如何修复Google Cloud Messaging注册错误:SERVICE_NOT_AVAILABLE?

Mai*_*r00 25 java android push-notification google-cloud-messaging

我遇到了一个奇怪的问题 - 我在我的应用程序中使用GCM已经有很长一段时间了,一切都运行得很好.然而,发布谷歌Play前,我从改变了我的应用程序包的名字com.android.testappcom.android.recognition并在此之后GCM停止工作.起初我得到错误GCM sender id not set on constructor并通过覆盖修复它getSenderIds(Context context),但现在我无法获得注册ID.以下是来自logcat的消息: 在此输入图像描述

我怎样才能解决这个问题?当我切换到新包时,我将清单文件中的所有内容更改为新包:

<receiver
        android:name="com.google.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.android.recognition" />
        </intent-filter>
    </receiver>
Run Code Online (Sandbox Code Playgroud)

那背后的问题是什么?可以重命名应用程序包导致这个还是有另一个原因?

Ama*_*tam 42

这个问题得到了回答,在我看来,这个问题要复杂得多.

  1. 检查您是否有有效的互联网连接
  2. 检查您的清单中是否具有Internet权限
  3. 确保包装名称正确,如Eran所述
  4. 设备时间设置正确.即使一切都很完美,如果设备时钟设置不正确,也会失败.

错误的时钟给我带来了麻烦.:)


Pan*_*mar 32

SERVICE_NOT_AVAILABLE错误表示GCM Service当前不可用.等一段时间后再试.

这种情况发生很多次(根据我的经验),所以不要担心.


请参阅GCMConstantsGCM Lib类.

/**
     * The device can't read the response, or there was a 500/503 from the
     * server that can be retried later. The application should use exponential
     * back off and retry.
     */
    public static final String ERROR_SERVICE_NOT_AVAILABLE =
            "SERVICE_NOT_AVAILABLE";
Run Code Online (Sandbox Code Playgroud)

对于更多的调查看handleRegistration()GCMBaseIntentService

private void handleRegistration(final Context context, Intent intent) {
        String registrationId = intent.getStringExtra(EXTRA_REGISTRATION_ID);
        String error = intent.getStringExtra(EXTRA_ERROR);
        String unregistered = intent.getStringExtra(EXTRA_UNREGISTERED);
        Log.d(TAG, "handleRegistration: registrationId = " + registrationId +
                ", error = " + error + ", unregistered = " + unregistered);

        // registration succeeded
        if (registrationId != null) {
            GCMRegistrar.resetBackoff(context);
            GCMRegistrar.setRegistrationId(context, registrationId);
            onRegistered(context, registrationId);
            return;
        }

        // unregistration succeeded
        if (unregistered != null) {
            // Remember we are unregistered
            GCMRegistrar.resetBackoff(context);
            String oldRegistrationId =
                    GCMRegistrar.clearRegistrationId(context);
            onUnregistered(context, oldRegistrationId);
            return;
        }

        // last operation (registration or unregistration) returned an error;
        Log.d(TAG, "Registration error: " + error);
        // Registration failed
        if (ERROR_SERVICE_NOT_AVAILABLE.equals(error)) {
            boolean retry = onRecoverableError(context, error);
            if (retry) {
                int backoffTimeMs = GCMRegistrar.getBackoff(context);
                int nextAttempt = backoffTimeMs / 2 +
                        sRandom.nextInt(backoffTimeMs);
                Log.d(TAG, "Scheduling registration retry, backoff = " +
                        nextAttempt + " (" + backoffTimeMs + ")");
                Intent retryIntent =
                        new Intent(INTENT_FROM_GCM_LIBRARY_RETRY);
                retryIntent.putExtra(EXTRA_TOKEN, TOKEN);
                PendingIntent retryPendingIntent = PendingIntent
                        .getBroadcast(context, 0, retryIntent, 0);
                AlarmManager am = (AlarmManager)
                        context.getSystemService(Context.ALARM_SERVICE);
                am.set(AlarmManager.ELAPSED_REALTIME,
                        SystemClock.elapsedRealtime() + nextAttempt,
                        retryPendingIntent);
                // Next retry should wait longer.
                if (backoffTimeMs < MAX_BACKOFF_MS) {
                  GCMRegistrar.setBackoff(context, backoffTimeMs * 2);
                }
            } else {
                Log.d(TAG, "Not retrying failed operation");
            }
        } else {
            // Unrecoverable error, notify app
            onError(context, error);
        }
    }
Run Code Online (Sandbox Code Playgroud)

  • 谢谢man.The问题是我的Wi-Fi :) (9认同)
  • "等一段时间再试." 我在不同的设备上已经有三天这个错误 (3认同)
  • 我在1天内没有遇到这个问题.如果您在3天内遇到此问题,那么它可能还会遇到其他问题.您是否在prev中使用相同的代码获得了成功? (2认同)

Era*_*ran 18

确保您更改了清单的权限部分中的包名称:

<permission android:name="YOUR_PACKAGE_NAME.permission.C2D_MESSAGE"
    android:protectionLevel="signature" />
<uses-permission android:name="YOUR_PACKAGE_NAME.permission.C2D_MESSAGE" />
Run Code Online (Sandbox Code Playgroud)

由于该部分中的包名称不正确,我遇到了类似的错误.


Ela*_*ava 18

SERVICE_NOT_AVAILABLE是Google Cloud Messaging最令人沮丧的问题之一.这是一个例外GoogleCloudMessaging.register(SENDER_ID),函数调用注册设备以进行推送通知并返回注册ID.

  1. SERVICE_NOT_AVAILABLE可能意味着用户的设备无法读取对注册请求的响应,或者从服务器返回了500/503错误代码.开发人员无法修复此错误,因为它位于Google端,因此我们可以盲目地建议用户应该在几个小时内再次尝试.
  2. 即使注册成功,某些设备上也可能出现SERVICE_NOT_AVAILABLE.这可以通过实现变通方广播接收器来解决,以便在呼叫失败时捕获令牌.我实现了这个解决方法,它可能已经解决了一些用户的问题,但我仍然收到了许多其他SERVICE_NOT_AVAILABLE投诉.
  3. 由于设备上的Google Play服务库已过时或缺失,可能会发生SERVICE_NOT_AVAILABLE.在这种情况下,该应用程序理论上可以通过打开相应的Google Play应用程序列表来通知用户更新Google Play服务.但是,应用程序不知道这就是抛出SERVICE_NOT_AVAILABLE的原因,因此它无法盲目地将用户重定向到Google Play上的Google Play服务应用页面.
  4. 当设备的时钟与网络不同步时,可能会发生SERVICE_NOT_AVAILABLE.同样,开发人员无法知道这是确切的问题,因此我们可以盲目地建议用户检查他们的系统时钟同步,希望他们是极少数时钟不同步的人之一.
  5. 当root用户从他们的设备中删除了Hangouts/GTalk应用程序时,可能会发生SERVICE_NOT_AVAILABLE(因为他们认为它是英国媒体报道软件).GCM由Hangouts/GTalk实施和处理,因此没有它就无法使用GCM.
  6. 如果用户正在运行未安装Google API的设备(例如Amazon Kindle),则可能会出现SERVICE_NOT_AVAILABLE.这里没什么可做的,这些用户永远不会收到来自您应用的推送通知.

阅读更多:http: //eladnava.com/google-cloud-messaging-extremely-unreliable/

仅这些问题就足以让我开始寻找GCM替代品.我每天或每两天都会对我的应用程序进行1星评价,并在评论中包含抛出SERVICE_NOT_AVAILABLE时显示的错误消息.我无能为力帮助这些用户,因为他们中的大多数人都是出于他们无法控制的原因而接收这些用户.

Google Cloud Messaging的替代方案

Pushy(https://pushy.me/)是一个独立的推送通知网关,完全独立于GCM.它保持自己的后台套接字连接,就像GCM一样,用于接收推送通知.底层协议是MQTT,一种极轻量级的pub/sub协议,利用非常少的网络带宽和电池.

Pushy的一个巨大优势是,用于发送推送通知(来自服务器)以及注册设备以进行推送通知的代码实际上可以在GCM和Pushy之间互换.这使得在实施GCM之后切换到Pushy非常容易,并且由于其不稳定而不得不放弃它.

(完全披露:我为自己的项目创立了Pushy,并意识到许多应用程序将从这样的服务中受益)


Mah*_*iya 13

对我来说 - 设备时间不正确.我更改了设备设置以使用"自动日期和时间",再次尝试并且一切都很好.

干杯

  • 对于downvoters而言,这也是我案例中的问题. (2认同)