我創建了一個應用程序,它使用GCM從我們的服務器接收通知,使用Google的gcm.jar,並且有一個customGCMIntentService類來處理它。我的問題是,撥打GCMRegistrar.register()
時,只有一部手機實際上從GCM獲得響應(或更有可能正確路由響應)。自定義GCM廣播接收器沒有在幾個設備上使用,但在其他設備上使用
我所看到的是GCMRegistrar(來自gcm庫)正確地將我的自定義廣播接收器設置爲nexus 3手機上的重試接收器,唯一可用的,但不是其他的。這讓我相信我可能會從GCM獲得迴應,但是它並未在其他三部手機上處理(詳情如下)。
GCMRegistrar Setting the name of retry receiver class to <My_application_package>.CustomGCMBroadcastReceiver
所有這些具有數據連接的允許與GCM通信,都對它們的活性的Gmail帳戶(它們都具有Play商店中工作)。我也運行過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,因爲它們都不是不斷叫作。問題不在他們身上。
設備我測試的:
- HTC Desire的GSM運行的CyanogenMod 7
- 谷歌nexus 3運行Android 4.1.1(應用在這一個工程)
- 摩托羅拉T910運行Android 4.0.1
- 三星Galaxy mini運行Android 4.2.6
清單:
<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
大膽猜測。 – Hrafn 2013-02-13 16:39:19
@Qkyrie'<','>'是包名中的無效字符。 – wtsang02 2013-02-13 23:15:54