gcm适用于模拟器,但在我的设备中给出canonical_ids“:0”

时间:2014-06-17 10:56:30

标签: android google-cloud-messaging

当我向模拟器发送推送通知时,我收到以下消息:

{"multicast_id":8595716062607030073,"success":1,"failure":0,"canonical_ids":1,"results":            [{"message_id":"0:1403002114354553%44f16b55f9fd7ecd","registration_id":"XXXXXXX...

但是在注册并使用新的regId将通知发送到我的设备后,我得到了这个:

{"multicast_id":8356469968000736599,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1403002260325568%44f16b55f9fd7ecd"}]}

我在手机中激活了通知并与Google帐户相关联 此外,我在注册时在我的数据库中获得了新的注册ID,但我无法找出问题所在 这是我的manifest.xml:

   <!-- for gcm -->
    <receiver                        
        android:name="com.test.android.gcm.GcmBroadcastReceiver"
        android:permission="com.google.android.c2dm.permission.SEND" >
         <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            <action android:name="com.google.android.c2dm.intent.REGISTRATION" />

            <category android:name="com.test.android.gcm" />
        </intent-filter>
    </receiver>

    <service android:name="com.test.android.gcm.GCMNotificationIntentService" />
    <!-- end for gcm -->
    <!-- GCM activity -->
    <activity
        android:name="com.test.android.gcm.RegisterActivity"
        android:label="@string/app_name" >
    </activity>
    <activity
        android:name="com.test.android.gcm.MainActivity"
        android:configChanges="orientation|keyboardHidden"
        android:label="@string/app_name" >
    </activity>
    <!-- End GCM activity -->

有人能指出我正确的方向吗

1 个答案:

答案 0 :(得分:1)

这是它的工作原理。

向GCM注册客户端时,您会获得注册ID。我们称之为 A 。您的服务器将保留该服务器,以便能够发送通知。

时间流逝并且无论出于何种原因,例如GCM服务器中的注册ID到期,GCM决定为同一客户端提供不同的新ID。我们称之为 B 。您的服务器也会保留该服务器。

现在您需要同一设备的ID,一个是旧的,另一个是最新的。他们 都有效发送通知

在MulticastResult中,接收Canonical ID意味着您使用的ID不是最新的ID。当您收到规范ID时,它应该替换您正在使用的ID(因为它是最新的ID)。

对于 A ,您将收到成功= 1的MulticastResult,规范ID = B 。对于 B ,您只会收到成功= 1,因为它是最新的ID。 A 的响应表明它已过期,应由 B 替换。

因为在您的情况下,您使用的是新注册的ID(就像您所说的那样),所以没有理由让它过时,您的代码也没有问题。

至于为什么你没有收到通知, 你的客户端必须有一个扩展WakefulBroadcastReceiver的接收者类,并处理传入的通知:< / p>

public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // Explicitly specify that GcmIntentService will handle the intent.
        ComponentName comp = new ComponentName(context.getPackageName(),
                GcmIntentService.class.getName());
        // Start the service, keeping the device awake while it is launching.
        startWakefulService(context, (intent.setComponent(comp)));
        setResultCode(Activity.RESULT_OK);
    }
}

IntentService来完成图片

`public class GcmIntentService extends IntentService {     public static final int NOTIFICATION_ID = 1;     private NotificationManager mNotificationManager;     NotificationCompat.Builder构建器;

public GcmIntentService() {
    super("GcmIntentService");
}

@Override
protected void onHandleIntent(Intent intent) {
    Bundle extras = intent.getExtras();
    GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
    // The getMessageType() intent parameter must be the intent you received
    // in your BroadcastReceiver.
    String messageType = gcm.getMessageType(intent);

    if (!extras.isEmpty()) {  // has effect of unparcelling Bundle
        /*
         * Filter messages based on message type. Since it is likely that GCM
         * will be extended in the future with new message types, just ignore
         * any message types you're not interested in, or that you don't
         * recognize.
         */
        if (GoogleCloudMessaging.
                MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
            sendNotification("Send error: " + extras.toString());
        } else if (GoogleCloudMessaging.
                MESSAGE_TYPE_DELETED.equals(messageType)) {
            sendNotification("Deleted messages on server: " +
                    extras.toString());
        // If it's a regular GCM message, do some work.
        } else if (GoogleCloudMessaging.
                MESSAGE_TYPE_MESSAGE.equals(messageType)) {
            // This loop represents the service doing some work.
            for (int i=0; i<5; i++) {
                Log.i(TAG, "Working... " + (i+1)
                        + "/5 @ " + SystemClock.elapsedRealtime());
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                }
            }
            Log.i(TAG, "Completed work @ " + SystemClock.elapsedRealtime());
            // Post notification of received message.
            sendNotification("Received: " + extras.toString());
            Log.i(TAG, "Received: " + extras.toString());
        }
    }
    // Release the wake lock provided by the WakefulBroadcastReceiver.
    GcmBroadcastReceiver.completeWakefulIntent(intent);
}

// Put the message into a notification and post it.
// This is just one simple example of what you might choose to do with
// a GCM message.
private void sendNotification(String msg) {
    mNotificationManager = (NotificationManager)
            this.getSystemService(Context.NOTIFICATION_SERVICE);

    PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
            new Intent(this, DemoActivity.class), 0);

    NotificationCompat.Builder mBuilder =
            new NotificationCompat.Builder(this)
    .setSmallIcon(R.drawable.ic_stat_gcm)
    .setContentTitle("GCM Notification")
    .setStyle(new NotificationCompat.BigTextStyle()
    .bigText(msg))
    .setContentText(msg);

    mBuilder.setContentIntent(contentIntent);
    mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
    }
}

请参阅Implementing a GCM client