Android不同系统版本的悬浮窗权限问题

Android悬浮窗权限问题

一、悬浮窗适配的两种方法:

1、按照正规的流程,如果系统没有赋予 APP 弹出悬浮窗的权限,就先跳转到权限授权界面,等用户打开该权限之后,再去弹出悬浮窗,比如 QQ 等一些主流应用就是这么做得;
2、利用系统的漏洞,绕过权限的申请,简单粗暴;不建议使用,因为兼容性有待商榷。
3、大脑模糊区域:悬浮窗与对话框权限是不同的,是不一样的。

二、不同系统版本之间的差异(以正规流程申请权限)

1、API 19之前:
  • 直接调用 WindowManager 的 addView 方法弹出即可。
  • 由于判断权限的类 AppOpsManager 是 API19 版本添加,所以Android 4.4 之前的版本(不包括4.4)就不用去判断了。
2、Android 4.4 ~ Android 5.1.1:(需要引导用户手动打开申请权限)
  • 由于碎片化程度比较大,所以需要针对特定机型进行适配
  • 主要问题在于,如何检测出不同产商的ROM,不同产商的ROM如何引导用户手动打开申请权限,可参考博客(http://blog.csdn.net/self_study/article/details/52859790)
  • 各ROM版本,通用检查悬浮窗权限方法
//OP_SYSTEM_ALERT_WINDOW = 24;

@TargetApi(Build.VERSION_CODES.KITKAT)
private static boolean checkOp(Context context, int op) {
    final int version = Build.VERSION.SDK_INT;
    if (version >= 19) {
        AppOpsManager manager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
        try {
            Class clazz = AppOpsManager.class;
            Method method = clazz.getDeclaredMethod("checkOp", int.class, int.class, String.class);
            return AppOpsManager.MODE_ALLOWED == (int) method.invoke(manager, op, Binder.getCallingUid(), context.getPackageName());
        } catch (Exception e) {
            Log.e(TAG, Log.getStackTraceString(e));
        }
    } else {
        Log.e(TAG, "Below API 19 cannot invoke!");
    }
    return false;
}
3、Android 6.0:
  • 悬浮窗权限在 6.0 之后就被 google 单独拿出来管理了,因此在所有手机和 6.0 以及之后的版本上适配的方法都是一样的
  • 在 AndroidManifest.xml中静态申请
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
  • 在使用时先判断该权限是否已经被授权,如果没有授权使用下面这段代码进行动态申请:
// 检查是否已经申请了 权限
if (Build.VERSION.SDK_INT >= 23) {
    try {
        Class clazz = Settings.class;
        Method canDrawOverlays = clazz.getDeclaredMethod("canDrawOverlays", Context.class);
        result = (Boolean) canDrawOverlays.invoke(null, context);
    } catch (Exception e) {
        Log.e(TAG, Log.getStackTraceString(e));
    }
}

// 跳转到设置页面,引导用户手动打开申请权限
try {
    Class clazz = Settings.class;
    Field field = clazz.getDeclaredField("ACTION_MANAGE_OVERLAY_PERMISSION");

    Intent intent = new Intent(field.get(null).toString());
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.setData(Uri.parse("package:" + context.getPackageName()));
    context.startActivity(intent);
} catch (Exception e) {
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值