Write your Android app to run in background mode as a service

In some use cases, you may encounter a problem when your users put your app in the background mode or screen lock state, then your app functionality would be lost after several minutes. This would not be a good user experience, which may cause a Bluetooth device disconnected from your app or data sync to server in the background got interrupted. Users would then complain about the connectivity and stability of your app.

To solve this problem, first, you need to understand a bit of the android app Activity lifecycle. When your user got distracted and open Facebook app in the foreground instead of your app, your app’s activity is finished and the onDestroy() would be triggered. This is good for the android system as it would free up unused memory as well as better battery management. However, this may not be good for your app since it got killed and your states and functionality are lost.

Next step, you need to refactor your app to separate the background functionality, such as Bluetooth connectivity, into a service. A Service is an application component that can perform long-running operations in the background, independent from the user interface. Here is an example of a service code:

import android.app.Service

class MyService : Service() {

override fun onBind(intent: Intent): IBinder? {
return null
}

override fun onCreate() {
// move your service logic here
}

override fun onDestroy() {
// clean up your service logic here
}

}

To use this service, you also need to define it in your AndroidManifest.xml, here is an example (replace the name with your service package name):

<application>
...
<service android:enabled="true" android:name="com.victorleungtw.myapp.services.MyService"></service>

</application>

One more thing, to trigger the start on this service in your activity, such as Activity onCreate, add this line:

startService(Intent(this, MyService::class.java))

Also at the place where you want to stop the service, add this line:

stopService(Intent(this, BleService::class.java))

After this change, your app is better structured, but it’s not yet able to keep running in background mode forever. To do so, inside your service, you also need to add two more methods:

class MyService : Service() {

@RequiresApi(Build.VERSION_CODES.O)
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {

val channelId =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createNotificationChannel("my_service", "My Background Service")
} else {
// If earlier version channel ID is not used
""
}

val notification: Notification = Notification.Builder(this, channelId)
.setContentTitle("title")
.setContentText("text")
.build()
startForeground(2001, notification)

return START_STICKY
}

@RequiresApi(Build.VERSION_CODES.O)
private fun createNotificationChannel(channelId: String, channelName: String): String{
val chan = NotificationChannel(channelId,
channelName, NotificationManager.IMPORTANCE_NONE)
chan.lightColor = Color.BLUE
chan.lockscreenVisibility = Notification.VISIBILITY_PRIVATE
val service = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
service.createNotificationChannel(chan)
return channelId
}

}

What is happening here is that a notification is created so that your user got notify when the app still keeps running in the background. It would look something like this:

That’s is. Now your user can multi-task, while reading Facebook app in the foreground, while keeping your app running in the background, connect with Bluetooth, sync user data or playing music etc depending on your app features.


Originally published at https://victorleungtw.com on September 12, 2020.

By Victor Leung

Experience in software development, consulting services and technical product management. Understanding of business and technology with an MBA in Finance and a Master degree in Computer Science. AWS Certified Solution Architect with experience in building products from scratch and serving as a charismatic leader.

Leave a comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.