GVKun编程网logo

在GoogleCloudMessaging API中,如何处理注册ID的续订或到期?(google cloud platform注册)

12

在本文中,我们将详细介绍在GoogleCloudMessagingAPI中,如何处理注册ID的续订或到期?的各个方面,并为您提供关于googlecloudplatform注册的相关解答,同时,我们也将

在本文中,我们将详细介绍在GoogleCloudMessaging API中,如何处理注册ID的续订或到期?的各个方面,并为您提供关于google cloud platform注册的相关解答,同时,我们也将为您带来关于Android Google Cloud Messaging(GCM)和不匹配的发件人ID、Android Push Notifications using Google Cloud Messaging (GCM、android – Google Cloud Messaging(GCM) – 无法实例化接收器 – java.lang.ClassNotFoundException、android – Google Cloud Messaging(GCM)和registration_id到期,我怎么知道?的有用知识。

本文目录一览:

在GoogleCloudMessaging API中,如何处理注册ID的续订或到期?(google cloud platform注册)

在GoogleCloudMessaging API中,如何处理注册ID的续订或到期?(google cloud platform注册)

如问题所述,如何确定何时在GoogleCloudMessaging
API中注册ID无效?我已经阅读了有关类似主题的几个问题的答案:GCM注册ID是否过期?以及Google Coud
Mesaging(GCM)和registration_id到期,我怎么知道?。这些问题的问题在于,答案是使用GCMRegistrar而不是GoogleCloudMessaging
API的旧GCMAPI。前两种方法已贬值。)C2DM

我将 逐步解决我的困惑/问题

1) 在“ 启用GCM
”标题下,第二点是:

Google may periodically refresh the registration ID, so you should designyour Android application with the understanding that thecom.google.android.c2dm.intent.REGISTRATION intent may be called multipletimes. Your Android application needs to be able to respond accordingly.

The registration ID lasts until the Android application explicitlyunregisters itself, or until Google refreshes the registration ID for yourAndroid application. Whenever the application receives acom.google.android.c2dm.intent.REGISTRATION intent with a registration_idextra, it should save the ID for future use, pass it to the 3rd-party serverto complete the registration, and keep track of whether the server completedthe registration. If the server fails to complete the registration, it shouldtry again or unregister from GCM.

2)
现在,如果是这种情况,那么我应该在BroadcastReceiver中处理意图,然后再次发送register()请求以获取新的注册ID。但是问题在于,在同一页面上标题ERROR_MAIN_THREAD下的
内容是: GCM methods are blocking. You should not run them in the main thread orin broadcast receivers

3) 我还了解到,注册ID发生更改时,还有其他两种情况(如“
使注册状态保持同步”标题下的“高级主题” 所述):应用程序更新和备份与还原。我已经在打开应用程序时处理了它们。

4) 在GCMRegistrar
API,内部GCMBaseIntentService,过去有一个回调
onRegistered()方法中,当设备注册得到其中得到调用。在这里,我曾经保留注册ID并将其发送给第三方服务器。

但是,现在我应该如何处理注册ID的更新或更新,将其保留并发送给第三方服务器?

可能是由于阅读全部内容而使我感到困惑,或者我错过了一些东西。非常感谢您的帮助。

更新资料

即使在Android线程上处理Google
Cloud
Messaging中的注册ID更改时,也没有提及如何处理Google定期刷新ID?

答案1

小编典典

我正在给出一种方法,就像我在应用程序中实现的一样

@Overrideprotected void onRegistered(Context context, String registrationId) {     Log.i(TAG, "Device registered: regId = " + registrationId);     //displayMessage(context, getString(R.string.gcm_registered));     //ServerUtilities.register(context, registrationId);     //1. Store this id to application Prefs on each request of device registration     //2. Clear this id from app prefs on each request of device un-registration       //3. Now add an if check for new registartion id to server, you can write a method on server side to check if this reg-id matching for this device or not (and you need an unique identification of device to be stored on server)     //4. That method will clear that if id is matching it meanse this is existing reg-id, and if not matching this is updated reg-id.     //5. If this is updated reg-id, update on server and update into application prefs.}

你也可以这样

if reg_id exists_into prefrences then    if stored_id equals_to new_reg_id then        do nothing    else        say server to reg_id updated        update prefrences with new id    end ifelse    update this id to application prefs    say server that your device is registeredend if

但是,当用户清除应用程序数据并且您将丢失当前的注册表ID时,就会出现问题。


新API示例示例的更新
功劳归功于Eran及其Android上的Google
Cloud Messaging中的)他的答案处理注册ID更改

Google更改了其演示应用程序以使用新界面。他们通过在应用程序本地保留的值上设置过期日期来刷新注册ID。应用启动时,他们会加载其本地存储的注册ID。如果它已“过期”(在演示中这意味着它是7天前从GCM收到的),他们会gcm.register(senderID)再次致电。

这不适用于假设的情况,在这种情况下,Google会为长时间未启动的应用刷新注册ID。在这种情况下,应用程序将不会知道更改,第三方服务器也不会。

public void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.main);    mDisplay = (TextView) findViewById(R.id.display);    context = getApplicationContext();    regid = getRegistrationId(context);    if (regid.length() == 0) {        registerBackground();    }    gcm = GoogleCloudMessaging.getInstance(this);}/** * Gets the current registration id for application on GCM service. * <p> * If result is empty, the registration has failed. * * @return registration id, or empty string if the registration is not *         complete. */private String getRegistrationId(Context context) {    final SharedPreferences prefs = getGCMPreferences(context);    String registrationId = prefs.getString(PROPERTY_REG_ID, "");    if (registrationId.length() == 0) {        Log.v(TAG, "Registration not found.");        return "";    }    // check if app was updated; if so, it must clear registration id to    // avoid a race condition if GCM sends a message    int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);    int currentVersion = getAppVersion(context);    if (registeredVersion != currentVersion || isRegistrationExpired()) {        Log.v(TAG, "App version changed or registration expired.");        return "";    }    return registrationId;}/** * Checks if the registration has expired. * * <p>To avoid the scenario where the device sends the registration to the * server but the server loses it, the app developer may choose to re-register * after REGISTRATION_EXPIRY_TIME_MS. * * @return true if the registration has expired. */private boolean isRegistrationExpired() {    final SharedPreferences prefs = getGCMPreferences(context);    // checks if the information is not stale    long expirationTime =            prefs.getLong(PROPERTY_ON_SERVER_EXPIRATION_TIME, -1);    return System.currentTimeMillis() > expirationTime;}

Android Google Cloud Messaging(GCM)和不匹配的发件人ID

Android Google Cloud Messaging(GCM)和不匹配的发件人ID

我想在我的 Android应用程序中使用GCM服务.

为此,我使用了http://developer.android.com/guide/google/gcm/gcm.html的android文档

我创建了客户端注册过程与发件人ID等和服务器端应用程序,我使用注册ID和发件人ID发送邮件.

当我通过Eclipse在我的手机中安装应用程序时,推送通知工作正常,因此我拥有的发件人ID是正确的.

然后,当我用Eclipse导出apk文件并将其安装在我的手机中时,我收到SenderId错误的错误消息

MissmatchedSenderId

任何人都知道为什么我会得到这个.

我读过这些话题:

Why do I get “MismatchSenderId” from GCM server side?

When sending messages using GCM,I keep getting the response ‘MismatchSenderId’

但在我的情况下奇怪的是,在将应用程序导出为apk之前一切正常,然后我遇到了这个问题.

任何想法都是最好的.

解决方法

我实际上遇到了同样的问题,并且正在研究超过10个小时.

我终于找到了问题!
与服务器API密钥或浏览器API密钥或SenderID无关.
问题是Google文档:

final String regId = GCMRegistrar.getRegistrationId(this);
if (regId.equals("")) {
  GCMRegistrar.register(this,SENDER_ID);
} else {
  Log.v(TAG,"Already registered");
}

Google表示你必须调用getRegistrationId函数并且只有当id为空时才调用register!
这对我来说根本不起作用……当我这样做时,我总是在发送到这个regId时找回MismatchSenderId.

我的解决方案是:
总是打电话

GCMRegistrar.register(this,SENDER_ID);

而当功能

protected void onRegistered( Context c,String regId )

被称为在我的服务器数据库中保存regId.

如果我这样做,一切正常!

Android Push Notifications using Google Cloud Messaging (GCM

Android Push Notifications using Google Cloud Messaging (GCM

http://www.androidhive.info/2012/10/android-push-notifications-using-google-cloud-messaging-gcm-php-and-mysql/ 按照链接中文章的步骤,实现了GCM-HTTP在client 和app server之间的部署,链接一下供需要的同学参考。 在从本地Server移植到web server遇

http://www.androidhive.info/2012/10/android-push-notifications-using-google-cloud-messaging-gcm-php-and-mysql/

按照链接中文章的步骤,实现了GCM-HTTP在client 和app server之间的部署,链接一下供需要的同学参考。


在从本地Server移植到web server遇到的问题:

1.Google Api Key是绑定服务器IP的,所以在本地换到Web的时候,Google Api Key需要重新申请;

2.如果服务器端CURL不可用,那么推送就会出问题,需要安装CURL模块

参考链接:

http://stackoverflow.com/questions/22004716/gcm-is-not-working-on-live-server

http://stackoverflow.com/questions/2939820/how-to-enable-curl-installed-ubuntu-lamp-stack

http://www.2cto.com/os/201102/84031.html

android – Google Cloud Messaging(GCM) – 无法实例化接收器 – java.lang.ClassNotFoundException

android – Google Cloud Messaging(GCM) – 无法实例化接收器 – java.lang.ClassNotFoundException

一旦应用程序启动或从服务器发送推送通知,就会发生以下回溯.
08-31 02:00:14.733: E/AndroidRuntime(30973): java.lang.RuntimeException: Unable to instantiate receiver com.example.smsmining.GcmbroadcastReceiver: java.lang.classNotFoundException: Didn't find class "com.example.smsmining.GcmbroadcastReceiver" on path: DexPathList[[zip file "/data/app/com.example.smsmining-1.apk"],nativeLibraryDirectories=[/data/app-lib/com.example.smsmining-1,/vendor/lib,/system/lib]]
08-31 02:00:14.733: E/AndroidRuntime(30973):    at android.app.ActivityThread.handleReceiver(ActivityThread.java:2405)
08-31 02:00:14.733: E/AndroidRuntime(30973):    at android.app.ActivityThread.access$1500(ActivityThread.java:141)
08-31 02:00:14.733: E/AndroidRuntime(30973):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1332)
08-31 02:00:14.733: E/AndroidRuntime(30973):    at android.os.Handler.dispatchMessage(Handler.java:99)
08-31 02:00:14.733: E/AndroidRuntime(30973):    at android.os.Looper.loop(Looper.java:137)
08-31 02:00:14.733: E/AndroidRuntime(30973):    at android.app.ActivityThread.main(ActivityThread.java:5103)
08-31 02:00:14.733: E/AndroidRuntime(30973):    at java.lang.reflect.Method.invokeNative(Native Method)
08-31 02:00:14.733: E/AndroidRuntime(30973):    at java.lang.reflect.Method.invoke(Method.java:525)
08-31 02:00:14.733: E/AndroidRuntime(30973):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
08-31 02:00:14.733: E/AndroidRuntime(30973):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
08-31 02:00:14.733: E/AndroidRuntime(30973):    at dalvik.system.NativeStart.main(Native Method)
08-31 02:00:14.733: E/AndroidRuntime(30973): Caused by: java.lang.classNotFoundException: Didn't find class "com.example.smsmining.GcmbroadcastReceiver" on path: DexPathList[[zip file "/data/app/com.example.smsmining-1.apk"],/system/lib]]
08-31 02:00:14.733: E/AndroidRuntime(30973):    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:53)
08-31 02:00:14.733: E/AndroidRuntime(30973):    at java.lang.classLoader.loadClass(ClassLoader.java:501)
08-31 02:00:14.733: E/AndroidRuntime(30973):    at java.lang.classLoader.loadClass(ClassLoader.java:461)
08-31 02:00:14.733: E/AndroidRuntime(30973):    at android.app.ActivityThread.handleReceiver(ActivityThread.java:2400)
08-31 02:00:14.733: E/AndroidRuntime(30973):    ... 10 more

我的清单文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.smsmining"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="9"
        android:targetSdkVersion="16" />
    <uses-permission android:name="android.permission.READ_SMS"/>
    <uses-permission android:name="android.permission.RECEIVE_SMS"/>
    <uses-permission android:name="android.permission.READ_CONTACTS"/>
    <uses-permission android:name="android.permission.INTERNET"/>

    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />


     <permission android:name="com.example.smsmining.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />
    <uses-permission android:name="com.example.smsmining.permission.C2D_MESSAGE" />

    <!-- This app has permission to register and receive data message. -->
    <uses-permission
        android:name="com.google.android.c2dm.permission.RECEIVE" />


    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

         <receiver android:name="com.example.smsmining.SMSbroadcastReceiver">
            <intent-filter>
                <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
            </intent-filter>
        </receiver>



         <receiver
            android:name=".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.example.smsmining" />
            </intent-filter>
        </receiver>
        <service android:name=".GCMIntentService" />

    </application>

</manifest>

GcmbroadcastReceiver.java

package com.example.smsmining;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.WakefulbroadcastReceiver;


/**
 * This {@code WakefulbroadcastReceiver} takes care of creating and managing a
 * partial wake lock for your app. It passes off the work of processing the GCM
 * message to an {@code IntentService},while ensuring that the device does not
 * go back to sleep in the transition. The {@code IntentService} calls
 * {@code GcmbroadcastReceiver.completeWakefulIntent()} when it is ready to
 * release the wake lock.
 */

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

GcmIntentService.java

public class GcmIntentService extends IntentService {
    public static final int NOTIFICATION_ID = 1;
    private notificationmanager mnotificationmanager;
    NotificationCompat.Builder builder;

    public GcmIntentService() {
        super("GcmIntentService");
    }
    public static final String TAG = "GCM Demo";

    @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(5);
                    } 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,new Intent(this,MainActivity.class),0);

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

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

解决方法

我有同样的错误.这对我有帮助.
尝试检查v.4库.
属性 – > Java构建路径 – >订单和导出

编辑:选择项目并转到:Properties-> Java Build Path-> Order and Export,确保在列表中选中了android.support.v4库,如果没有,请标记它. (我假设您已经将库导入到项目中),清理项目并且它应该可以工作

android – Google Cloud Messaging(GCM)和registration_id到期,我怎么知道?

android – Google Cloud Messaging(GCM)和registration_id到期,我怎么知道?

我已经整理了一个骨架客户端/服务器GCM应用程序,该应用程序接受并在我的粗略和准备好的服务器上显示我的 Android手机上的消息.我说’骨架’和’粗糙和准备’,因为我的应用程序的registration_id被硬编码到服务器端,作为我在调试器中捕获的值,当我启动示例Android应用程序并在GCM服务器上注册应用程序/设备组合时.当我开始思考时,我正要开始为双方提供读/写机制来访问服务器上的简单数据库以存储reg_id /设备组合:

我知道这个reg_id可以随时过期,因为谷歌说它可以.从文档中可以清楚地看到如何检查id是否仍然正常,并且它是一个很大的IF,我再次启动应用程序.但是,为什么我或任何其他用户再次启动它?在清单中注册的GCMIntentService根据需要在那里收集消息,并且无需出于任何原因再次运行应用程序.因此,当id到期时,我将停止获取消息 – 服务器可能从返回代码中知道,但无法通知我的应用程序 – 无法恢复,除非我再次运行应用程序并通过其onCreate()并且可能registerClient()方法.

那么当id到期时会发生什么?我没有看到IntentService中的任何on ..方法都会执行.谷歌自己会发一条正常消息说它即将到期吗?我是否需要编写一个每天运行的警报任务并检查ID?

解决方法

根据 GCM:

An existing registration ID may cease to be valid in a number of
scenarios,including:

  • If the application manually unregisters by issuing a com.google.android.c2dm.intent.UNREGISTER intent.
  • If the application is automatically unregistered,which can happen (but is not guaranteed) if the user uninstalls the application. If the registration ID expires. Google might decide to refresh registration IDs.
  • If the application is updated but the new version does not have a broadcast receiver configured to receive com.google.android.c2dm.intent.RECEIVE intents.

考虑与注册相关的响应将触发“com.google.android.c2dm.intent.REGISTRATION”意图.因此,您应该注意从GCM发送的注册消息.

更新

GCM doc说:

If the registration ID expires. Google might decide to refresh
registration IDs. For all these cases,you should remove this
registration ID from the 3rd-party server and stop using it to send
messages. Happens when error code is NotRegistered.

考虑到上述事实,然后在您的服务器上,您应该处理过期的ID并在您的数据库中设置一个标志,下次您的Android客户端检查您的服务器(最后您必须进行定期检查)或调用isRegisteredOnServer在GCMRegistrar类上得到错误的结果,你应该激活REGISTRATION意图以获得一个新的ID.

关于在GoogleCloudMessaging API中,如何处理注册ID的续订或到期?google cloud platform注册的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于Android Google Cloud Messaging(GCM)和不匹配的发件人ID、Android Push Notifications using Google Cloud Messaging (GCM、android – Google Cloud Messaging(GCM) – 无法实例化接收器 – java.lang.ClassNotFoundException、android – Google Cloud Messaging(GCM)和registration_id到期,我怎么知道?等相关内容,可以在本站寻找。

本文标签: