サーバーからの通知を受信するためにGCMを使用し、Googleのgcm.jarを使用していて、customGCMIntentServiceクラスがそれを処理するアプリを作成しています。私の問題は、1つの受話器だけが、を呼び出したときにGCMから実際に応答を取得している(または応答を正しくルーティングしている可能性が高い)ことGCMRegistrar.register()
です。
私が見ているのは、GCMRegistrar(gcmライブラリから)が私のカスタムブロードキャストレシーバーをネクサス3電話のリトライレシーバーとして正しく設定していることです。これにより、GCMから応答が返される可能性がありますが、他の3台の電話では処理されていないと思います(詳細は以下を参照)。
GCMRegistrar Setting the name of retry receiver class to <My_application_package>.CustomGCMBroadcastReceiver
それらはすべて、GCMとの通信を可能にするデータ接続を備えており、アクティブなGmailアカウントを持っています(すべて、プレイストアが機能しています)。また、GoogleのGCMデモをすべて問題なく実行しました。
登録コード:
//This is almost identical to how Google's GCM demo does it.
private void registerOnGCM(){
checkNotNull(SERVER_URL, "SERVER_URL"); //What it says on the tin
checkNotNull(SENDER_ID, "SENDER_ID");
// Make sure the device has the proper dependencies.
GCMRegistrar.checkDevice(this);
// Make sure the manifest was properly set - comment out this line
// while developing the app, then uncomment it when it's ready.
GCMRegistrar.checkManifest(this);
/*
registerReceiver(mHandleMessageReceiver,
new IntentFilter(HANDLE_MESSAGE));
*/
final String regId = GCMRegistrar.getRegistrationId(getApplicationContext());
if (regId.equals("")) {
// Automatically registers application on startup.
GCMRegistrar.register(getApplicationContext(), SENDER_ID);
}
else {
// Device is already registered on GCM, check server.
if (GCMRegistrar.isRegisteredOnServer(getApplicationContext())) {
// Skips registration.
Log.i(TAG, "Already registered");
} else {
// Try to register again, but not in the UI thread.
// It's also necessary to cancel the thread onDestroy(),
// hence the use of AsyncTask instead of a raw thread.
final Context context = this;
mRegisterTask = new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
boolean registered = ServerUtilities.register(context, regId);
if (!registered) {
GCMRegistrar.unregister(context);
}
return null;
}
@Override
protected void onPostExecute(Void result) {
mRegisterTask = null;
}
};
mRegisterTask.execute(null, null, null);
}
}
CustomGCMBroadcastReceiverのコードは重要ではなく、GCMIntentServiceも重要ではありません。どちらも呼び出されないためです。問題は彼らにありません。
私がテストしているデバイス:
- CyanogenMod7を実行しているHTCDesireGSM
- Android4.1.1を実行しているGoogleNexus3(アプリケーションはこれで動作します)
- Android4.0.1を実行しているMotorolaT910
- Android4.2.6を実行しているSamsungGalaxymini
マニフェスト:
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="16" />
<uses-permission android:name="android.permission.INTERNET" />
<!-- App has permission to read/write files on sd card. Used for RSS document -->
<uses-permission android:name = "android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name = "android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- GCM connects to Google Services. -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- GCM requires a Google account. -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<!-- Keeps the processor from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<permission
android:name="<My_package_name>.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission
android:name="<My_package_name>.permission.C2D_MESSAGE" />
<!-- This app has permission to register and receive data message. -->
<uses-permission
android:name="com.google.android.c2dm.permission.RECEIVE" />
<application
android:allowBackup="true"
android:theme="@style/AppTheme"
android:label="@string/app_name">
<activity
android:name="<My_package_name>.MasterActivity"
android:screenOrientation="portrait">
</activity>
<activity android:name="<My_package_name>.WebActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!--
BroadcastReceiver that will receive intents from GCM
services and handle them to the custom IntentService.
The com.google.android.c2dm.permission.SEND permission is necessary
so only GCM services can send data messages for the app.
-->
<receiver
android:name="<My_package_name>.CustomGCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<!-- Receives the actual messages. -->
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<!-- Receives the registration id. -->
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="<My_package_name>" />
</intent-filter>
</receiver>
<!--
Application-specific subclass of GCMBaseIntentService that will
handle received messages.
By default, it must be named .GCMIntentService, unless the
application uses a custom BroadcastReceiver that redefines its name.
-->
<service android:name="<My_package_name>.GCMIntentService"
android:enabled="true"/>
</application>
追加するのを忘れたものかもしれません。お知らせ下さい。
すべてのアイデアを歓迎します。
-MrDresden