Android O 之后,为了更好的用户体验, Google 对后台启动activity 做了诸多限制, 详情请参考官网:
Android 10 中的隐私权变更 | Android 开发者 | Android Developers
这篇文章主要介绍 SYSTEM_ALERT_WINDOW 权限 对后台启动Activity的影响
涉及权限:
android.permission.SYSTEM_ALERT_WINDOW
<!-- Allows an app to create windows using the type
{@link android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY},
shown on top of all other apps. Very few apps
should use this permission; these windows are intended for
system-level interaction with the user.
<p class="note"><strong>Note:</strong> If the app
targets API level 23 or higher, the app user must explicitly grant
this permission to the app through a permission management screen. The app requests
the user's approval by sending an intent with action
{@link android.provider.Settings#ACTION_MANAGE_OVERLAY_PERMISSION}.
The app can check whether it has this authorization by calling
{@link android.provider.Settings#canDrawOverlays
Settings.canDrawOverlays()}.
<p>Protection level: signature|setup|appop|installer|pre23|development -->
<permission android:name="android.permission.SYSTEM_ALERT_WINDOW"
android:label="@string/permlab_systemAlertWindow"
android:description="@string/permdesc_systemAlertWindow"
android:protectionLevel="signature|setup|appop|installer|pre23|development" />
可以看到 除了由系统签名外,还可以通过android.provider.Settings#ACTION_MANAGE_OVERLAY_PERMISSION 拉起系统授权框,让用户授权
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + activity.getPackageName()));
activity.startActivityForResult(intent, ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE);
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE) {
if (!Settings.canDrawOverlays(this)) {
// You don't have permission
} else {
}
}
}
另外还可以让有系统签名的app 通过AppOpManager 给我们的应用授权
<!-- appop 操作 需要的权限 signature|installer|verifier-->
<uses-permission android:name="android.permission.MANAGE_APP_OPS_MODES" />
AppOpsManager mAppOps = (AppOpsManager) activity.getSystemService(Context.APP_OPS_SERVICE);
mAppOps.setMode(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, getAppUid(activity), activity.getPackageName(), AppOpsManager.MODE_ALLOWED);
言归正传,对后台启动Activity:
1.启动自己的activity
获取到SYSTEM_ALERT_WINDOW权限: 可以启动, 而且能覆盖在其他app界面之上
未获取到SYSTEM_ALERT_WINDOW权限: 可以启动, 但是不能覆盖在其他app界面之上
2.启动别的activity
获取到SYSTEM_ALERT_WINDOW权限: 可以启动, 而且能覆盖在其他app界面之上
未获取到SYSTEM_ALERT_WINDOW权限: 不可以启动