Soluciones tecnológicas
Soluciones tecnológicasLa inteligencia artificial generativa pasa a ser parte como un pilar fundamental de la ...
Open Banking, powered by Generative Artificial Intelligence (GenAI), is redefining the ...
SANTA CLARA, Calif.–January 10, 2025–GlobalLogic Inc, una empresa del Grupo...
GlobalLogic establecerá un centro de desarrollo de ingeniería de software automotriz en...
GlobalLogic ofrece una combinación única de experiencia y conocimientos en la intersección entre datos, diseño e ingeniería.
ContáctanosLast week, I had to update the current app (changing the targetSdkVersion to 26 ) to support Android Oreo (8.0) . Everything works great (in previous versions) but in Oreo that was not the happy case. The notifications were not working as expected: the app was crashing when a push notification was received by device. This was the exception in logcat:
Fatal Exception: java.lang.RuntimeException: Unable to start receiver com.google.firebase.iid.FirebaseInstanceIdInternalReceiver: java.lang.IllegalStateException: Not allowed to start service Intent { act=com.google.firebase.INSTANCE_ID_EVENT pkg=PACKAGE cmp=COMPONENT }: app is in background uid UidRecord{c5e5e69 u0a325 RCVR bg:+1m25s411ms idle procs:1 seq(0,0,0)}
at android.app.ActivityThread.handleReceiver(ActivityThread.java:3397)
at android.app.ActivityThread.-wrap18(Unknown Source)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1780)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6938)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
Well, I’ll be honest and I should confess that I spent one day researching information about this problem. In addition, the project has a gradle file with a lot of dependencies to be used in every module. This distribution helps to keep all dependencies in one place and then make a reference to them from the specific build.gradle file.
After doing a quick investigation about the problem, the main cause was: “ Not allowed to start service ”. This message is thrown from Android system when you try to start a service when the app is in the background or it is not running. That was the starting point . All posts were referenced to Background Execution Limits : the best solution is to create a notification receiver in the middle to execute the service as it matches. First mistake : that was not I have in my code. Using Firebase Messaging Cloud , there was not place where a service was starting. SW? Are there other solutions?
Well, the main problem was the FCM version I had : it was pointing to 8.4.0 which it does not support Oreo .
After playing around on this, I figured out the FCM version 11.4.0 supports Android Oreo. Actually, Oreo support was introduced in 11.2.0 . You can use whatever you want.
dependencies {
compile 'com.google.firebase:firebase-core:11.4.0'
compile 'com.google.firebase:firebase-messaging:11.4.0'
}
The official documentation suggests use 11.8.0 instead. Again, you can choose whatever you want .
“Nice, so that’s all, right?” Well, not really. Oreo introduced a new concept for notifications named Notification Channels . All notifications must be assigned to a channel or it will not appear . So, if we have our app targeting API 26 and we should display a notification for any reason, we must assign it to a channel. Otherwise, you will get a warning toast message like this one:
The first step is create a channel id . The best place to create one is in strings.xml file.
<string name="default_notification_channel_id" translatable="false">fcm_default_channel</string>
Then, you must add a meta-data in manifest file to enable it:
<application>
...
<meta-data android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="@string/default_notification_channel_id"/>
</application>
Perfect, our last step is the assignment on code side. In the same place where you are calling to notify method to display the notification, you should add the channel assignment :
...
// Since android Oreo notification channel is needed.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String channelId = context.getString(R.string.default_notification_channel_id);
NotificationChannel channel = new NotificationChannel(channelId, title, NotificationManager.IMPORTANCE_DEFAULT);
channel.setDescription(body);
mNotificationManager.createNotificationChannel(channel);
builder.setChannelId(channelId);
}
mNotificationManager.notify(1, notification);
...
And that’s it! Now the app should work on devices with Oreo.
You can check the following repo to make sure you are doing it in a right way:
firebase/quickstart-android
quickstart-android – Firebase Quickstart Samples for Android github.com
Please, feel free to comment, suggest or ask anything you want. Happy coding!