3

私と私の友人は、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() メソッドは、ドキュメントにあるようにバックグラウンド プロセスで実行されます。したがって、AsyncTask の代わりに通常の Thread を使用しましたが、これが問題を引き起こす可能性はないと思います。次のクラスは 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 対応です」という文字列が表示されるため、正しいはずです。Settings クラスは設定を保持するための独自の実装であり、Logbook クラスは 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 Services は最新 (バージョン 4.1.32) です。彼の Android バージョンは 4.3 で、Sony ストック ROM です。私の Nexus 4 は CM 11 のナイトリー ビルドで実行されています (つまり、Android 4.4.2 です)。

同じアプリが Wi-Fi 経由では正しく動作しますが、セルラー ネットワークでは動作しないことを覚えておいてください。これは私たち二人にとって混乱を招くだけであり、多くの問題解決アプローチを試みましたが、いずれも状況を改善するものはありませんでした.

誰かが私たちを助けてくれることを願っています、ありがとう

4

0 に答える 0