android 11 kotlin创建service
1. 启动服务, 判断下android版本调用不同的启动函数
// TestService: Service() 假设服务类叫TestService
fun startService(context: Context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(Intent(context, TestService::class.java))
} else {
context.startService(Intent(context, TestService::class.java))
}
}
不然可能会在使用startService时出现运行出错:
java.lang.IllegalStateException: Not allowed to start service Intent xxxx app is in background uid UidRecord
原因是安卓8开始无法创建后台服务,解决方法是使用startForegroundService创建前台服务。
2. 加权限,设置服务名
AndroidManifest.xml
加上
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application>
<service android:name=".TestService"/>
</application>
不然使用startForegroundService创建前台服务出错
java.lang.SecurityException: Permission Denial: startForeground from pid=25141, uid=10167 requires android.permission.FOREGROUND_SERVICE
3. 配置system权限
这步不细说了,加系统权限,就是用系统中的秘钥给apk签名
否则会出错
java.lang.RuntimeException: Unable to start service TestService@15e1549 with Intent { cmp=.TestService }: android.view.WindowManager
B
a
d
T
o
k
e
n
E
x
c
e
p
t
i
o
n
:
U
n
a
b
l
e
t
o
a
d
d
w
i
n
d
o
w
a
n
d
r
o
i
d
.
v
i
e
w
.
V
i
e
w
R
o
o
t
I
m
p
l
BadTokenException: Unable to add window android.view.ViewRootImpl
BadTokenException:Unabletoaddwindowandroid.view.ViewRootImplW@3e10f50 – permission denied for window type 2038
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:4433)
4. 在service中的onCreate中设置一个notification的channelId
private fun setForceGround() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// 在android8.0后, 无法创建后台服务,需要调用startForeground(id, notification)创建前台服务, 另需要给notification设置一个channel id
val channelId = "default"
val channel = NotificationChannel(channelId, channelId, NotificationManager.IMPORTANCE_DEFAULT)
val nm = getSystemService(Context.NOTIFICATION_SERVICE) as? NotificationManager
nm?.let {
if (it.getNotificationChannel(channelId) == null) {//没有创建
it.createNotificationChannel(channel)//则先创建
}
}
val notification: Notification
val builder = Notification.Builder(this, channelId)
.setContentTitle("")
.setContentText("")
notification = builder.build()
startForeground(1, notification)
}
}
不然会在运行5秒后崩溃掉:
android.app.RemoteServiceException: Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{49b053a u0
作者:帅得不敢出门