gcm适用于模拟器,但在我的设备中给出canonical

系统教程 行业动态 更新时间:2024-06-14 17:03:54
gcm适用于模拟器,但在我的设备中给出canonical_ids“:0”(gcm works on emulator but give canonical_ids":0 in my device)

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

{"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 -->

任何人都可以指出我正确的方向

When I send a push notification to the emulator I get this message:

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

But after registering and sending the notification to my device with the new regId i get this :

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

I activated the notification in my phone and connected with Google account Also i get the new registration ID in my database when registering but i cant figure out the problem Here is my 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 -->

Can anyone point me to the right direction please

最满意答案

这是它的工作原理。

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

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

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

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

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

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

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

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()); } }

请参阅实施GCM客户端 。

This is how it works.

When registering a client to GCM you get a registration ID. Let's call it A. Your server will hold on to that for it to be able to send notifications.

Time goes by and for whatever reason, say expiration of the registration ID in the GCM server, GCM decides to give the same client a different, newer ID. We'll call it B. Your server holds on to that one, too.

Now you have to IDs for the same device, one is old and another is up to date. They will both be valid for sending notifications.

In a MulticastResult, receiving a Canonical ID means that the ID you're using isn't the most recent ID. When you do receive a canonical ID, it should replace the one you're using (since it's the most up to date ID).

For A you'll receive a MulticastResult with success=1, canonical id=B. For B you'll just receive success=1 because it is the most recent ID. The response for A indicates it is out of date and should be replace by B.

Since in your case you're using a newly registered ID (like you've said), there's no reason for it to be out of date, and there is no problem with your code.

As for why you are not getting the notification, your client has to have a receiver class that extends WakefulBroadcastReceiver, and handles the incoming notification:

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); } }

and an IntentService to complete the picture

`public class GcmIntentService extends IntentService { public static final int NOTIFICATION_ID = 1; private NotificationManager mNotificationManager; NotificationCompat.Builder 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()); } }

See Implementing a GCM client.

更多推荐

本文发布于:2023-04-24 14:06:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/dzcp/168ad07257768b1c0894faa931c9b1ba.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:但在   适用于   模拟器   设备   gcm

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!