Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 談談Android 6.0 的動態權限管理

談談Android 6.0 的動態權限管理

編輯:關於Android編程

1.前言

大家都知道Android 6.0的新特性之一就是應用權限的管理。也就是說凡是涉及用戶隱私的權限,用戶可以自己去設置管理了。然而在6.0以前,我們安裝一款APP是默認同意此APP所需的所有權限(比如定位、訪問通訊錄),不同意就不能安裝。當然,國內的一些手機廠商基於Android定制的系統中,可以實現在6.0以前關閉指定的權限。如下圖:

這裡寫圖片描述

這裡寫圖片描述

2.危險權限列表(Dangerous Permission)

Dangerous Permission一般都是涉及用戶隱私的權限。

這裡寫圖片描述

從上面的圖片中可以看到,攝像頭、電話、定位等等都是我們平常開發中常用的權限。

3.可以在6.0不適配權限管理嗎?

答案是可以,但是不推薦。

首先說怎麼不適配,那就是設置targetSdkVersion小於23(Android 6.0系統默認為targetSdkVersion小於23的應用默認授予了所申請的所有權限,所以如果您APP設置的targetSdkVersion低於23,在運行時也不會崩潰。)

有人一看這不是挺好的嘛,解決問題。那麼我想告訴你,首先這不是長久之計,早晚都要面對的。你不可能永遠targetSdkVersion低於23。其次,它是有一個前提,那就是用戶自己不去操作權限。要知道如果用戶是6.0以上的手機,他可以自己在設置中關閉權限,那麼到時APP因為沒有權限獲取數據異常,導致空指針的異常時,APP就會崩潰。

4.怎麼適配

首先Android Studio

在build.gradle中聲明targetSdkVersion為23及以上。

Eclipse

在AndroidManifest.xml中聲明targetSdkVersion為23及以上。

這裡引用高德定位Demo的CheckPermissionsActivity類,代碼如下:

/**
 * 繼承了Activity,實現Android6.0的運行時權限檢測
 * 需要進行運行時權限檢測的Activity可以繼承這個類
 * 
 * @創建時間:2016年5月27日 下午3:01:31 
 * @項目名稱: AMapLocationDemo
 * @author hongming.wang
 * @文件名稱:PermissionsChecker.java
 * @類型名稱:PermissionsChecker
 * @since 2.5.0
 */
public class CheckPermissionsActivity extends Activity
        implements
            ActivityCompat.OnRequestPermissionsResultCallback {
    /**
     * 需要進行檢測的權限數組
     */
    protected String[] needPermissions = {
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.READ_PHONE_STATE
            };

    private static final int PERMISSON_REQUESTCODE = 0;

    /**
     * 判斷是否需要檢測,防止不停的彈框
     */
    private boolean isNeedCheck = true;

    @Override
    protected void onResume() {
        super.onResume();
        if(isNeedCheck){
            checkPermissions(needPermissions);
        }
    }

    /**
     * 
     * @param needRequestPermissonList
     * @since 2.5.0
     * requestPermissions方法是請求某一權限,
     */
    private void checkPermissions(String... permissions) {
        List needRequestPermissonList = findDeniedPermissions(permissions);
        if (null != needRequestPermissonList
                && needRequestPermissonList.size() > 0) {
            ActivityCompat.requestPermissions(this,
                    needRequestPermissonList.toArray(
                            new String[needRequestPermissonList.size()]),
                    PERMISSON_REQUESTCODE);
        }
    }

    /**
     * 獲取權限集中需要申請權限的列表
     * 
     * @param permissions
     * @return
     * @since 2.5.0
     * checkSelfPermission方法是在用來判斷是否app已經獲取到某一個權限
     * shouldShowRequestPermissionRationale方法用來判斷是否
     * 顯示申請權限對話框,如果同意了或者不在詢問則返回false
     */
    private List findDeniedPermissions(String[] permissions) {
        List needRequestPermissonList = new ArrayList();
        for (String perm : permissions) {
            if (ContextCompat.checkSelfPermission(this,
                    perm) != PackageManager.PERMISSION_GRANTED) {
                needRequestPermissonList.add(perm);
            } else {
                if (ActivityCompat.shouldShowRequestPermissionRationale(
                        this, perm)) {
                    needRequestPermissonList.add(perm);
                } 
            }
        }
        return needRequestPermissonList;
    }

    /**
     * 檢測是否所有的權限都已經授權
     * @param grantResults
     * @return
     * @since 2.5.0
     *
     */
    private boolean verifyPermissions(int[] grantResults) {
        for (int result : grantResults) {
            if (result != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }
        return true;
    }

    /**
    * 申請權限結果的回調方法
    */
    @Override
    public void onRequestPermissionsResult(int requestCode,
            String[] permissions, int[] paramArrayOfInt) {
        if (requestCode == PERMISSON_REQUESTCODE) {
            if (!verifyPermissions(paramArrayOfInt)) {
                showMissingPermissionDialog();
                isNeedCheck = false;
            }
        }
    }

    /**
     * 顯示提示信息
     * 
     * @since 2.5.0
     *
     */
    private void showMissingPermissionDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("提示");
        builder.setMessage("當前應用缺少必要權限。請點擊\"設置\"-\"權限\"-打開所需權限。");

        // 拒絕, 退出應用
        builder.setNegativeButton("取消",
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        finish();
                    }
                });

        builder.setPositiveButton("設置",
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        startAppSettings();
                    }
                });

        builder.setCancelable(false);

        builder.show();
    }

    /**
     *  啟動應用的設置
     * 
     * @since 2.5.0
     *
     */
    private void startAppSettings() {
        Intent intent = new Intent(
                Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        intent.setData(Uri.parse("package:" + getPackageName()));
        startActivity(intent);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if(keyCode == KeyEvent.KEYCODE_BACK){
            this.finish();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

}

我在上面的類中,自己加入了一些注釋,大家仔細看就可以明白了。

當然不止上面一種實現方法,github上有許多大神開源的封裝庫,可以很方便的實現權限適配。我推薦兩個庫,大家根據需求選擇:

1. PermissionsDispatcher

2. 鴻洋大神的MPermissions

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved