我遇到了一个奇怪的问题 - 我在我的应用程序中使用GCM已经有很长一段时间了,一切都运行得很好。但是,在发布到Google Play之前,我将应用程序包名称从com.android.testapp
更改为com.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>
那背后的问题是什么?可以重命名应用程序包导致这个还是有另一个原因?
答案 0 :(得分:42)
问题得到解答,在我的情况下,它稍微复杂一点。
错误的时钟给我带来了问题。 :)
答案 1 :(得分:32)
此SERVICE_NOT_AVAILABLE
错误表示GCM Service
目前不可用。等一段时间后再试。
这种情况多次发生(根据我的经验),所以不要担心。
请参阅GCM Lib的GCMConstants
类。
/**
* 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";
有关更多调查,请参阅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);
}
}
答案 2 :(得分:18)
确保您更改了清单的权限部分中的包名称:
<permission android:name="YOUR_PACKAGE_NAME.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="YOUR_PACKAGE_NAME.permission.C2D_MESSAGE" />
由于该部分中的包名称不正确,我遇到了类似的错误。
答案 3 :(得分:18)
SERVICE_NOT_AVAILABLE 是Google Cloud Messaging最令人沮丧的问题之一。它是GoogleCloudMessaging.register(SENDER_ID)
抛出的异常,函数调用注册设备以进行推送通知并返回注册ID。
了解更多: http://eladnava.com/google-cloud-messaging-extremely-unreliable/
仅这些问题足以让我开始寻找GCM替代品。我会每天或每两天对我的应用程序进行1星评价,并在评论中包含抛出SERVICE_NOT_AVAILABLE时显示的错误消息。我没有办法帮助这些用户,因为他们中的大多数人都是出于他们无法控制的原因而接收这些用户。
Google Cloud Messaging的替代方案
Pushy(https://pushy.me/)是一个独立的推送通知网关,完全独立于GCM。它保持自己的后台套接字连接,就像GCM一样,用于接收推送通知。底层协议是MQTT,一种极轻量级的发布/订阅协议,利用非常少的网络带宽和电池。
Pushy的一个巨大优势是,用于发送推送通知(来自服务器)以及注册设备以进行推送通知的代码实际上可以在GCM和Pushy之间互换。这使得在实施GCM之后切换到Pushy非常容易,并且由于其不稳定而不得不放弃它。
(完全披露:我为自己的项目创立了Pushy,并意识到许多应用程序将从这样的服务中受益)
答案 4 :(得分:13)
对我来说 - 设备时间不正确。我更改了设备设置以使用“自动日期和时间”,再次尝试并且一切都很好。
干杯
答案 5 :(得分:3)
就我而言,解决方案是根据https://snowdog.co/blog/dealing-with-service_not_available-google-cloud-messaging/
向清单添加新的intent-filter操作REGISTRATION <receiver
android:name=".RemoteNotificationReceiver"
android:permission="com.getset.getset.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.getset.getset.c2dm.intent.RECEIVE" />
<action android:name="com.getset.getset.c2dm.intent.REGISTRATION" />
<category android:name="com.getset.getset" />
</intent-filter>
</receiver>
我必须承认,我很惊讶这是有效的,因为教程中缺少它,但是取出它肯定会将成功的注册ID变成异常。
注意:使用Nexus 5 API 21(棒棒糖)模拟器。
答案 6 :(得分:3)
对我来说,通过在我的Galaxy S4上的数据使用选项中选中“限制后台数据”,我已经为谷歌服务启用了“后台数据访问”。我一打开它就在cellarer网络上解决了问题。在Wifi上工作正常。
答案 7 :(得分:3)
对我来说有连接问题。更改互联网连接解决了我的问题
答案 8 :(得分:3)
我有类似的问题。在google nexus(Android 4.4.2)上工作得很好,但在三星galaxy s3(Android 4.1.2)上却没有。 我在三星注册时获得了SERVICE_NOT_AVAILABLE。事实证明三星的时间已经过去了。它未设置为使用网络时间自动更新。一旦我修复了GCM就像一个魅力。谢谢 - Umesh
答案 9 :(得分:3)
我遇到了同样的问题,但上述解决方案都没有解决我的问题。幸运的是,我最近解决了它,我想解释一下,跳跃它会帮助其他人:
在我的情况下,我在自定义应用程序类中注册了推送服务(在任何活动之前执行,我认为是由于某些事情尚未被初始化)。将其更改为主要活动解决了问题。
public class MyCustomApp extends Application {
@Override
public void onCreate() {
super.onCreate();
PushService.register(this); //BAD IDEA, don't register pushes in Application Class
}
}
答案 10 :(得分:2)
对我来说,问题是电话没有连接到互联网。我断开连接并连接到Wi-Fi,并测试了与浏览器的连接并再次进行了测试。工作就像一个魅力: - )
答案 11 :(得分:0)
我已经为谷歌服务启用了“后台数据访问”。通过取消选中数据使用选项中的“限制后台数据”它对我有用!
答案 12 :(得分:0)
对我来说goolge阻止了我的IP!我不得不重置我的DSL conn从池中获取一个新的IP,一切都恢复了,idk为什么他们阻止我,也许是为了尝试很多应用程序?无论如何现在正在工作,我希望这有助于其他人:)
答案 13 :(得分:0)
对我来说,由于接收器类,SERVICE_NOT_AVAILABLE问题出现在我的应用程序项目中。
所以我在实现接收器后解决了如下问题。
<receiver
android:name="receiver name"
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="your package"/>
</intent-filter>
</receiver>
我希望这会对你有所帮助:-)。
答案 14 :(得分:0)
我有一个OnePlus2,在数据上无法接收推送。当我与logcat
连接时,我看到了很多错误,但我不确定它是否相关。
我放弃了尝试找到与之对应的设置,并且刚刚恢复出厂设置。运行OxygenOS的OnePlus设备有时会在安装软件更新时出现奇怪的配置错误,并且恢复出厂设置,然后从Google备份恢复,使得恢复工作的速度比理解底层问题要快得多(并且可能是用户甚至没有正确访问以解决潜在问题。)
答案 15 :(得分:0)
就我而言,这是因为我的手机内没有SIM卡。
我想拥有sim卡会在设备上设置“自动时间”,从而解决此问题。
答案 16 :(得分:-1)
经过长时间的努力,我设法解决了这个问题。 确保Google Play服务应用是最新的,并且未在手机上禁用其后台同步。