Android 各版本查询和开启悬浮窗权限
如果你是从事Android开发的程序员,那么你肯定对于权限这个词不会陌生,Android的权限分为一般权限和危险权限,一般权限(只需在AndroidManifest.xml文件中声明即可),危险权限(需要手动申请),接下来进入正题。
悬浮窗权限
悬浮窗权限不同于其他的权限如相机、相册、文件读写权限等,这些权限,动态申请后,用户只要的应用里面弹出来的提示框里面开启就可以了,并不会离开应用,而开启悬浮窗权限用户则需要进入到应用列表或者是应用详情里面开启悬浮窗权限。
业务逻辑:
APP默认是没有开启这个悬浮窗权限的,所以需要申请,而申请之后又要先判断有没有开启这个权限,这个判断是很重要的,你总不能每次都让用户去应用列表看这个权限有没有开启吧。
判断也是要分Android的版本的,如Android6.0、Android6.0至Android8.0、Android8.0以上,更低的版本就不考虑了,(你不要和我说你现在还用着Android4.4或者Android5.0,那你就是一个狠人,我惹不起),我的手机是9.0,亲测有效,判断的代码如下
在AndroidManifest.xml文件添加以下两个权限
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" />
权限检查
//判断是否开启悬浮窗权限 context可以用你的Activity.或者tiis public static boolean checkFloatPermission(Context context) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return true; if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { try { Class cls = Class.forName("android.content.Context"); Field declaredField = cls.getDeclaredField("APP_OPS_SERVICE"); declaredField.setAccessible(true); Object obj = declaredField.get(cls); if (!(obj instanceof String)) { return false; } String str2 = (String) obj; obj = cls.getMethod("getSystemService", String.class).invoke(context, str2); cls = Class.forName("android.app.AppOpsManager"); Field declaredField2 = cls.getDeclaredField("MODE_ALLOWED"); declaredField2.setAccessible(true); Method checkOp = cls.getMethod("checkOp", Integer.TYPE, Integer.TYPE, String.class); int result = (Integer) checkOp.invoke(obj, 24, Binder.getCallingUid(), context.getPackageName()); return result == declaredField2.getInt(cls); } catch (Exception e) { return false; } } else { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { AppOpsManager appOpsMgr = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); if (appOpsMgr == null) return false; int mode = appOpsMgr.checkOpNoThrow("android:system_alert_window", android.os.Process.myUid(), context .getPackageName()); return mode == AppOpsManager.MODE_ALLOWED || mode == AppOpsManager.MODE_IGNORED; } else { return Settings.canDrawOverlays(context); } } }
简单粗暴,在需要的地方使用即可,一般来说是放在onCreate()方法里面,如下所示:
if(!checkFloatPermission(context)){ //权限请求方法 requestSettingCanDrawOverlays(); }
权限请求方法
//权限打开 private void requestSettingCanDrawOverlays() { int sdkInt = Build.VERSION.SDK_INT; if (sdkInt >= Build.VERSION_CODES.O) {//8.0以上 Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION); startActivityForResult(intent, REQUEST_DIALOG_PERMISSION); } else if (sdkInt >= Build.VERSION_CODES.M) {//6.0-8.0 Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION); intent.setData(Uri.parse("package:" + getPackageName())); startActivityForResult(intent, REQUEST_DIALOG_PERMISSION); } else {//4.4-6.0以下 //无需处理了 } }
简单粗暴,写完收工