Reputation: 186
I have implemented GCM messaging at my app and server and everything works fine but not on every phone!
The main problem is:
When app is opened i get the GCM message and i generate the notification as it's supposed, but when the app is closed i can see(through LOGCAT) that the message was received but cancelled -> "Broadcast receiver, result=CANCELLED".
Next thing is that i cannot get my app-services to work in the background. As long as i "close" my app from the "recent activities" menu it also stops in the background(going under Settings -> Apps -> "MY_APP" -> force stop is disabled).
I have done a lot of research and i think the cause may be that Huawei P8(the primary testing device) forcefully closes all apps automatically when you swipe them away from the "recent activities" tab. But if that's the case other apps like "Facebook", "Viber" and so on would not send me push notifications.
Manifest.xml
<receiver
android:name="com.happyhour.gcm.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.REBOOT"/>
<action android:name="android.intent.action.PACKAGE_REPLACED"/>
<action android:name="android.intent.action.BATTERY_CHANGED"/>
<action android:name="android.intent.action.USER_PRESENT"/>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.happyhour.main" />
</intent-filter>
</receiver>
<service
android:name="com.happyhour.gcm.GcmIntentService" >
</service>
<receiver android:name="com.happyhour.gcm.UpdateReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<action android:name="android.intent.action.PACKAGE_INSTALL"/>
<data android:path="com.happyhour.main"
android:scheme="package" />
</intent-filter>
</receiver>
GCMBroadCastReceiver
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Log.i("GcmBroadcast",intent.getExtras().toString());
SharedPreferences settings = context.getSharedPreferences("MyPrefsFile", 0);
if (settings.getBoolean("my_first_time", true)) {
//the app is being launched for first time, do something
//do nothing
// record the fact that the app has been started at least once
settings.edit().putBoolean("my_first_time", false).commit();
}else{
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
public class GcmIntentService extends IntentService {
private String TAG = "GcmIntent";
public static final int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
public GcmIntentService() {
super("GcmIntentService");
}
@Override
public void onCreate(){
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
onHandleIntent(intent);
return START_STICKY;
}
@Override
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
// The getMessageType() intent parameter must be the intent you received
// in your BroadcastReceiver.
Log.i(TAG, "Received: " + extras.toString());
String messageType = gcm.getMessageType(intent);
Log.i(TAG, "Message type:" + messageType);
if (!extras.isEmpty()) { // has effect of unparcelling Bundle
/*
* 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_MESSAGE.equals(messageType)) {
Log.i(TAG, "Completed work @ " + SystemClock.elapsedRealtime());
// Post notification of received message.
sendNotification(extras.getString("message"), extras.getString("title"));
Log.i(TAG, "Received: " + extras.toString());
}
}
// Release the wake lock provided by the WakefulBroadcastReceiver.
GcmBroadcastReceiver.completeWakefulIntent(intent);
}
// 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, String title) {
mNotificationManager = (NotificationManager)
this.getSystemService(Context.NOTIFICATION_SERVICE);
if(title.isEmpty()){
title="Happy Hour plus";
}
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, SplashScreen.class), 0);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_stat_notification)
.setContentTitle(title)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(msg))
.setContentText(msg)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setVibrate(new long[] {250,250,250,250})
.setAutoCancel(true);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
public boolean checkApp(){
ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
// get the info from the currently running task
List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
ComponentName componentInfo = taskInfo.get(0).topActivity;
if (componentInfo.getPackageName().equalsIgnoreCase("com.happyhour.main")) {
return true;
} else {
return false;
}
}
}
I am confused! I can't find the root of the cause.
Thanks in advance.
Upvotes: 2
Views: 1384
Reputation: 186
So apparently seems like EMUI interface of Huawei (P8 in my case) has a special way to handle things.
After installation of each app, it will prompt a toggle button asking you, whether or not, to allow this certain app to run in background.
So if an app comes straight from the Google Play store it won't prompt you this "Run in background" allowance button because it's a "trusted source" .
If you just export your .apk from Android Studio and install it straight to your phone it will prompt the button as shown above because installing straight on your phone falls in the case of the "untrusted source".
Finally if you are using the USB debugger option to install the .apk on the phone it will NEVER prompt the button and it will always act like you have pressed "off". Everytime you close the app it will force close all its tasks.
So, what i did was to transfer my Android-Studio-generated .apk into my phone and install it manually. When it prompted the button i toggled it to "ON" and that's it. I can finally receive GCM messages when app is closed!
I think that's an EMUI bug/special-app-handling problem.
Special thanks @TeChNo_DeViL for his help.
Upvotes: 3
Reputation: 739
You are using very old libraries. Consider switching to latest official GCM libraries. Make your listener extend GcmListenerService. Look up official docs for the same. Also it's far easier to maintain.
Ensure all TODO's mentioned below are properly done:
Upvotes: 2