Android各版本查詢和開啓懸浮窗權限

Android 各版本查詢和開啓懸浮窗權限

如果你是從事Android開發的程序員,那麼你肯定對於權限這個詞不會陌生,Android的權限分爲一般權限和危險權限,一般權限(只需在AndroidManifest.xml文件中聲明即可),危險權限(需要手動申請),接下來進入正題。

懸浮窗權限

懸浮窗權限不同於其他的權限如相機、相冊、文件讀寫權限等,這些權限,動態申請後,用戶只要的應用裏面彈出來的提示框裏面開啓就可以了,並不會離開應用,而開啓懸浮窗權限用戶則需要進入到應用列表或者是應用詳情裏面開啓懸浮窗權限。
業務邏輯:
APP默認是沒有開啓這個懸浮窗權限的,所以需要申請,而申請之後又要先判斷有沒有開啓這個權限,這個判斷是很重要的,你總不能每次都讓用戶去應用列表看這個權限有沒有開啓吧。
判斷也是要分Android的版本的,如Android6.0Android6.0至Android8.0Android8.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以下
            //無需處理了
        }
    }

簡單粗暴,寫完收工

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章