Context.startForegroundService() did not then call Service.startForeground()

匿名 (未验证) 提交于 2019-12-03 02:05:01

问题:

I am using Service Class on the Android O OS.

I plan to use the Service in the background.

The Android recommendation states that startService should use startForegroundService.

If you use startForegroundService, the Service throws a Context.startForegroundService() did not then call Service.startForeground() error.

What's wrong with this?

回答1:

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.

Solution: Call startForeground in Oncreate() for the Service which you use Context.startForegroundService().

See also: Background Execution Limits for Android 8.0 (Oreo)



回答2:

I called ContextCompat.startForegroundService(this, intent) to start the service then

In service onCreate

 @Override  public void onCreate() {         super.onCreate();          if (Build.VERSION.SDK_INT >= 26) {             String CHANNEL_ID = "my_channel_01";             NotificationChannel channel = new NotificationChannel(CHANNEL_ID,                     "Channel human readable title",                     NotificationManager.IMPORTANCE_DEFAULT);              ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(channel);              Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)                     .setContentTitle("")                     .setContentText("").build();              startForeground(1, notification);         } } 


回答3:

https://developer.android.com/reference/android/content/Context.html#startForegroundService(android.content.Intent)

Similar to startService(Intent), but with an implicit promise that the Service will call startForeground(int, android.app.Notification) once it begins running. The service is given an amount of time comparable to the ANR interval to do this, otherwise the system will automatically stop the service and declare the app ANR.

Unlike the ordinary startService(Intent), this method can be used at any time, regardless of whether the app hosting the service is in a foreground state.

make sure you call the Service.startForeground(int, android.app.Notification) on the onCreate() so you ensure it will be called..if you have any condition that may prevent you from doing that, then you'd better off using the normal Context.startService(Intent) and call the Service.startForeground(int, android.app.Notification) yourself.

It seems that the Context.startForegroundService() adds a watchdog to make sure you called the Service.startForeground(int, android.app.Notification) before it was destroyed...



回答4:

Make sure that all code paths calls startForeground method , for example the code may generate an exception on the onCreate Method of your service that prevent the startForeground from being called

   @Override     public void onCreate() { try{ } catch(Exception e) { } finally{     startForeground(1, notificationbuilder.build());  }     } 


回答5:

You app will crash if you call Context.startForegroundService(...) and then call Context.stopService(...) before Service.startForeground(...) is called.

I have a clear repro at: https://github.com/paulpv/ForegroundServiceAPI26/blob/repro/app/src/main/java/com/github/paulpv/foregroundserviceapi26/MainService.kt#L28

I have opened a bug on this: https://issuetracker.google.com/issues/76112072

Several bugs on this have been opened and closed Won't Fix.

Hopefully mine with clear repro steps.



回答6:

I have researched on this for a couple of days and got the solution. Now in Android O you can set the background limitation as below

The service which is calling a service class

Intent serviceIntent = new Intent(SettingActivity.this,DetectedService.class);                     if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O){                          SettingActivity.this.startForegroundService(serviceIntent);                     }else{                         startService(serviceIntent);                     } 

and the service class should be like

public class DetectedService extends Service {      @Override     public IBinder onBind(Intent intent) {         return null;     }      @Override     public int onStartCommand(Intent intent, int flags, int startId) {         return START_STICKY;     }      @Override     public void onCreate() {         super.onCreate();         int NOTIFICATION_ID = (int) (System.currentTimeMillis()%10000);          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {             startForeground(NOTIFICATION_ID, new Notification.Builder(this).build());         }           // Do whatever you want to do here     } } 


回答7:

I am facing same issue and after spending time found a solutons you can try below code. If your using Service then put this code in onCreate else your using Intent Service then put this code in onHandleIntent.

if (Build.VERSION.SDK_INT >= 26) {         String CHANNEL_ID = "my_app";         NotificationChannel channel = new NotificationChannel(CHANNEL_ID,                 "MyApp", NotificationManager.IMPORTANCE_DEFAULT);         ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(channel);         Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)                 .setContentTitle("")                 .setContentText("").build();         startForeground(1, notification);     } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!