I'm running into an issue with my implementation of GCM on Android, min SDK 15. I am perfectly able to receive push notifications from GCM, and my GcmListenerService
implementation has a functioning onMessageReceived(...)
callback. My issue, though, is that whenever one or the other performs a receive, it forces the application into the foreground!
My expected behavior is that I am able to receive these push notifications as they come, whether or not the application is in the background, and then to create a notification in the tray that starts an activity should a payload require it.
The flow that causes an issue is (physical device, Motorola Razr M xt907):
1. Launch application. Device key is verified from GCM instanceID.
2. Press Home on Android.
3. Press Recent Apps key; swipe away the application; wait a few seconds
4. Manually send a push notification to the device via GCM
5. Application receives the notification, and the application forces itself back into the foreground
If it helps, I threw the main application and receivers into separate processes to get an idea of what was actually happening in the background, and a truncated version of this is below:
NotificationsProcess I/MultiDex﹕ VM with version 1.6.0 does not have multidex support
NotificationsProcess I/MultiDex﹕ install
NotificationsProcess I/MultiDex﹕ MultiDexExtractor.load(/data/app/com.MyApp.MyAppmobile.alpha-1.apk, false)
NotificationsProcess I/MultiDex﹕ loading existing secondary dex files
NotificationsProcess I/MultiDex﹕ load found 1 secondary dex files
NotificationsProcess I/MultiDex﹕ install done
...
[... Main Application Code ... ]
...
PrivateProcess I/MultiDex﹕ VM with version 1.6.0 does not have multidex support
PrivateProcess I/MultiDex﹕ install
PrivateProcess I/MultiDex﹕ MultiDexExtractor.load(/data/app/com.MyApp.MyAppmobile.alpha-1.apk, false)
PrivateProcess I/MultiDex﹕ loading existing secondary dex files
PrivateProcess I/MultiDex﹕ load found 1 secondary dex files
PrivateProcess I/MultiDex﹕ install done
NotificationsProcess D/MyApp﹕ Network is connected via WIFI
NotificationsProcess D/MyApp﹕ Executing networkWentOnline() callbacks
NotificationsProcess D/MyApp﹕ Successfully connected to GoogleApiServices for Location Awareness.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
GcmListenerService finally comes alive
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
NotificationsProcess D/GCMMessageHandler﹕ From: 149994375514
NotificationsProcess D/GCMMessageHandler﹕ Message: null
NotificationsProcess D/GCMMessageHandler﹕ Data: Bundle[{gcm.notification.body=Hey there dude, I like text =), collapse_key=com.MyApp.MyAppmobile.alpha}]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
GcmListenerService is finished
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
NotificationsProcess D/MyApp﹕ [... Main Application Code ... ]
NotificationsProcess D/MyApp﹕ [... Main Application Code ... ]
PrivateProcess D/MyApp﹕ [... Main Application Code ... ]
PrivateProcess D/MyApp﹕ [... Main Application Code ... ]
PrivateProcess D/MyApp﹕ [... Main Application Code ... ]
PrivateProcess D/MyApp﹕ [... Main Application Code ... ]
PrivateProcess D/MyApp﹕ [... Main Application Code ... ]
PrivateProcess V/TDCollateJSON﹕ SQLite3 handle is 1417181168
PrivateProcess D/MyApp﹕ [... Main Application Code ... ]
PrivateProcess D/MyApp﹕ [... Main Application Code ... ]
PrivateProcess D/MyApp﹕ [... Main Application Code ... ]
PrivateProcess D/MyApp﹕ [... Main Application Code ... ]
PrivateProcess D/MyApp﹕ [... Main Application Code ... ]
My Android manifest is setup as such, with the following items found under the main <application>
tag:
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:process="NotificationsProcess"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter
android:process="NotificationsProcess">
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
</intent-filter>
</receiver>
<service
android:name=".GCMMessageHandler"
android:process="NotificationsProcess"
android:exported="false">
<intent-filter
android:process="NotificationsProcess">
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<service
android:name=".GCMInstanceIDListenerService"
android:process="NotificationsProcess"
android:exported="false">
<intent-filter
android:process="NotificationsProcess">
<action android:name="com.google.android.gms.iid.InstanceID"/>
</intent-filter>
</service>
<service
android:name=".RegistrationIntentService"
android:process="NotificationsProcess"
android:exported="false">
</service>
[... Other app activities ...]
<activity
android:name=".activities.SyncActivity"
android:label="@string/app_name"
android:theme="@style/Theme.AppCompat.NoActionBar"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
I have the distinct feeling like this is a simple manifest issue, but I wouldn't be surprised if this is instead a much more subtle issue. If I can offer any more application output, please let me know!
Any experience, wisdom, or paths to try for this are greatly appreciated!
EDIT:
I am including the GcmListenerService implementation. Notice the only thing I do is actually create a notification and post it. With no interaction from the user, the application simply comes to the foreground - no tap, no swipe, just poof foreground.
@Override
public void onMessageReceived(String from, Bundle data) {
String message = data.getString("gcm.notification.body");
Log.d("GCMMessageHandler", "From: " + from);
Log.d("GCMMessageHandler", "Message: " + message);
MyApp.WAS_STARTED_FROM_NOTIFICATION = true;
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Hello from MyApp")
.setContentText(message);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(MY_APP_NOTIFICATION_ID, mBuilder.build());
}