如何正确申请SYSTEM_ALERT_WINDOW的权限

1.在清单中声明权限

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

这一步至关重要

2.判定是否拥有权限

//检查是否已经授予权限
if (!Settings.canDrawOverlays(this)) {
    //若未授权则请求权限
} 

其中,Settings.canDrawOverlays(this)方法是在API level 23也就是Android M中新加入的用于检查当前是否拥有出现在“出现在其他应用上”权限的方法。

在6.0以前的系统版本,悬浮窗权限是默认开启的,直接使用即可
而面向于6.0以后,如果没有处理权限相关的操作,可能会导致IDE报错:

Unable to add window android.view.ViewRootImpl$W@1a8910d – the specified window type 0 is not valid

有关canDrawOverlays(),详参:
public static boolean canDrawOverlays (Context context)

3.申请权限(6.0以上版本)

//请求悬浮窗权限
@TargetApi(Build.VERSION_CODES.M)
private void getOverlayPermission() {
    Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
    intent.setData(Uri.parse("package:" + getPackageName()));
    startActivityForResult(intent, 0);
}

上述代码,使用隐式intent启动ACTION_MANAGE_OVERLAY_PERMISSION,其中携带着应用的包名信息,这样会跳转到一个悬浮窗权限申请界面,具体界面样式依系统而定。

实际上,在上述对于canDrawOverlays()介绍的官方文档中,也明确说明了申请权限的方法:

As of API level 23, an app cannot draw on top of other apps unless it declares the Manifest.permission.SYSTEM_ALERT_WINDOW permission in its manifest, and the user specifically grants the app this capability. To prompt the user to grant this approval, the app must send an intent with the action ACTION_MANAGE_OVERLAY_PERMISSION, which causes the system to display a permission management screen.

有关ACTION_MANAGE_OVERLAY_PERMISSION,详参:
public static final String ACTION_MANAGE_OVERLAY_PERMISSION

4.还应注意的细节问题

写好了上面的部分,却发现同样的代码在7.1上能跑起来,在8.1上直接崩溃,经排查发现,一些常用的LayoutParams属性,在API 27上已经处于废除状态,删除或替换这些属性即可。
FLAG_SHOW_WHEN_LOCKED
TYPE_SYSTEM_ERROR
在此不再赘述,如果您有相关问题,可以排查LayoutParams属性
有关LayoutParams,详参:
public static class WindowManager.LayoutParams

5.闲话

从历代Android版本对于悬浮窗权限的改动,可以看出Google对于Android的开放与安全之间的权衡,昨日听说回来的脚步近了,这也许是返乡,又也许是起航。

猜你喜欢

转载自blog.csdn.net/bestcxcxj/article/details/81385288