Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android 9 (Pie) Only: Context.startForegroundService() did not then call Service.startForeground() - Works fine on Oreo

Tags:

We adjusted our ongoing notification for Oreo and it worked great. Now, on Pie only (not happening on Oreo devices), we're getting the titled error. Has something changed in foreground services in Pie that I'm missing?

Here's the onCreate code for the foreground service ->

override fun onCreate() {
    super.onCreate()

    val notification: Notification = NotificationCompat.Builder(this, packageName)
            .setSmallIcon(R.drawable.status_notification_icon)
            .setContentTitle(getString(R.string.ongoing_notify_temp_title))
            .setContentText(getString(R.string.ongoing_notify_temp_message))
            .setGroup(AppConstants.NOTIFICATION_GROUP_ONGOING)
            .setColor(ContextCompat.getColor(this, R.color.custom_blue))
            .build()

    startForeground(ONGOING_NOTIFY_ID, notification)

    appSettings = AppSettings(this)

    weatherLookUpHelper = WeatherLookUpHelper()
    MyRoomDatabase.getInstance().invalidationTracker.addObserver(onChange)

    retrieveCurrentLocation()
    createAlarmManager()
}

as you can see, we're just creating the notification and then calling startForeground. Any ideas on why this code would generate the titled error?

Side Note: Fabric Crashlytics shows this crash only happening on Pixel devices (pixel, pixel xl, pixel 2, pixel 2 xl) running Pie

EDIT: We do have the foreground permission in our manifest

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
like image 513
Psest328 Avatar asked Oct 26 '18 19:10

Psest328


People also ask

What is startForeground in Android?

A started service can use the startForeground(int, android. app. Notification) API to put the service in a foreground state, where the system considers it to be something the user is actively aware of and thus not a candidate for killing when low on memory.

What is the difference between startService and startForegroundService?

NO MORE STARTSERVICE - The new context. startForegroundService() method starts a foreground service but with a implicit contract that service will call start foreground within 5 second of its creation. You can also call startService and startForegroundService for different OS version.

When should the startForeground function be called?

From Google's docs on Android 8.0 behavior changes: The system allows apps to call Context. startForegroundService() even while the app is in the background. However, the app must call that service's startForeground() method within five seconds after the service is created.

How do you stop foreground service?

User can dismiss notification by default Starting in Android 13 (API level 33), users can dismiss the notification associated with a foreground service by default. To do so, users perform a swipe gesture on the notification.


2 Answers

As mentioned here Background Service Limitations, the app/service has five seconds to call startForeground(), If the app does not call startForeground() within the time limit, the system stops the service and declares the app to be ANR.

There are some possibilities:

  1. Either your foreground service gets destroyed/finished before calling the startForeground() method.
  2. Or if the foreground service is already instantiated and its getting called again, then the onCreate method will not be called, instead onStartCommand will be called. Then move your logic to onStartCommand to call startForeground() method.
  3. Your notification id in startForeground must not be 0, otherwise it will also cause the crash.
like image 59
Arshad Mehmood Avatar answered Sep 20 '22 13:09

Arshad Mehmood


Has something changed in foreground services in Pie that I'm missing?

YES Have a look here migration notes of Android 9 / Pie

Change

Foreground service permission

Summary

Apps wanting to use foreground services must now request the FOREGROUND_SERVICE permission first. This is a normal permission, so the system automatically grants it to the requesting app. Starting a foreground service without the permission throws a SecurityException.

UPDATE

related issue in Google Issue Tracker Context.startForegroundService() did not then call Service.startForeground

like image 42
AskNilesh Avatar answered Sep 21 '22 13:09

AskNilesh