GCM SERVICE_NOT_AVAILABE только в сотовой сети

Я и мой друг разрабатываем приложение для Android и внедрили все необходимое для GCM. На моем устройстве (Nexus 4) регистрация и получение сообщений работают нормально по WiFi и сотовой сети. Но если мой друг пытается зарегистрировать свое устройство (Xperia Z), оно выходит из строя по сотовой сети, и он получает ошибку SERVICE_NOT_AVAILABLE. Через Wi-Fi регистрация и получение сообщений работает нормально с его устройством тоже. Если он регистрирует свое устройство по 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() выполняется в фоновом процессе, как это делает документация. Поэтому мы использовали обычный поток вместо 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 и также должен быть корректным, поскольку в logcat появляется строка "Устройство поддерживает GCM". Класс "Настройки" - это наша собственная реализация для хранения настроек, а класс "Журнал" - только класс-оболочка для android.util.Log. Мой друг также сделал перехват своего сетевого трафика с помощью DDMS:

трафик с 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, и это стандартное ПО Sony. Мой Nexus 4 работает с ночной сборкой CM 11 (так что это Android 4.4.2).

Пожалуйста, помните, что одно и то же приложение работает правильно по Wi-Fi, но не по сотовой сети. Это просто сбивает нас с толку, и мы пробовали много подходов к решению проблем, но ни один из них не улучшил нашу ситуацию.

Я надеюсь, что кто-то может помочь нам, спасибо

0 ответов

Другие вопросы по тегам