谷歌云消息传递 - GCM - 无法使用服务

23

我正在尝试实现新的GCM,我正在遵循Google的入门指南:http://developer.android.com/guide/google/gcm/gs.html

但是我无法获取到设备注册ID!

我的应用一直在尝试与Google服务器连接,下面是出错日志:

onReceive: com.google.android.gcm.intent.RETRY
GCM IntentService class: com.dombox.app.GCMIntentService
Acquiring wakelock
[GCMIntentService] start
Registering app com.dombox.app of senders _my_sender_id_
Releasing wakelock
onReceive: com.google.android.c2dm.intent.REGISTRATION
GCM IntentService class: com.dombox.app.GCMIntentService
Acquiring wakelock
[GCMIntentService] start
handleRegistration: registrationId = null, error = SERVICE_NOT_AVAILABLE, unregistered = null
Registration error: SERVICE_NOT_AVAILABLE
Scheduling registration retry, backoff = 912617 (768000)
Releasing wakelock

这是我的Activity代码,询问一个ID:

    try{
        Log.i(TAG, "[checkNotifRegistration] checkDevice");
        GCMRegistrar.checkDevice(this);
        Log.i(TAG, "[checkNotifRegistration] checkManifest");
        GCMRegistrar.checkManifest(this);
        if (GCMRegistrar.isRegistered(this)) {
            Log.i(TAG, "[checkNotifRegistration] reg id : "+GCMRegistrar.getRegistrationId(this));
        }
        final String regId = GCMRegistrar.getRegistrationId(this);
        if (regId.equals("")) {
            // SENDER_ID is my project id into google account url
            GCMRegistrar.register(this, SENDER_ID);
            Log.i(TAG, "[checkNotifRegistration] reg id : "+GCMRegistrar.getRegistrationId(this));
        } else {
            Log.i(TAG, "[checkNotifRegistration] already registered as : " + regId);
        }
    } catch(Exception e){
        Log.e(TAG, "[checkNotifRegistration] Exception : "+e.getMessage());
        e.printStackTrace();
    }

这是我的服务代码

public class GCMIntentService extends GCMBaseIntentService {

private static final String TAG = "GCMIntentService";

public GCMIntentService() {
    super(SENDER_ID);
           // SENDER_ID is my project id into google account url
    // TODO Auto-generated constructor stub
    Log.d(TAG, "[GCMIntentService] start");
}


public GCMIntentService(String senderId) {
    super(senderId);
    // TODO Auto-generated constructor stub
    Log.d(TAG, "[GCMIntentService] start - sender Id : "+senderId);
}
}

以下是我的 Android 清单文件:

<permission android:name="com.dombox.app.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="com.dombox.app.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

<application
    android:icon="@drawable/icon"
    android:label="@string/app_name" >

    <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.myapp.app" />
        </intent-filter>
    </receiver>

<service android:name=".GCMIntentService" android:enabled="true"/>

    <activity
        android:name=".activity.Myapp"
        android:label="@string/app_name" >

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

    </activity>

我遵循谷歌的指示,但却遇到了SERVICE_NOT_AVAILABLE错误,

我做错了什么?

6个回答

39

问题不是代码相关的,而是与测试手机的链接有关。 测试手机没有SIM卡,并且时钟没有设置。因此Google无法使用错误的时间进行注册。

我通过使用带有Google API的Android虚拟设备,并且设置了测试手机的时钟,成功获取到了注册ID。


我曾经遇到同样的问题,即使使用了可行的代码,原因是时间设置不正确。 - Zachary Moshansky
你有遇到过这种情况吗? 这个应用程序以前在我的虚拟机(Google API)上运行得很顺畅,但现在却卡在了“service_not_available - retry cycle”阶段。 - Marl
你的 AVD 上安装的 Android 版本是什么? - Muhammad Babar
我正在使用三星S2手机,但一直出现“service_not_available”的错误。请帮忙解决。 - user2085965
我的Android 5.0.2设备时间是正确的,但它没有SIM卡。在一个插有SIM卡的相同设备上运行良好。 - Hashim Akhtar
显示剩余2条评论

7
android:enabled="true"  

如果您还没有将此添加到您的清单文件中,请执行以下操作:
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="8"

您不需要在GCMIntentService中使用第二个构造函数,只需要使用这一个。
public GCMIntentService() {         
 super(SENDER_ID);  }

确保你的SENDER_ID是从你浏览Google Code网站和GCM服务时从浏览器URL中复制出来的数字。


小心我发布的targetSdkVersion。它可能会影响您的布局,并在您在新的SDK上运行时引发可能的异常。 - Ryan Gray
我将我的目标API级别设置为8,同时设置了<uses-sdk android:minSdkVersion="3" android:targetSdkVersion="8"/>。但是我仍然遇到了一个SERVICE_NOT_AVAILABLE错误。 - Thomas Besnehard
1
@Tommecpe 刚刚解决了 SERVICE_NOT_AVALIBLE 问题。如果您没有收到 RegID,请检查您的目录,如果还是没有,请重新启动设备并再次尝试,这对我有用。 - Maikel Bollemeijer
你的XML标签 <minSdkVersion="3"/> 必须改为 <minSdkVersion="8"/>。我对你迂回的评论感到困惑。 - Ryan Gray
1
问题并非与代码有关,而是与测试手机使用的谷歌帐户链接或测试手机本身有关。我成功地在带有 Google API 的 Android 虚拟设备上获得了注册 ID。感谢您的帮助。 - Thomas Besnehard
设备恢复出厂设置帮助了我。 - vokilam

3

请记住,如果您在公司防火墙后面,GCM使用的某些端口可能无法通过本地无线电进行通信。当我最初尝试让模拟器工作时,我遇到了这个问题。我不得不获取一个允许以下端口通过的特殊IP。


注意:如果您的组织有限制互联网流量的防火墙,您需要配置它以允许与GCM建立连接,以便您的Android设备接收消息。要打开的端口是:5228、5229和5230。GCM通常只使用5228端口,但有时也会使用5229和5230端口。GCM不提供特定的IP地址,因此您应该允许防火墙接受到在Google的ASN 15169中列出的所有IP地址的传出连接。

http://developer.android.com/google/gcm/gcm.html


2
我遇到了这个问题......我的解决方案是禁用互联网连接并使用电话服务。

在平板电脑上使用3G代替Wifi连接对我也起作用了。谢谢! - Stefan Hoth

2
我曾遇到这个问题,它是由WIFI连接引起的。我关闭了WIFI并再次进行测试(使用3G),结果成功了。然后我重新打开了WIFI,又出现了错误。为了确认,我又切换回了3G,结果又成功了。
因此,总结来说,这个问题是由连接引起的。

1

我在Genymotion上运行应用程序时遇到了问题。按照这里所说的安装Google Play服务,一切都正常工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接