Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
453 views
in Technique[技术] by (71.8m points)

location - Android O - Old start foreground service still working?

So, with Android O, you need to have your service running as a foreground service if you want to receive more than just a few location updates per hour.

I noticed that the old method for starting a foreground service does seem to work on O. i.e.

startForeground(NOTIFICATION_ID, getNotification());

According to the behaviour changes guide here: https://developer.android.com/preview/behavior-changes.html

The NotificationManager.startServiceInForeground() method starts a foreground service. The old way to start a foreground service no longer works.

Though the new method only works when targeting O, it seems that the old method still seems to work on an O device whether targeting O or not.

Edit Including example:

The Google sample project LocationUpdatesForegroundService actually has a working example where you can see the issue first hand. https://github.com/googlesamples/android-play-location/tree/master/LocationUpdatesForegroundService

The startForeground method seems to work without issue whether targeting and compiling against API level 25 OR targeting and compiling against O (as directed to here: https://developer.android.com/preview/migration.html#uya)

So, to reproduce:

  1. Configure the app gradle as mentioned in the previous link
  2. Open the app
  3. Request location updates
  4. Close app (either via back button or home button)

Service is running in foreground (shown by icon in notification shade). Location updates are coming through as expected (every 10 seconds) even on a device running O. What I am missing here?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This worked for me.

  1. In Activity class, start service using startForegroundService() instead of startService()
    Intent myService = new Intent(this, MyService.class);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        startForegroundService(myService);
    } else {
        startService(myService);
    }
  1. Now in Service class in onStartCommand() do as following
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    ......
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

        Notification.Builder builder = new Notification.Builder(this, ANDROID_CHANNEL_ID)
                .setContentTitle(getString(R.string.app_name))
                .setContentText(text)
                .setAutoCancel(true);

        Notification notification = builder.build();
        startForeground(1, notification);

    } else {

        NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
                .setContentTitle(getString(R.string.app_name))
                .setContentText(text)
                .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                .setAutoCancel(true);

        Notification notification = builder.build();

        startForeground(1, notification);
    }
    return START_NOT_STICKY;
}

Note: Using Notification.Builder instead of NotificationCompat.Builder made it work. Only in Notification.Builder you will need to provide Channel ID which is new feature in Android Oreo.

Hope it works!

EDIT:

If you target API level 28 or higher, you need FOREGROUND_SERVICE permission otherwise, your app will crash.

Just add this to the AndroidManifest.xml file.

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...