GCM服务在Android 2.2上不可用
我在Android 2.2设备上的GoogleCloudMessaging.register()调用中收到错误“SERVICE\u NOT\u AVAILABLE” 我正在编写一个应用程序,使用新的Google Play服务使用Google CloudMessaging。我使用Android网站上提供的指南实现了它,我的源代码中包含大量错误检查和处理代码,例如确保安装或更新了Google Play服务。GCM注册码还实现了一个指数退避,正如google建议的那样,可以实现一个指数退避来处理服务不可用的错误 我已经在一系列设备上测试了我的应用程序,包括ICS、JB、Honeycom甚至2.3.x设备。GCM注册工作正常,我可以通过GCM向其发送消息。然而,在2.2设备上,我在GoogleCloudMessaging.register()调用中不断收到一个SERVICE\u NOT\u AVAILABLE错误,即使在指数退避的情况下也是如此 GCM的故障设备准确地说是三星SGH-I896,手机上有2个谷歌账户。我已经读到这个错误可能是由错误配置的时间引起的,但是时间被设置为自动。该手机没有调制解调器,正在运行三星股票ROM 我还尝试过重新启动设备以及重新安装GooglePlay服务,但运气不好。在此问题上的任何帮助都将不胜感激 编辑:我尝试使用旧的GCM.jar和gcmregistar实现GCM,结果它在设备上工作。然而,由于谷歌已经不再支持这一方法,我几乎不认为这是一个很好的解决方案。GCM服务在Android 2.2上不可用,android,android-2.2-froyo,google-cloud-messaging,google-play-services,service-not-available,Android,Android 2.2 Froyo,Google Cloud Messaging,Google Play Services,Service Not Available,我在Android 2.2设备上的GoogleCloudMessaging.register()调用中收到错误“SERVICE\u NOT\u AVAILABLE” 我正在编写一个应用程序,使用新的Google Play服务使用Google CloudMessaging。我使用Android网站上提供的指南实现了它,我的源代码中包含大量错误检查和处理代码,例如确保安装或更新了Google Play服务。GCM注册码还实现了一个指数退避,正如google建议的那样,可以实现一个指数退避来处理服务不
EDIT2:查看已接受的答案。目前,除非谷歌修复此漏洞或有人提供更好的解决方案,否则我使用的是混合解决方案,它将在最初几次使用谷歌播放器服务(指数退避),但之后切换到GCMRegistar。我遇到了同样的问题。GCM在我运行安卓4.04的平板电脑上运行良好,但在我运行安卓2.3的智能手机上总是收到一个不可用的服务 我发现以下解决方法没有使用(据我所知)任何不推荐的类。将操作“com.google.android.c2dm.intent.REGISTRATION”添加到清单中的GCMBroadcastReceiver。这将使您能够在GCMBroadcastReceiver接收注册id
<receiver
android:name="YOUR_PACKAGE_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="YOUR_PACKAGE_NAME" />
</intent-filter>
</receiver>
虽然我仍然收到服务不可用错误,但我可以在我的GCMBroadcastReceiver中处理注册id,并且我可以向智能手机发送消息。这很奇怪,但对我来说是有效的。服务不可用可能是由于旧的或丢失的GooglePlayServices造成的。 使用GooglePlayServicesUtil检查版本,如果错误,则重定向到市场,以便用户可以手动安装-这将修复服务不可用的问题,并获得所有改进 和错误修复(以及新的错误:-) 如果您不能做到这一点-使用register()没有意义,那么该方法希望匹配的播放服务检索结果。为了向后兼容,它确实生成相同的广播。直接使用REGISTER intent或不推荐使用的库将继续工作-我建议使用intent,GCMRegistar与GoogleServicesFramework中的旧实现绑定(它调用intent.setPackage(GSF_PACKAGE)),因此无法从任何修复中获益
拥有最新版本的GCM——通过使用GooglePlayServicesUtil处理未自动安装的设备——不仅有助于注册。在阅读了来自的帖子后,我尝试了下面的代码,我成功地让我的活动获得了注册。只需添加以下内容:
<activity
android:name=".MyActivity"
... />
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="your.package.here" />
</intent-filter>
</activity>
在您的AndroidManifest.xml中,还有一件事需要注意,这让我大吃一惊。 我让它在emulator+和测试应用程序中运行良好,但在实际设备上部署它时遇到了问题。
始终获得服务\u不可用错误,并采用与上述答案类似的方法:
IntentFilter filter = new IntentFilter("com.google.android.c2dm.intent.REGISTRATION");
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.i(TAG, "Got into onReceive for manual GCM retrieval. "
+ intent.getExtras());
String regId = intent.getStringExtra("registration_id");
if (regId != null && !regId.isEmpty()) {
theResult.add(regId);
} else {
theResult.add("");
}
lastDitchEffortComplete = true;
}
};
cont.registerReceiver(receiver, filter);
这种方法奏效了。
但收到这些信息花了相当长的时间,在我的等待循环中,只有在我放弃并让事情继续进行之后,它才会检索到这些信息
这让我想到服务不可用可能还有另一个原因
这是我必须使用GCM进行抓取/注册的代码:
new AsyncTask<Void, Void, Void>() {
final long timeSleep = 1000;
@Override
protected Void doInBackground(Void... params) {
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(cont);
String registrationId = "";
int count = 0;
while (count < 1) {
try {
count++;
Log.i(TAG, "Starting GCM Registration Attempt #" + count);
registrationId = gcm.register(CLOUDAPPID);
rph.storeRegistrationId(registrationId);
return null;
} catch (IOException e) {
e.printStackTrace();
}
Log.w(TAG, "Registration failed. Retrying in " + timeSleep + " ms.");
try {
Thread.sleep(timeSleep);
} catch (InterruptedException e) {
}
}
return null;
}
}.execute().get();
阻止异步线程外结果的“聪明/欺骗”方法
事实证明,这就是造成问题的原因。
我刚一有:
.execute();
让它通过,并使算法/代码与报告一起工作,而不需要立即注册id,然后就可以了。我甚至不需要手动广播接收器,它只是正常工作。如果标记的答案对您不起作用(就像对我一样),请检查您设备前面的人,可能摇动它,然后启用internet连接。为我工作;-)
如果没有internet,您会收到相同的异常,我花了一个下午的时间研究服务的复杂问题……这个错误也发生在我身上,但它发生了,因为我试图通过公司的防火墙在GCM中注册。在我找到的文档中: “注意:如果您的组织具有限制流量的防火墙 到Internet或从Internet访问时,您需要将其配置为允许 连接GCM,以便您的Android设备接收 要打开的端口通常为:5228、5229和5230.GCM 仅使用5228,但有时使用5229和5230。GCM不使用 提供特定的IP,因此您应该允许防火墙接受 到IP块中包含的所有IP地址的传出连接 在谷歌15169年的ASN中列出。”
一旦我打开端口或尝试从另一个网络,它就工作了。我也有同样的问题,但它发生在所有设备上。我花了很长时间才发现我的问题,但我想我
.execute.get();
.execute();
public class Login extends Activity {
Context context;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
context = getApplicationContext();
//Get GCM registration id
new GcmRegistrationAsyncTask().execute(context);
Set<Tuple> timeline = new HashSet<Tuple>();
try {
//Get data from Redis database
timeline = new RedisAsyncTask().execute(context).get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
public class Login extends Activity {
Context context;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
context = getApplicationContext();
new GcmRegistrationAsyncTask().execute(context);
new RedisAsyncTask().execute(context);
}
}