首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >gcm在模拟器上工作,但在我的设备中给出canonical_ids":0“

gcm在模拟器上工作,但在我的设备中给出canonical_ids":0“
EN

Stack Overflow用户
提问于 2014-06-17 10:56:30
回答 1查看 2K关注 0票数 0

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

代码语言:javascript
复制
{"multicast_id":8595716062607030073,"success":1,"failure":0,"canonical_ids":1,"results":            [{"message_id":"0:1403002114354553%44f16b55f9fd7ecd","registration_id":"XXXXXXX...

但是,在使用新的regId注册并发送通知到我的设备后,我得到以下信息:

代码语言:javascript
复制
{"multicast_id":8356469968000736599,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1403002260325568%44f16b55f9fd7ecd"}]}

我在手机中激活了通知,并连接了Google帐户,在注册时,我在数据库中获得了新的注册ID,但我不知道这里的问题是我的manifest.xml:

代码语言:javascript
复制
   <!-- 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 -->

谁能给我指出正确的方向吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-06-17 11:01:04

这就是它的工作原理。

当向GCM注册客户端时,您将得到一个注册ID。让我们将其称为A。您的服务器将保留它,以便它能够发送通知。

时间一天天过去,不管出于什么原因,比如说GCM服务器注册ID的过期,GCM决定给同一个客户端一个不同的更新ID,我们称之为B。你的服务器也保留着那个。

现在,您必须为同一设备的is,一个是旧的,另一个是最新的。它们都将用于发送通知

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

对于A,您将收到一个带有success=1的MulticastResult,规范的id=B。对于B,您将只收到success=1,因为它是最新的ID。对A的响应表明它已经过时,应该由B替换。

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

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

代码语言:javascript
复制
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来完成这幅画

‘公共类GcmIntentService扩展了IntentService {公共静态最终int NOTIFICATION_ID = 1;私有NotificationManager mNotificationManager;NotificationCompat.Builder生成器;

代码语言:javascript
复制
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客户端

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24262015

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档