My app currently uses a background service to communicate (Bluetooth) with a physical device. (I manufacture and sell the physical device.) The app sends a command to the device every 500ms. The user starts this process and it must run until the user stops it. While the app is active, results of the process are sent to the app. This process needs to run even if the app is not active. (i.e. they take a phone call, search the web.) Once the app becomes active again, the state of the process is synced with the app. The process can run anywhere from a few minutes to many hours. (Yes, the user would need to plug in if they want to run the process for 99hrs.) Most users run it for 2-15min. All is fine for now, but with API 26, it looks like this architecture is no longer allowed. One migration option is to move to a foreground service. However, I find the documentation to be unclear on how foreground services work. Does the foreground service continue to run with the app is not active? (i.e. it has gone through onPause.) If so, how is this any different than a background service? Is there better documentation on how the foreground service works. (My web searches have not turned up anything significant.) Alos, the API 26 documentation does not say if the app is bonded to the background service if the new limitations still apply. Do they?
Thanks, Stan
A Foreground Service is a Service that you put in the foreground state, that means, the system will not kill the process if it needs CPU or if your app is closed.
First you have 3 kinds of Services:
As said above, if you close your app, a Bound Service will be closed too, it is launched by bindService().
IntentService
s are a subtype of Service
which simplify a "work queue process" for incoming intents, i.e it handles incoming intents one by one within a queue, as said in the IntentService description. It has a default implementation and is launched by startService(). It is mainly for asynchronous tasks.
A Started Service is a Service started by a component, and continue to live until stopService() is called or your app is closed.
Using a Foreground Service makes your Service
persistent. You have to call startForeground() inside your service. It will still run until you stop your Service
, e.g with stopSelf() or stopService();
Note that onStartCommand() will be triggered each time you call startService() but onCreate()
is triggered only once.
Here is a simple implementation of a Foreground Started Service:
In your Manifest.xml:
<service android:name=".ConnectionService"
android:enabled="true"/>
In MyService.java:
public class MyService extends Service {
// Unique notification identifier
private final static int NOTIFICATION_ID = 95;
private NotificationManager mNotificationManager;
public MyService() { super(); }
@Override
public void onCreate() {
// Initialize notification
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
// Build your notification here
mBuilder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));
mBuilder.setSmallIcon(R.mipmap.ic_small_icon);
mBuilder.setContentTitle("MyService");
mBuilder.setContentText("The Service is currently running");
// Launch notification
startForeground(NOTIFICATION_ID, mBuilder.build());
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Handle startService() if you need to
// for exmple if you are passing data in your intent
return START_NOT_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
// We don't provide binding, so return null
return null;
}
@Override
public void onDestroy() {
super.onDestroy();
// Remove the notification when the service is stopped
mNotificationManager.cancel(NOTIFICATION_ID);
}
}
Finally just call startService().
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With