0

就像大多数试图理解 C2DM 的人一样,我已经按照Vogella C2DM 教程的教程进行操作,这是获取代码的好教程,但它并不能真正帮助我理解如何使用它。我已经设置了我的 Android 类和我的服务器(移植到 php),但现在我不知道如何继续。我的代码如下所示:

c2dm.php(服务器端)

 function googleAuthenticate($username, $password, $source="Company-AppName-Version", $service="ac2dm") {
    session_start();
    if( isset($_SESSION['google_auth_id']) && $_SESSION['google_auth_id'] != null)
        return $_SESSION['google_auth_id'];

    // get an authorization token
    $ch = curl_init();
    if(!ch){
        return false;
    }

    curl_setopt($ch, CURLOPT_URL, "https://www.google.com/accounts/ClientLogin");
    $post_fields = "accountType=" . urlencode('HOSTED_OR_GOOGLE')
        . "&Email=" . urlencode($username)
        . "&Passwd=" . urlencode($password)
        . "&source=" . urlencode($source)
        . "&service=" . urlencode($service);
    curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
    curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

    // for debugging the request
    //curl_setopt($ch, CURLINFO_HEADER_OUT, true); // for debugging the request

    $response = curl_exec($ch);

    //var_dump(curl_getinfo($ch)); //for debugging the request
    //var_dump($response);

    curl_close($ch);

    if (strpos($response, '200 OK') === false) {
        return false;
    }

    // find the auth code
    preg_match("/(Auth=)([\w|-]+)/", $response, $matches);

    if (!$matches[2]) {
        return false;
    }

    $_SESSION['google_auth_id'] = $matches[2];  
}

function sendMessageToPhone($authCode, $deviceRegistrationId, $msgType, $messageText) {

    $headers = array('Authorization: GoogleLogin auth=' . $authCode);
    $data = array(
        'registration_id' => $deviceRegistrationId,
        'collapse_key' => $msgType,
        'data.message' => $messageText //TODO Add more params with just simple data instead           
    );

    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, "https://android.apis.google.com/c2dm/send");
    if ($headers)
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);


    $response = curl_exec($ch);

    curl_close($ch);

    return $response;
}

C2DMRegistrationReceiver.java

@Override
public void onReceive(Context context, Intent intent) {
    String action = intent.getAction();
    Log.w("C2DM", "Registration Receiver called");
    if ("com.google.android.c2dm.intent.REGISTRATION".equals(action)) {
        Log.w("C2DM", "Received registration ID");
        final String registrationId = intent
                .getStringExtra("registration_id");
        String error = intent.getStringExtra("error");

        Log.d("C2DM", "dmControl: registrationId = " + registrationId
                + ", error = " + error);
        // TODO Send this to my application server
    }
}

public void sendRegistrationIdToServer(String deviceId, String registrationId) {

    Log.d("C2DM", "Sending registration ID to my application server");
    HttpClient client = new DefaultHttpClient();
    HttpPost post = new HttpPost("myserverpage");
    try {
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
        // Get the deviceID
        nameValuePairs.add(new BasicNameValuePair("deviceid", deviceId));
        nameValuePairs.add(new BasicNameValuePair("registrationid", registrationId));

        post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
        HttpResponse response = client.execute(post);
        BufferedReader rd = 
        new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
        String line = "";
        while ((line = rd.readLine()) != null) {
        Log.e("HttpResponse", line);
    }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

C2DMMessageReceiver.java

@Override
public void onReceive(Context context, Intent intent) {
    String action = intent.getAction();
    Log.w("C2DM", "Message Receiver called");
    if ("com.google.android.c2dm.intent.RECEIVE".equals(action)) {
        Log.w("C2DM", "Received message");
        final String payload = intent.getStringExtra("payload");
        Log.d("C2DM", "dmControl: payload = " + payload);
        // Send this to my application server
    }
}

在我的 MainActivity 我有

public void register() {
    Intent intent = new Intent("com.google.android.c2dm.intent.REGISTER");
    intent.putExtra("app",PendingIntent.getBroadcast(this, 0, new Intent(), 0));
    intent.putExtra("sender", "app-name@gmail.com");
    startService(intent);
}

我在我的应用程序启动期间调用了 register() ,在 LogCat 中它显示“调用消息接收器”,而不是“调用注册接收器”。我当然已经将 app-name@gmail.com 更改为我自己的等等,但我现在不知道如何使用代码。谁能帮助我?

提前致谢!

4

3 回答 3

2

Vogella 的教程非常简单明了。如果您一步一步地遵循它,您将不会很难理解。

您的记录器说Message Receiver Called因为那是您使用 C2DMMessageReceiver 记录的内容。如果您有另一个注册接收器,请确保在清单中声明它并在此处发布代码。

我建议使用相同的接收器类。例如,这是一个简单的onReceive方法:

if (action != null){
        // This is for registration
        if (action.equals("com.google.android.c2dm.intent.REGISTRATION")){
            Log.d(LOG_TAG, "Received registration ID");

            final String registrationId = intent.getStringExtra("registration_id");
            String error = intent.getStringExtra("error");

            Log.d(LOG_TAG, "dmControl: registrationId = " + registrationId + ", error = " + error);

            // Create a notification with the received registration id

            // Also save it in the preference to be able to show it later

            // Get the device id in order to send it to the server
            String deviceId = Secure.getString(context.getContentResolver(), Secure.ANDROID_ID);
            // .. send it to the server
        }
        // This is for receiving messages
        else if (action.equals("com.google.android.c2dm.intent.RECEIVE")){
            String payload = intent.getStringExtra("payload");
            Log.d(LOG_TAG, "Message received: " + payload);
            // .. create a notification with the new message
        }

我添加了评论,您可以在其中进行更多操作(例如创建通知、将您的注册 ID 发送到您的第三方服务器等)。在 Lars Vogel 的教程中也可以找到如何执行上述这些操作的示例。

于 2012-05-03T09:38:10.880 回答
0

就我而言,我对两者都使用单个接收器:

if (action.equals("com.google.android.c2dm.intent.REGISTRATION")) {
String registrationId = intent.getStringExtra("registration_id");
//do somting
} else if (intent.getAction().equals("com.google.android.c2dm.intent.RECEIVE")) {
Bundle extras = intent.getExtras();
String message = extras.getString("message");
}// end if

}

并在清单中

 <receiver
  android:name=".receiverName"
 android:permission="com.google.android.c2dm.permission.SEND" >
  <intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />

<category android:name="packageName" />
</intent-filter>
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />

 <category android:name="packageName" />
</intent-filter>
于 2012-05-03T09:36:17.450 回答
0

我只会解释我所理解的。

  1. 首先,在您拥有的 gmail id 下使用您的 android 应用程序包名称(例如 com.example.app)在 android c2dm 站点中注册。

  2. 开发一个 android 应用程序应该能够将设备注册 id 作为请求发送到服务器。服务器应将这些 ID 存储在 db 中。

  3. 一旦你准备好从服务器向所有设备推送一些消息,你只需要为你在 c2dm 中注册的 gmail id 和存储在 db 中的设备 id 提供一个新的 auth_token。

Vogella 教程包含获取设备的 regid 和 auth_token 的示例代码。我已经尝试过了,并在我的应用程序中进行了修改。

于 2012-05-03T10:06:21.970 回答