android6.0權限管理工具EasyPermissionUtil


前言

android6.0開始,權限的申請發生了改變,申請變的動態化,也就是執行時權限,和iOS相仿,動態化的意思是指,在每次使用須要危急權限的方法的時候。須要檢查程序是否獲得了該權限的許可。動態化的權限申請能夠讓用戶更加清晰的知道程序須要什么權限。以及程序中哪些地方的操作須要涉及用戶安全。

不再是只在程序安裝的時候,一次性把所須要的普通的、危急級別的權限一次性列出來。然后展示給用戶。

當project項目的target Sdk為23時,因為考慮到用戶假設沒有進行權限的動態檢查,那么在執行到須要權限的代碼時,會發生crash。而當你的target Sdk為23下面時,則不強制要求權限的動態監測,此時app不會crash。還是能夠正常的使用功能。

Google官網上動態申請權限的方法分了在Activity和Fragment這兩種,通過ContextCompat以及子類,ActivityCompat和FragmentCompat去進行權限的申請和權限的檢查,而申請的方式是彈出一個系統的不能夠改寫的對話框。結果是通過Activity和Fragment的onRequestPermissionResult()方法進行返回。
詳細能夠參考官網

可是這樣的代碼會促使以前的project進行大改造或者說代碼的邏輯會耦合的寫在同一個方法里。顯的不方便和臃腫。

所以下面的EasyPermissionUtil就是簡化權限請求的方式,同一時候能夠使代碼的邏輯更加清晰。

EasyPermissionUtil:簡化權限請求

因為權限的請求和結果的返回須要分開Activity和Fragment兩種去進行操作,這樣會比較麻煩,所以EasyPermissionUtil中投機取巧,通過開啟一個新的activity進行權限申請和檢查的操作。這樣不用去區分多種情況,同一時候也能夠把全部的申請過程和結果統一由EasyPermissionUtil進行處理。
接下來看一下總體的思想:
這里寫圖片描寫敘述

使用的方法

PermissionUtil.getInstance().request(MainActivity.this, new String[]{Manifest.permission.READ_CALENDAR}, mRequestCode,
    new PermissionResultCallBack() {
        @Override
        public void onPermissionGranted() {
            // 當全部權限的申請被用戶允許之后,該方法會被調用
        }

        @Override
        public void onPermissionDenied(String... permissions) {
            // 當權限申請中的某一個或多個權限,被用戶以前否定了,並確認了不再提醒時,也就是權限的申請窗體不能再彈出時,該方法將會被調用
        }

        @Override
        public void onRationalShow(String... permissions) {
            // 當權限申請中的某一個或多個權限,被用戶否定了,但沒有確認不再提醒時,也就是權限窗體申請時,但被否定了之后,該方法將會被調用.
        }
    });

項目源代碼下載以及介紹。請看github。

項目源代碼

在PermissionUtil中,要做的是:
1.進行權限檢查
2.沒有得到權限許可的進行權限申請
3.返回權限申請的結果

public class PermissionUtil {

    private PermissionResultCallBack mPermissionResultCallBack;
    private volatile static PermissionUtil instance;
    private int mRequestCode;
    private Context mContext;
    private Fragment mFragment;
    private List<PermissionInfo> mPermissionListNeedReq;
    private String[] mPermissions;

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

    /** * 用於fragment中請求權限 * @param fragment * @param permissions * @param requestCode * @param callBack */
    public void request(@NonNull Fragment fragment,@NonNull String[] permissions,@NonNull int requestCode, PermissionResultCallBack callBack) {
        this.mFragment = fragment;
        this.request(fragment.getActivity(), permissions, requestCode, callBack);
    }

    /** * 用於activity中請求權限 * @param context * @param permissions * @param requestCode * @param callBack */
    public void request(@NonNull Context context,@NonNull String[] permissions,@NonNull int requestCode, PermissionResultCallBack callBack) {

        if (Looper.myLooper() != Looper.getMainLooper()) {
            throw new RuntimeException("request permission only can run in MainThread!");
        }

        if (permissions.length == 0) {
            return;
        }

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            onGranted();
            return;
        }

        this.mContext = context;
        this.mPermissions = permissions;
        this.mRequestCode = requestCode;
        this.mPermissionResultCallBack = callBack;
        this.mPermissionListNeedReq = new ArrayList<PermissionInfo>();

        if (needToRequest()) {
            requestPermissions();
        } else {
            onGranted();
        }
    }

    /** * 通過開啟一個新的activity作為申請權限的媒介 */
    private void requestPermissions() {

        Intent intent = new Intent(mContext, HelpActivity.class);
        intent.putExtra("permissions", mPermissions);
        intent.putExtra("requestCode", mRequestCode);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        mContext.startActivity(intent);
    }

    /** * 檢查是否須要申請權限 * @return */
    private boolean needToRequest() {
        for (String permission : mPermissions) {
            int checkRes = ContextCompat.checkSelfPermission(mContext, permission);
            if (checkRes != PackageManager.PERMISSION_GRANTED) {
                PermissionInfo info = new PermissionInfo(permission);
                if (mContext instanceof Activity &&
                        ActivityCompat.shouldShowRequestPermissionRationale((Activity) mContext, permission)) {
                    info.setRationalNeed(true);
                }
                mPermissionListNeedReq.add(info);
            }
        }

        if (mPermissionListNeedReq.size() > 0) {
            mPermissions = new String[mPermissionListNeedReq.size()];
            for (int i = 0; i < mPermissionListNeedReq.size(); i++) {
                mPermissions[i] = mPermissionListNeedReq.get(i).getName();
            }
            return true;
        }

        return false;
    }

    /** * 申請權限結果返回 * @param requestCode * @param permissions * @param grantResults */
    @TargetApi(Build.VERSION_CODES.M)
    protected void onRequestPermissionResult(int requestCode, String[] permissions, int[] grantResults) {

        if (requestCode == mRequestCode) {

            if (mContext != null && mContext instanceof Activity) {
                ((Activity) mContext).onRequestPermissionsResult(requestCode, permissions, grantResults);
            }

            if (mFragment != null) {
                mFragment.onRequestPermissionsResult(requestCode, permissions, grantResults);
            }

            boolean isAllGranted = true;
            List<PermissionInfo> needRationalPermissionList = new ArrayList<PermissionInfo>();
            List<PermissionInfo> deniedPermissionList = new ArrayList<PermissionInfo>();
            for (int i = 0; i < permissions.length; i++) {
                if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
                    if (mPermissionListNeedReq.get(i).isRationalNeed()) {
                        needRationalPermissionList.add(mPermissionListNeedReq.get(i));
                    } else {
                        deniedPermissionList.add(mPermissionListNeedReq.get(i));
                    }
                    isAllGranted = false;
                }
            }

            if (needRationalPermissionList.size() != 0) {
                showRational(needRationalPermissionList);
            }

            if (deniedPermissionList.size() != 0) {
                onDenied(deniedPermissionList);
            }

            if (isAllGranted) {
                onGranted();
            }

        }
    }

    /** * 權限被用戶許可之后回調的方法 */
    private void onGranted() {
        if (mPermissionResultCallBack != null) {
            mPermissionResultCallBack.onPermissionGranted();
        }
    }

    /** * 權限申請被用戶否定之后的回調方法,這個主要是當用戶點擊否定的同一時候點擊了不在彈出, * 那么當再次申請權限,此方法會被調用 * @param list */
    private void onDenied(List<PermissionInfo> list) {
        if(list == null || list.size() == 0) return;

        String[] permissions = new String[list.size()];
        for (int i = 0; i < list.size(); i++) {
            permissions[i] = list.get(i).getName();
        }

        if (mPermissionResultCallBack != null) {
            mPermissionResultCallBack.onPermissionDenied(permissions);
        }
    }

    /** * 權限申請被用戶否定后的回調方法,這個主要場景是當用戶點擊了否定,但未點擊不在彈出, * 那么當再次申請權限的時候,此方法會被調用 * @param list */
    private void showRational(List<PermissionInfo> list) {
        if(list == null || list.size() == 0) return;

        String[] permissions = new String[list.size()];
        for (int i = 0; i < list.size(); i++) {
            permissions[i] = list.get(i).getName();
        }

        if (mPermissionResultCallBack != null) {
            mPermissionResultCallBack.onRationalShow(permissions);
        }
    }

}

在PermissionResutCallBack中,要做的是:
1.返回相應的結果

public interface PermissionResultCallBack {

    /** * 當全部權限的申請被用戶允許之后,該方法會被調用 */
    void onPermissionGranted();

    /** * 當權限申請中的某一個或多個權限,被用戶以前否定了,並確認了不再提醒時,也就是權限的申請窗體不能再彈出時, * 該方法將會被調用 * @param permissions */
    void onPermissionDenied(String... permissions);

    /** * 當權限申請中的某一個或多個權限,被用戶否定了,但沒有確認不再提醒時,也就是權限窗體申請時,但被否定了之后, * 該方法將會被調用. * @param permissions */
    void onRationalShow(String... permissions);
}

在HelpActivity中。要做的就是:
1.申請權限
2.通過onRequestPermissionUtil返回結果給PermissionUtil
當然這個activity必須是透明的,並且是沒有不論什么的view的。這樣看起來才不像是開了一個新的activity。

public class HelpActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (savedInstanceState == null) {
            handleIntent(getIntent());
        }
    }

    @Override
    protected void onNewIntent(Intent intent) {
        handleIntent(intent);
    }

    // 權限申請
    @TargetApi(Build.VERSION_CODES.M)
    private void handleIntent(Intent intent) {
        String[] permissions = intent.getStringArrayExtra("permissions");
        int requestCode = intent.getIntExtra("requestCode", 42);
        ActivityCompat.requestPermissions(this, permissions, requestCode);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    // 返回結果
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        PermissionUtil.getInstance().onRequestPermissionResult(requestCode, permissions, grantResults);
        finish();
    }
}

項目源代碼下載以及介紹。請看github。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM