Android 權限請求及權限設置頁面跳轉的工具類

在別人的基礎上修改了一點點陡厘。集中了常見的幾種權限請求和常見手機品牌的權限設置頁面跳轉扭粱。先記下來屈扎,以后用得上。
話不多說析蝴,上代碼

import android.Manifest;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;

import com.codepig.common.activity.BaseActivity;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;

/**
 * 權限處理類
 */
public class PermissionCompat {
    private final static String TAG = PermissionCompat.class.getSimpleName();
    private static PermissionCompat instance;

    //自己的項目包名
    private String packageName="com.myapp";

    /**
     * 檢測文件的權限
     */
    private static String[] PERMISSIONS_EXTERNAL_STORAGE = {
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
    };

    /**
     * 存儲
     */
    public final static int REQUEST_EXTERNAL_STORAGE = 99;

    /**
     * 檢測相機的
     */
    public static String[] PERMISSION_CAMERA = {
            Manifest.permission.CAMERA};

    /**
     * 相機請求
     */
    public final static int REQUEST_CAMERA = 98;//華為的requestCode不能大于128

    /**
     * 檢測錄音
     */
    public static String[] PERMISSION_RECODE = {
            Manifest.permission.RECORD_AUDIO};

    /**
     * 錄音請求
     */
    public final static int REQUEST_RECODE = 96;

    /**
     * 檢測圖片選擇的
     */
    public static String[] PERMISSION_GALLERY = {
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.CAMERA
    };

    public static String[] PERMISSION_FILE = {
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
    };

    /**
     * 相冊選擇
     */
    public final static int REQUEST_GALLERY = 97;

    /**
     * 檢測撥打電話權限
     */
    private static String[] PERMISSION_CALL_PHONE = {
            Manifest.permission.CALL_PHONE,
    };

    /**
     * 撥打電話請求
     */
    public final static int REQUEST_CALL_PHONE = 10096;

    /**
     * 設備狀態(tài)
     */
    public final static int REQUEST_PHONE_STATE = 100;

    private final static String[] PERMISSIONS_PHONE_STATE = {Manifest.permission.READ_PHONE_STATE};

    /**
     * 獲取手機通訊錄
     */
    private final static int REQUEST_READ_CONTACTS = 101;

    private final static String[] PERMISSIONS_READ_CONTACTS = {Manifest.permission.READ_CONTACTS};

    /**
     * 定位權限
     */
    private static String[] PERMISSION_LOCATION = {Manifest.permission.ACCESS_COARSE_LOCATION};

    /**
     * 分享相關權限
     */
    String[] ABOUT_SHARE = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.CALL_PHONE,Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_EXTERNAL_STORAGE};

    private PermissionCompat() {
        //
    }

    public static PermissionCompat getInstance() {
        if (instance == null) {
            synchronized (PermissionCompat.class) {
                if (instance == null) {
                    instance = new PermissionCompat();
                }
            }
        }
        return instance;
    }

    public boolean checkCameraPermission(Activity activity) {
        return checkPermission(activity, PERMISSION_CAMERA, REQUEST_CAMERA);
    }

    public boolean checkRecodePermission(Activity activity) {
        return checkPermission(activity, PERMISSION_RECODE, REQUEST_RECODE);
    }

    /**
     * 檢測文件讀寫
     */
    public boolean checkFilePermission(Activity activity) {
        return checkPermission(activity, PERMISSION_FILE, REQUEST_EXTERNAL_STORAGE);
    }

    /**
     * 檢測相冊
     */
    public boolean checkGalleryPermission(Activity activity) {
        return checkPermission(activity, PERMISSION_GALLERY, REQUEST_GALLERY);
    }

    /**
     * 檢測電話
     */
    public boolean checkCallPhonePermission(Activity activity) {
        return checkPermission(activity, PERMISSION_CALL_PHONE, REQUEST_CALL_PHONE);
    }

    /**
     * 檢測文件讀寫
     */
    public boolean checkStoragePermission(Activity activity) {
        return checkPermission(activity, PERMISSIONS_EXTERNAL_STORAGE, REQUEST_EXTERNAL_STORAGE);
    }

    /**
     * 檢測手機狀態(tài)權限
     * @param activity
     * @return
     */
    public boolean checkPhoneStatePermission(Activity activity) {
        return checkPermission(activity, PERMISSIONS_PHONE_STATE,REQUEST_PHONE_STATE);
    }

    /**
     * 檢查手機通訊錄權限
     * @param activity
     * @return
     */
    public boolean checkReadContactsPermission(Activity activity) {
        return checkPermission(activity, PERMISSIONS_READ_CONTACTS,REQUEST_READ_CONTACTS);
    }

    /**
     * 檢測定位
     */
    public boolean checkLocationPermission(Activity activity) {
        return checkPermission(activity, PERMISSION_LOCATION, REQUEST_LOCATION);
    }

    /**
     * 定位權限
     */
    public final static int REQUEST_LOCATION = 10097;

    /**
     * 定位權限
     */
    public final static int REQUEST_SOCIAL_SHARE = 10098;

    /**
     * 分享相關權限
     * @param activity
     * @return
     */
    public boolean checkAboutSharePermission(Activity activity) {
        return checkPermission(activity, ABOUT_SHARE, REQUEST_SOCIAL_SHARE);
    }

    /**
     * @param activity
     * @param permission   需要檢測的權限數組
     * @param request_code 請求的request code 自定義
     * @return
     */
    public boolean checkPermission(Activity activity, String[] permission, int request_code) {
        for (String str : permission) {
            int check = ContextCompat.checkSelfPermission(activity, str);
            boolean is_granted = (check == PackageManager.PERMISSION_GRANTED);
            if (!is_granted) { //
                BaseActivity baseActivity=(BaseActivity) activity;
                switch (request_code){
                    case REQUEST_RECODE:
                        baseActivity.showPermissionAlert("請在應用權限設置允許錄音");
                        break;
                    case REQUEST_CAMERA:
                        baseActivity.showPermissionAlert("請在應用權限設置允許使用攝像頭");
                        break;
                    case REQUEST_EXTERNAL_STORAGE:
                        baseActivity.showPermissionAlert("請在應用權限設置允許讀寫手機存儲");
                        break;
                    case REQUEST_CALL_PHONE:
                        baseActivity.showPermissionAlert("請在應用權限設置允許撥打電話");
                        break;
                    case REQUEST_GALLERY:
                        baseActivity.showPermissionAlert("請在應用權限設置允許訪問手機相冊及攝像頭");
                        break;
                }
                ActivityCompat.requestPermissions(
                        activity,
                        permission,
                        request_code
                );
                return false;
            }
        }
        return true;
    }


    /**
     * 跳轉至權限設置頁面
     * @param activity
     */
    public void goPermissionSet(Activity activity) {
        String name = Build.MANUFACTURER;
        switch (name) {
            case "HUAWEI":
                goHuaWeiManager(activity);
                break;
            case "vivo":
                goVivoManager(activity);
                break;
            case "OPPO":
                goOppoManager(activity);
                break;
            case "Coolpad":
                goCoolpadManager(activity);
                break;
            case "Meizu":
                goMeizuManager(activity);
                break;
            case "Xiaomi":
                goXiaoMiManager(activity);
                break;
            case "samsung":
                goSangXinManager(activity);
                break;
            case "Sony":
                goSonyManager(activity);
                break;
            case "LG":
                goLGManager(activity);
                break;
            default:
                goIntentSetting(activity);
                break;
        }
    }

    private void goLGManager(Activity activity){
        try {
            Intent intent = new Intent(packageName);
            ComponentName comp = new ComponentName("com.android.settings", "com.android.settings.Settings$AccessLockSummaryActivity");
            intent.setComponent(comp);
            activity.startActivity(intent);
        } catch (Exception e) {
            ToastUtil.showToast("跳轉失敗");
            e.printStackTrace();
            goIntentSetting(activity);
        }
    }
    private void goSonyManager(Activity activity){
        try {
            Intent intent = new Intent(packageName);
            ComponentName comp = new ComponentName("com.sonymobile.cta", "com.sonymobile.cta.SomcCTAMainActivity");
            intent.setComponent(comp);
            activity.startActivity(intent);
        } catch (Exception e) {
            ToastUtil.showToast("跳轉失敗");
            e.printStackTrace();
            goIntentSetting(activity);
        }
    }

    private void goHuaWeiManager(Activity activity) {
        try {
            Intent intent = new Intent(packageName);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            ComponentName comp = new ComponentName("com.huawei.systemmanager", "com.huawei.permissionmanager.ui.MainActivity");
            intent.setComponent(comp);
            activity.startActivity(intent);
        } catch (Exception e) {
            ToastUtil.showToast("跳轉失敗");
            e.printStackTrace();
            goIntentSetting(activity);
        }
    }

    private static String getMiuiVersion(Activity activity) {
        String propName = "ro.miui.ui.version.name";
        String line;
        BufferedReader input = null;
        try {
            Process p = Runtime.getRuntime().exec("getprop " + propName);
            input = new BufferedReader(
                    new InputStreamReader(p.getInputStream()), 1024);
            line = input.readLine();
            input.close();
        } catch (IOException ex) {
            ex.printStackTrace();
            return null;
        } finally {
            try {
                input.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return line;
    }

    private void goXiaoMiManager(Activity activity) {
        String rom = getMiuiVersion(activity);
        Intent intent=new Intent();
        if ("V6".equals(rom) || "V7".equals(rom)) {
            intent.setAction("miui.intent.action.APP_PERM_EDITOR");
            intent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.AppPermissionsEditorActivity");
            intent.putExtra("extra_pkgname", packageName);
        } else if ("V8".equals(rom) || "V9".equals(rom)) {
            intent.setAction("miui.intent.action.APP_PERM_EDITOR");
            intent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.PermissionsEditorActivity");
            intent.putExtra("extra_pkgname", packageName);
        } else {
            goIntentSetting(activity);
        }
    }

    private void goMeizuManager(Activity activity) {
        try {
            Intent intent = new Intent("com.meizu.safe.security.SHOW_APPSEC");
            intent.addCategory(Intent.CATEGORY_DEFAULT);
            intent.putExtra("packageName", packageName);
            activity.startActivity(intent);
        } catch (ActivityNotFoundException localActivityNotFoundException) {
            localActivityNotFoundException.printStackTrace();
            goIntentSetting(activity);
        }
    }

    private void goSangXinManager(Activity activity) {
        //三星4.3可以直接跳轉
        goIntentSetting(activity);
    }

    private void goIntentSetting(Activity activity) {
        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        Uri uri = Uri.fromParts("package", activity.getPackageName(), null);
        intent.setData(uri);
        try {
            activity.startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void goOppoManager(Activity activity) {
        doStartApplicationWithPackageName("com.coloros.safecenter",activity);
    }

    /**
     * doStartApplicationWithPackageName("com.yulong.android.security:remote")
     * 和Intent open = getPackageManager().getLaunchIntentForPackage("com.yulong.android.security:remote");
     * startActivity(open);
     */
    private void goCoolpadManager(Activity activity) {
        doStartApplicationWithPackageName("com.yulong.android.security:remote",activity);
      /*  Intent openQQ = getPackageManager().getLaunchIntentForPackage("com.yulong.android.security:remote");
        startActivity(openQQ);*/
    }

    private void goVivoManager(Activity activity) {
        doStartApplicationWithPackageName("com.bairenkeji.icaller",activity);
     /*   Intent openQQ = getPackageManager().getLaunchIntentForPackage("com.vivo.securedaemonservice");
        startActivity(openQQ);*/
    }

    private void doStartApplicationWithPackageName(String packagename,Activity activity) {
        // 通過包名獲取此APP詳細信息害捕,包括Activities、services闷畸、versioncode尝盼、name等等
        PackageInfo packageinfo = null;
        try {
            packageinfo = activity.getPackageManager().getPackageInfo(packagename, 0);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        if (packageinfo == null) {
            return;
        }
        // 創(chuàng)建一個類別為CATEGORY_LAUNCHER的該包名的Intent
        Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null);
        resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER);
        resolveIntent.setPackage(packageinfo.packageName);
        // 通過getPackageManager()的queryIntentActivities方法遍歷
        List<ResolveInfo> resolveinfoList = activity.getPackageManager()
                .queryIntentActivities(resolveIntent, 0);
        System.out.println("resolve info List" + resolveinfoList.size());
        for (int i = 0; i < resolveinfoList.size(); i++) {
            System.out.println("PermissionPageManager"+resolveinfoList.get(i).activityInfo.packageName + resolveinfoList.get(i).activityInfo.name);
        }
        ResolveInfo resolveinfo = resolveinfoList.iterator().next();
        if (resolveinfo != null) {
            // packageName參數2 = 參數 packname
            String packageName = resolveinfo.activityInfo.packageName;
            // 該APP的LAUNCHER的Activity[組織形式:packageName參數2.mainActivityName]
            String className = resolveinfo.activityInfo.name;
            // LAUNCHER Intent
            Intent intent = new Intent(Intent.ACTION_MAIN);
            intent.addCategory(Intent.CATEGORY_LAUNCHER);
            // 設置ComponentName參數1:packageName參數2:MainActivity路徑
            ComponentName cn = new ComponentName(packageName, className);
            intent.setComponent(cn);
            try {
                activity.startActivity(intent);
            } catch (Exception e) {
                goIntentSetting(activity);
                e.printStackTrace();
            }
        }
    }

}

使用:
判斷及權限申請

PermissionCompat.getInstance().checkRecodePermission((Activity) context)

申請結果回調

/**
     * 權限申請回調
     * @param requestCode
     * @param permissions
     * @param grantResults
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults){
        boolean _permission=true;
        switch (requestCode){
            case REQUEST_RECODE:
            case REQUEST_CAMERA:
            case REQUEST_EXTERNAL_STORAGE:
            case REQUEST_CALL_PHONE:
            case REQUEST_GALLERY:
                for(int i=0;i<grantResults.length;i++){
                    if(grantResults[i]!=0){
                        _permission=false;
                    }
                }
                if(_permission){
                    if(permissionAlertDialog.isShowing()) {
                        hidePermissionAlert();
                    }
                }
                break;
        }
    }

跳轉應用權限設置頁面

PermissionCompat.getInstance().goPermissionSet(this);

關于跳轉應用權限設置頁面,小米手機上有個很坑爹的問題佑菩。在開發(fā)者模式下盾沫。用以上代碼跳轉的頁面和從系統(tǒng)設置里進去的權限設置頁面其實不是同一個。這導致了跳轉后做的修改在系統(tǒng)設置的權限頁面看不到變化殿漠。
而且如果在開發(fā)者模式下的啟用MIUI優(yōu)化是關閉的赴精,那么系統(tǒng)的權限設置頁面將是無效的。


相關github地址:
https://github.com/codeqian/MVVMDemo/blob/master/common/src/main/java/com/codepig/common/util/PermissionCompat.java

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末凸舵,一起剝皮案震驚了整個濱河市祖娘,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌啊奄,老刑警劉巖渐苏,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異菇夸,居然都是意外死亡琼富,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進店門庄新,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鞠眉,“玉大人,你說我怎么就攤上這事择诈⌒堤#” “怎么了?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵羞芍,是天一觀的道長哗戈。 經常有香客問我,道長荷科,這世上最難降的妖魔是什么唯咬? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任纱注,我火速辦了婚禮,結果婚禮上胆胰,老公的妹妹穿的比我還像新娘狞贱。我一直安慰自己,他們只是感情好蜀涨,可當我...
    茶點故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布瞎嬉。 她就那樣靜靜地躺著,像睡著了一般勉盅。 火紅的嫁衣襯著肌膚如雪佑颇。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天草娜,我揣著相機與錄音,去河邊找鬼痒筒。 笑死宰闰,一個胖子當著我的面吹牛,可吹牛的內容都是我干的簿透。 我是一名探鬼主播移袍,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼老充!你這毒婦竟也來了葡盗?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤啡浊,失蹤者是張志新(化名)和其女友劉穎觅够,沒想到半個月后,有當地人在樹林里發(fā)現(xiàn)了一具尸體巷嚣,經...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡喘先,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了廷粒。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片窘拯。...
    茶點故事閱讀 39,688評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖坝茎,靈堂內的尸體忽然破棺而出涤姊,到底是詐尸還是另有隱情,我是刑警寧澤嗤放,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布思喊,位于F島的核電站,受9級特大地震影響斤吐,放射性物質發(fā)生泄漏搔涝。R本人自食惡果不足惜厨喂,卻給世界環(huán)境...
    茶點故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望庄呈。 院中可真熱鬧蜕煌,春花似錦、人聲如沸诬留。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽文兑。三九已至盒刚,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間绿贞,已是汗流浹背因块。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留籍铁,地道東北人涡上。 一個月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像拒名,于是被迫代替她去往敵國和親吩愧。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,573評論 2 353