在Android 8.0以後(VERSION_CODES.O),背景服務的執行已經越管越嚴,如果將APP畫面收起,有極大機率我們在背景開啟的Service會被系統殺掉!
所以在Android 8.0之後,會使用startForegroundService的方式,將Service以前景的方式啟動,來達到常駐的效果~
1.首先在AndroidManifest.xml增加前景服務的權限。
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
2.在Service的程式中,增加一個通知訊息。
需要在onCreate時建立,注意:這邊要判斷作業系統版本,除非你的專案最低系統需求已經設為Android 8.0以上就不用判斷。
override fun onCreate() {
super.onCreate()
EventBus.getDefault().register(this)
//首次進入執行
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { //Android 8.0以上要設定前景通知才能背景執行
//初始化通知
val mNotificationManager = getSystemService(NotificationManager::class.java)
val mChannel = NotificationChannel("01", "位置服務", NotificationManager.IMPORTANCE_MIN)
mChannel.enableVibration(false) //是否開啟震動
mChannel.enableLights(false) //是否開啟燈號閃爍
mNotificationManager.createNotificationChannel(mChannel)
val notification = NotificationCompat.Builder(this, "01")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("藍牙服務")
.setContentText("背景服務執行中")
.setSmallIcon(R.mipmap.ic_launcher)
.setColor(getColor(R.color.black))
.build()
// 服務通知第一個Int參數ID不能為0
startForeground(1, notification)
}
LogUtil.e("NewBleService", "服務已建立")
}
3.使用startForegroundService啟動背景服務。
這邊一樣要判斷作業系統版本,除非你的專案最低系統需求已經設為Android 8.0以上就不用判斷。
val bleIntent = Intent(this, NewBleService::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { //Android 8.0以上要設定前景通知才能背景執行
startForegroundService(bleIntent)
}else{//相容舊版
startService(bleIntent)
}
啟動成功後,會有一條通知在通知欄:

這樣就可以在背景執行網路或藍牙連線的動作的,須注意的是,這樣子只是讓程式優先權往前面排,不代表永遠不會被殺掉,如果系統資源極低,還是會被砍的!
最後記得,不用的時候要把服務關掉節省系統資源:
//中止服務 val bleIntent = Intent(this, NewBleService::class.java) stopService(bleIntent)
-END-
發佈留言