in gradle:
compileSdkVersion 31
buildToolsVersion "31.0.0"
targetSdkVersion 31
in manifest:
<service android:name=".MyForegroundService"
android:exported="false"/>
<service android:name=".MyService"
android:exported="false"/>
<receiver android:name=".MyBroadcastReceiver"
android:exported="true">
<intent-filter>
<action android:name="com.sdk12.foreground.ACTION"/>
</intent-filter>
</receiver>
Receiver:
class MyBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
Log.d("tag", "onReceive()");
val myServiceIntent = Intent(context, MyForegroundService::class.java)
Handler(Looper.getMainLooper()).postDelayed({
try {
ContextCompat.startForegroundService(context,myServiceIntent)
} catch (ex : ForegroundServiceStartNotAllowedException){
Log.d("tag","ForegroundServiceStartNotAllowedException")
}
}, 5000)
}
}
foreground service:
class MyForegroundService : Service() {
private lateinit var br: BroadcastReceiver
override fun onBind(intent: Intent): IBinder? {
return null
}
override fun onCreate() {
super.onCreate()
br = MyBroadcastReceiver()
val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION).apply {
addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED)
}
registerReceiver(br, filter)
}
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
val channelId = createNotificationChannel("channel1","My Background Service")
val pendingIntent: PendingIntent =
Intent(this, MainActivity::class.java).let { notificationIntent ->
PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_MUTABLE)
}
val notificationBuilder = Notification.Builder(this, channelId )
val notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("title")
.setContentText("contentText")
.setCategory(Notification.CATEGORY_SERVICE)
.setContentIntent(pendingIntent)
.setForegroundServiceBehavior(Notification.FOREGROUND_SERVICE_IMMEDIATE)
.build()
startForeground(1, notification)
return START_STICKY
}
override fun onDestroy() {
unregisterReceiver(br)
super.onDestroy()
}
private fun createNotificationChannel(channelId: String, channelName: String): String {
val chan = NotificationChannel(
"channel1",
channelName, NotificationManager.IMPORTANCE_NONE
)
chan.lightColor = Color.BLUE
chan.lockscreenVisibility = Notification.VISIBILITY_PRIVATE
chan.importance = NotificationManager.IMPORTANCE_HIGH
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(chan)
return channelId
}
}
My Service:
class MyService : Service() {
private lateinit var br: BroadcastReceiver
override fun onBind(intent: Intent): IBinder? {
return null
}
override fun onCreate() {
super.onCreate()
br = MyBroadcastReceiver()
val filter = IntentFilter("com.sdk12.foreground.ACTION")
registerReceiver(br, filter)
}
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
return START_STICKY
}
override fun onDestroy() {
unregisterReceiver(br)
super.onDestroy()
}
}
trigger service:
startService(Intent(this, MyService::class.java))
send your app to background and call from adb:
adb shell am broadcast -a com.sdk12.foreground.ACTION -f 0x01000000
this will make sure you are in background
probably there are easier ways, but I find this most understandable