GCM SERVICE_NOT_AVAILABE仅适用于蜂窝网络

时间:2014-02-06 20:53:55

标签: java android networking google-cloud-messaging service-not-available

我和我的朋友正在开发一款Android应用,并实施了GCM所需的一切。在我的设备(Nexus 4)上,通过WiFi和蜂窝网络可以正常注册和接收消息。但如果我的朋友试图注册他的设备(Xperia Z),它会通过蜂窝网络进行故障恢复,并且他会收到SERVICE_NOT_AVAILABLE错误。通过WiFi,注册和消息接收也可以正常使用他的设备。如果他在WiFi上注册他的设备,然后切换回蜂窝数据,他就没有收到任何消息!

我们没有足够的设备来测试他的设备是否存在问题或我们的应用中存在问题,因此我们希望您能帮助我们。以下是我们项目的一些文件,如果您需要更多详细信息,我会在之后添加它们。

的AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="de.mypackage.vorlesungsplan.app"
    android:versionCode="0010201"
    android:versionName="1.2.1 (Raw Potato)" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.GET_ACCOUNTS"/>
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
    <uses-permission android:name="android.permission.GET_TASKS"/>
    <permission android:name="de.mypackage.vorlesungsplan.app.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />
    <uses-permission android:name="de.mypackage.vorlesungsplan.app.C2D_MESSAGE" />
    <supports-screens android:normalScreens="true" android:xlargeScreens="true" android:largeScreens="true" android:smallScreens="false"/>

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme"
        android:allowBackup="false" >
        <activity
            android:name="MainActivity"
            android:label="@string/title_activity_startup" android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="SettingsActivity" android:label="Einstellungen" android:screenOrientation="portrait"></activity>
        <activity android:name="InfoHelpActivity" android:screenOrientation="portrait"></activity>
        <activity android:name="LunchActivity" android:screenOrientation="portrait"></activity>
        <meta-data android:name="com.google.android.gms.version"
           android:value="@integer/google_play_services_version"/>

        <receiver
            android:name=".io.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="de.mypackage.vorlesungsplan.app" />
            </intent-filter>
        </receiver>
        <service android:name=".io.GCMIntentService" />
    </application>

</manifest>

register()方法在后台进程上执行,就像文档假装它一样。因此我们使用普通的Thread而不是AsyncTask,但我认为这不会导致问题。以下类扩展了Thread类:

RegisterServerOperation.java

public void run() {
    ...

    if(checkPlayServices()) {
        Logbook.d("Device is GCM capable");

        // Hole die regId des Geräts oder erzeuge eine neue
        GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(activity);
        String regId = Settings.getInstance(activity).getSetting("regId");

        if (regId == null || regId.isEmpty()) {
            regId = gcm.register(SENDER_ID);
            Settings.getInstance(activity).setSetting("regId", regId);
        }

        Logbook.d("Registration id for this device is: "+regId);
    } else {
        throw new Exception("REGISTRATION_FAILED");
    }

    ...
}

checkPlayServices()方法是从Google示例中复制的,也应该是正确的,因为“设备支持GCM”字符串会出现在logcat中。 Settings类是我们自己的实现,用于保存设置,而Logbook类只是android.util.Log的包装类。我的朋友也用DDMS捕获了他的网络流量:

traffic caputer with ddms

第一个峰值是由我们的应用在开始时发送的正常http请求引起的。它证明了他的蜂窝网络连接在这一刻是可行的。在此之后,应该有另一个由gcm.register(...)方法引起的峰值,但没有任何内容。

我们使用以下版本的google_play_services_lib项目构建了应用程序:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <integer name="google_play_services_version">4132500</integer>
</resources>

其设备上安装的Google Play服务是最新的(版本4.1.32)。他的Android版本是4.3,它是索尼的股票ROM。我的Nexus 4运行的是每晚构建的CM 11(因此它是Android 4.4.2)。

请记住,相同的应用程序在wifi上正常工作,但不是蜂窝网络。这对我们两个人来说都很困惑,我们已经尝试了许多解决问题的方法,但没有一个能改善我们的情况。

我希望有人可以帮助我们,谢谢

0 个答案:

没有答案