这是我参与8月更文挑战的第16天,活动详情查看:8月更文挑战
背景
项目以前基于android7.0以下运行,静态监听系统的开机广播,然后拉起自己的activity。但是在Android 10 之后,发现方法失效了。
经过查阅资料发现:Android 10 (API 级别 29) 及更高版本对后台应用的启动做了限制。Android10中, 当App的Activity不在前台时,其启动Activity会被系统拦截,导致无法启动。
这里摘一些概要:
Android 10 (API 级别 29) 及更高版本对后台应用可启动 Activity 的时间施加限制。这些限制有助于最大限度地减少对用户造成的中断,并且可以让用户更好地控制其屏幕上显示的内容。
注意:为启动 Activity,系统仍会将运行前台服务的应用视为“后台”应用。
方案一
要解决这个问题有两个方案: 其一是使用NotificationManager + 全屏Intent,并添加权限:
//AndroidManifest中
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
Intent fullScreenIntent = new Intent(this, CallActivity.class);
PendingIntent fullScreenPendingIntent = PendingIntent.getActivity(this, 0,
fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("Incoming call")
.setContentText("(919) 555-1234")
//以下为关键的3行
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_CALL)
.setFullScreenIntent(fullScreenPendingIntent, true);
NotificationManager notifyManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notifyManager.notify(notifyId, builder.build());
方案二
方案二是动态注册广播,并增加ACTION_MANAGE_OVERLAY_PERMISSION
权限:
//AndroidManifest中
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
if (!Settings.canDrawOverlays(this)) {
//开机自启动权限
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, 0);
}
m_adbReceiver = new AdbBootBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.intent.action.BROADCAST_FORM_ADB");
registerReceiver(m_bootReceiver, intentFilter2);
其中,canDrawOverlays
方法是在Android M(23)新加入的用于检查当前是否拥有“出现在其他应用上”权限的方法。在6.0以前的系统版本,悬浮窗权限是默认开启的,直接使用即可。