Closed Dimezis closed 6 years ago
HI @Dimezis I believe you'll need to migrate to FCM if you target Android O+. FCM doesn't use a receiver https://firebase.google.com/docs/cloud-messaging/android/client. I don't think it can be solved unless Google are doing something under the hood in their Play Services which seems they are not.
Let us know if you have any issues migrating. If you migrate your app correctly you should be able to target previous devices too using FCM.
Actually it should not have any problems as that intent filter is not an implicit one, only you app would receive that broadcast. We've tested here and we are having no problems but we'll keep digging. Do you by any chance have another provider and are using a different method to invoke our code (for example the code we had in the docs)?
@Sergio-Mira thank you for investigation. Are you targeting sdk 26+ and using 26+ build tools though? No, I don't have other providers, everything I have related to GCM is:
<receiver android:name="com.google.android.gms.gcm.GcmReceiver"
android:exported="true"
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="${packageName}" />
</intent-filter>
</receiver>
<service android:name="com.swrve.sdk.gcm.SwrveGcmIntentService" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<service android:name="com.swrve.sdk.gcm.SwrveGcmInstanceIDListenerService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID" />
</intent-filter>
</service>
And it works fine while in the app, but not after killing app's process. I also tried implementing custom receiver:
@Override
public void onReceive(Context context, Intent intent) {
boolean interceptedIntent = false;
// Call the Swrve intent service if the push contains the Swrve payload _p
if("com.google.android.c2dm.intent.RECEIVE".equals(intent.getAction())) {
Bundle extras = intent.getExtras();
if (extras != null) {
Object rawId = extras.get(SwrvePushConstants.SWRVE_TRACKING_KEY);
String msgId = (rawId != null) ? rawId.toString() : null;
if (!SwrveHelper.isNullOrEmpty(msgId)) {
// It is a Swrve push!
interceptedIntent = true;
ComponentName comp = new ComponentName(context.getPackageName(),
SwrveGcmConstants.SWRVE_DEFAULT_INTENT_SERVICE);
intent.setComponent(comp);
context.startService(intent);
}
}
}
if (!interceptedIntent) {
// Continue normally if the push is not a Swrve push
super.onReceive(context, intent);
}
}
But getting exception on context.startService(intent);
. So the receiver does get called, but it's impossible to start non-foreground service from the background.
Caused by: java.lang.IllegalStateException: Not allowed to start service Intent { act=com.google.android.c2dm.intent.RECEIVE flg=0x1000010 pkg=my.package cmp=my.package/com.swrve.sdk.gcm.SwrveGcmIntentService (has extras) }: app is in background uid UidRecord{8dc6f59 u0a186 RCVR idle procs:1 seq(0,0,0)}
at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1505)
at android.app.ContextImpl.startService(ContextImpl.java:1461)
at android.content.ContextWrapper.startService(ContextWrapper.java:644)
at android.content.ContextWrapper.startService(ContextWrapper.java:644)
Hi @Dimezis, can you can more details on how to reproduce the issue? We have been testing on Pixel 2 running Oreo, with an app targeting 26, using build tools 26+, swiping the app away from recent tasks, rebooting the device, and we still can't reproduce the issue. Also, can you give details on how you are "killing" the app process?
Hey, by killing the process I mean swiping it out from recents, just as you did. And then trying to send a notification from https://dashboard.swrve.com to a particular QA device. Nothing extra.
Please tell me what kind of details do you need, I can debug the places you're interested in and report all my findings.
But so far I don't understand how it can work on Android O.SwrveGcmIntentService
can't be started, because it's impossible to start a non foreground service in Android O when the app is in background.
Can you guys explain the flow Swrve supposed to have on Android O?
Sorry for delay in getting back. The SwrveGcmIntentService service is called by the OS, not swrve sdk, and the OS is not prohibited from doing this on Oreo. The GcmListenerService class would be deprecated if this was not allowed to be used anymore.
I'm still unable to reproduce the issue. I've attached a sample project that uses the configurations you originally posted:
Can you try the sample project and let me know what is different to your setup? I'd like to get to the bottom of it. Thanks for your patience!
Thank you, indeed it works OK in this sample app with my API keys.
So far I don't see any significant differences in setup though, but I had only a brief look. Will investigate it a bit more later and report the problem
Sorry guys, this issue is irrelevant. Long story short, the problem was in app's DI setup, Swrve is fine :)
Great it was resolved, thanks for letting us know!
@Dimezis I am facing exactly the same issue with similar configurations. On Android O as well. Could you share the solution you found? If it is related with Dependency Injection, what was exactly the problem?
@jiahaoliuliu Honestly, I don't remember details already. But I think it was because we initialized SDK in some Activity instead of Application. So when the process was started from the Receiver, it didn't work until you actually open the app.
You are exactly right. That would indeed cause an issue. The SDK must be initialised from the Application class.
Interesting. Thanks for point out the problem. We do initialize the Swrve on the application but we are facing the same problem. We register a custom Broadcast receiver and then start the Swrve service from there. The main issue is the app only crashes on Android 8 or above.
Now, the solution we found is apply the method StartForegroundService instead of start the service normally. It seems to work good.
To support multiple providers / custom receivers etc in Android O you need to update your code as shown in our sample https://github.com/Swrve/swrve-android-sdk/tree/release-5_2/samples/MultipleGCMProviders
Also worth noting, we have a major improvement for that sample which possibly fixes the integration on Android O. Being scheduled for release in next couple of weeks.
Hey Guys,
I am facing issue with Android O with GCM push notification. Can anyone guide me how to use JobIntentService instead of migrating to FCM? Due to some restrictions migrating FCM is not possible now.
@mehtaketan7 The following sample shows how to integrate for Android O https://github.com/Swrve/swrve-android-sdk/tree/release-5_2/samples/MultipleGCMProviders
However please be aware that GCM will be deprecated next year and you'll need to migrate before then.
If you still have issues please create a new issue instead.
@Sergio-Mira Yeah I aware about this but as of now customer facing into the live application we are already working to migrate to FCM but till now I have to resolve existing issue for Android O devices.
Thanks for your quick reply. Appreciated!
@Sergio-Mira can you suggest me native changes without using third-party SDK.
I want something like this. https://stackoverflow.com/questions/49117558/android-oreo-broadcastreceiver-jobintentservice-does-not-work-properly-gcm
But I am not aware below things where should I change this. EDIT: I fixed this issue by changing notification channel parameter IMPORTANCE from IMPORTANCE_DEFAULT to IMPORTANCE_HIGH!
Is it possible to receive pushes from Swrve on Android O, when the app process is not running? I'm using Swrve 4.11.3 with Play Services 11.6.2, my app is targeting SDK 27 now, and it seems like I am able to receive pushes only when the app is running, but not if you kill the process. Prior to Android O it was possible.
This seems to be related to https://developer.android.com/about/versions/oreo/background.html#broadcasts (GCM broadcast receiver not triggered), but not 100% sure, as I'd expect intents for GCM broadcasts to be explicit.
Do you know if this issue can be resolved for GCM, or I need to move to FCM?