本来最近在开发一个app保活另外一个app的功能,方案介绍如下:
- 应用A 启动一个前台服务保活自己
- 应用A 用grpc连接应用B(服务端)是否存活
- 如果发现B不存活,则在服务中拉起B
这次没有做好调研,直接开始了开发工作,等grpc都调试开发完了,才发现 后台服务中启动应用B有时候能成功,有时候不能正常,不能成功报错如下:
Background activity start [callingPackage。。。。
问题原因就是 android10增加了后台启动activity的限制,当应用A在前台时,拉起应用B是可以的,担当应用A回到后台,即使有一个前台服务,也不能直接拉起应用B。
在网上查了很多资料,参考:Android 后台启动Activity适配
解决方案
我采用的是添加SYSTEM_ALERT_WINDOW权限,并申请该权限。
只需要申请权限,并不需要真的弹出一个悬浮窗出来。
- 在AndroidManifest.xml中添加
XML
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
- 申请权限
Kotlin
private val requestAlertWindowsPermission = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
Log.i(TAG, "result code:${result.resultCode}")
if (result.resultCode == Activity.RESULT_OK) {
Log.i(TAG, "data_return:${result.data?.getStringExtra("data_return")}")
}
if (!Settings.canDrawOverlays(this)) {
Log.i(TAG, "request alert windows Permission failed")
} else {
Log.i(TAG, "request alert windows Permission success")
}
}
private fun requestAlertWindowPermission() {
if (!Settings.canDrawOverlays(this)) {
Log.i(TAG, "requestAlertWinPerm: request alert windows Permission")
val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)
intent.setData(Uri.parse("package:$packageName"))
requestAlertWindowsPermission.launch(intent)
} else {
Log.i(TAG, "requestAlertWindowPermission already has Permission.")
}
}
- 服务中启动activity。别忘了添加 FLAG_ACTIVITY_NEW_TASK
Kotlin
val packageName = "pkg"
val launchIntent = packageManager.getLaunchIntentForPackage(packageName)
if (launchIntent == null) {
Log.e(TAG, "目标应用未安装")
throw RuntimeException("目标应用未安装")
}
launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(launchIntent)