I got a program including GCM service and the GCM service performs perfectly on some of my devices
including:
1)android emulator (Google API 17 - 4.2.2)
2)LG Phone (Android 4.1.2)
3)Google phone (Android 4.2.2)
However, on the following device it seems the GCM function stops at registration status and
onRegistered()
was not called.
including:
1)Sony (Android 4.0.4)
2)HTC (Android 4.0.3)
3)SAMSUNG Tablet (Android 3.0.3)
Since it can run on some of my devices, I am pretty sure the problem is not in my code or the Android manifest permission settings, but I don't know what can I add or modify to solve this.
I knew that GCM function for version 4.0.4 and lower needs an active Google account, but I tried it and it's still not working. Meanwhile I tried the solution suggested in these two questions, but it didn't help
I can not get registration ID from Android GCM
Android GCM : GCMRegistrar gives empty registration ID
Can anyone give me some advice how to solve this problem? Any other way I can perform server push notification function?
Here are my code
//GCM part
cd = new ConnectionDetector(getApplicationContext());
// Check if Internet present
if (!cd.isConnectingToInternet()) {
// Internet Connection is not present
alert.showAlertDialog(this,
"Internet Connection Error",
"Please connect to working Internet connection", false);
// stop executing code by return
return;
}
// Getting name, email from intent
Intent i = getIntent();
// Make sure the device has the proper dependencies.
try{
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);
}catch(Exception e){
Toast.makeText(getApplicationContext(), "Version too old" + e.toString(), Toast.LENGTH_LONG).show();
}
registerReceiver(mHandleMessageReceiver, new IntentFilter(
DISPLAY_MESSAGE_ACTION));
// Get GCM registration id
final String regId = GCMRegistrar.getRegistrationId(this);
// Check if regid already presents
if (regId.equals("")) {
// Registration is not present, register now with GCM
try{
GCMRegistrar.register(this, SENDER_ID);
Toast.makeText(getApplicationContext(), "Trying to register", Toast.LENGTH_LONG).show();
}
catch(Exception e){
Toast.makeText(getApplicationContext(), "Registration failure", Toast.LENGTH_LONG).show();
}
} else {
// Device is already registered on GCM
if (GCMRegistrar.isRegisteredOnServer(this)) {
// Skips registration.
Toast.makeText(getApplicationContext(), "Already registered with GCM", Toast.LENGTH_LONG).show();
} 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) {
// Register on our server
// On server creates a new user
ServerUtilities.register(context, userId, "123", regId);
return null;
}
@Override
protected void onPostExecute(Void result) {
mRegisterTask = null;
}
};
mRegisterTask.execute(null, null, null);
}
}
And also Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.activity"
android:versionCode="1"
android:versionName="2" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- GCM connects to Internet 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" />
<!-- Creates a custom permission so only this app can receive its messages. -->
<permission
android:name="com.test.activity.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.test.activity.C2D_MESSAGE" />
<!-- This app has permission to register and receive data message. -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<!-- Network State Permissions to detect Internet status -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Permission to vibrate -->
<uses-permission android:name="android.permission.VIBRATE" />
<application
.
.
.
<receiver
android:name="com.google.android.gcm.GCMBroadcastReceiver"
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="com.test.activity" />
</intent-filter>
</receiver>
<service android:name="com.test.activity.GCMIntentService" />
</application>
</manifest>