问题
My GCM client is able to register on all versions but messages are received on android above 4.x versions, not on android 2.3.6. I have made many changes but I cannot figure this problem out please help me, thanks in advance.
manifest file code
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.democlientapp"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:name="com.democlientapp.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.democlientapp.permission.C2D_MESSAGE" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version"/>
<activity android:name="com.google.android.gms.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>
<activity
android:name="com.democlientapp.RegisterActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.democlientapp.MainActivity"
android:label="@string/app_name" >
</activity>
<receiver
android:name="com.democlientapp.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="com.democlientapp" />
</intent-filter>
</receiver>
<service android:name="com.democlientapp.GcmIntentService" />
</application>
</manifest>
GCMBrodcastReceiver.java
package com.democlientapp;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.WakefulBroadcastReceiver;
import android.util.Log;
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.i("tag", "****************GcmBroadcastReceiver.java ok*************");
// Explicitly specify that GcmIntentService will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(),
GcmIntentService.class.getName());
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
GCMIntentService.java
package com.democlientapp;
import android.app.IntentService;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import com.google.android.gms.gcm.GoogleCloudMessaging;
public class GcmIntentService extends IntentService {
public static int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
String TAG="tag";
SharedPreferences sp;
StringBuffer sb;
public GcmIntentService() {
super("GcmIntentService");
}
@Override
protected void onHandleIntent(Intent intent) {
Log.i("tg", "intent sservice******************");
String extras1 = intent.getExtras().getString("data");
//Log.i("tag", "string extras :"+extras1.toString());
Bundle extras=intent.getExtras();
//Log.i("tag", "bundle extras :"+extras);
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
// The getMessageType() intent parameter must be the intent you received
// in your BroadcastReceiver.
String messageType = gcm.getMessageType(intent);
if (!extras.isEmpty()) { // has effect of unparcelling Bundle
Log.i("tag", "entered");
/*
* Filter messages based on message type. Since it is likely that GCM
* will be extended in the future with new message types, just ignore
* any message types you're not interested in, or that you don't
* recognize.
*/
if (GoogleCloudMessaging.
MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
sendNotification("Send error: " + extras.toString());
} else if (GoogleCloudMessaging.
MESSAGE_TYPE_DELETED.equals(messageType)) {
sendNotification("Deleted messages on server: " +
extras.toString());
// If it's a regular GCM message, do some work.
} else if (GoogleCloudMessaging.
MESSAGE_TYPE_MESSAGE.equals(messageType)) {
// This loop represents the service doing some work.
for (int i=0; i<5; i++) {
Log.i(TAG, "Working... " + (i+1)
+ "/5 @ " + SystemClock.elapsedRealtime());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
Log.i(TAG, "Completed work @ " + SystemClock.elapsedRealtime());
Log.i(TAG, "Received: " + extras.toString());
// Post notification of received message.
sendNotification("Received: " + extras);
}
}
//Log.i(TAG, "Received11111111111111111111");
//sendNotification("Received: registeration "+extras);
// Release the wake lock provided by the WakefulBroadcastReceiver.
//Log.i(TAG, "Received22222222222222222222222");
GcmBroadcastReceiver.completeWakefulIntent(intent);
//Log.i(TAG, "Received3333333333333333");
}
// Put the message into a notification and post it.
// This is just one simple example of what you might choose to do with
// a GCM message.
private void sendNotification(String msg) {
Log.i("tag","GcmBroadcastReceiver.java send notification");
//storing message in shared preference
StoreMsg(msg);
mNotificationManager = (NotificationManager)
this.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Spy notification")
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(msg))
.setContentText(msg);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
//mNotificationManager.no
//NOTIFICATION_ID++;
}
public void StoreMsg(String Msg)
{
String name="MyPrefs";
sp = this.getSharedPreferences(name, Context.MODE_PRIVATE);
sb=new StringBuffer();
String mg = sp.getString("MESSAGES", "false");
if (mg.equals("false")) {
//sb.append(mg);
sb.append(Msg);
}
else{
sb.append(mg+"\n****************");
sb.append("\n"+Msg);
}
Log.i("tag", "storemsg is: "+sb);
Editor editor = sp.edit();
editor.putString("MESSAGES",sb.toString());
//Log.i("tag","Gcmintentservice.java,MESSAGES storing SharedPreferences");
editor.commit();
//Log.i("tag", "registeractivity.java, onclick method client username exists in DB");
}
public String getMsg(){
String name="MyPrefs";
sp = this.getSharedPreferences(name, Context.MODE_PRIVATE);
String prefName = sp.getString("MESSAGES", "false");
Log.i("tag", "storemsg is: "+sb);
return prefName;
}
}
回答1:
If you are using product flavors maybe you have the same problem than I found.
I found that when using flavors with diferent applicationId, then your package in the AndroidManifest file for the permission and the category is not correct. And this does not matter for Android 5.x, but for Android 2.3 causes that the broadcast receiver will never be called.
The solution I found is use the gradle's placeholder support. Using ${applicationId} the issue is resolved for all the Android versions.
build.gradle:
productFlavors {
prod {
applicationId 'com.democlientapp'
}
dev {
applicationId 'com.democlientapp.dev'
}
}
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.democlientapp"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:name="${applicationId}.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="${applicationId}.permission.C2D_MESSAGE" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version"/>
<activity android:name="com.google.android.gms.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>
<activity
android:name="com.democlientapp.RegisterActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.democlientapp.MainActivity"
android:label="@string/app_name" >
</activity>
<receiver
android:name="com.democlientapp.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="${applicationId}" />
</intent-filter>
</receiver>
<service android:name="com.democlientapp.GcmIntentService" />
</application>
</manifest>
回答2:
Use Latest dependency/library for GCM for sdk version 4 or heigher
compile "com.google.android.gms:play-services-gcm:10.2.0"
in build.gradle file in dependency. and add build.gragle level file
classpath 'com.google.gms:google-services:3.0.0'
its works for hiegher versions.
来源:https://stackoverflow.com/questions/28926947/gcm-messages-are-not-received-on-android-2-3-6-v-but-working-fine-on-android-4-x