Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android6.0權限申請源碼解析及其注意事項

Android6.0權限申請源碼解析及其注意事項

編輯:關於Android編程

一、概述

隨著android版本的不斷升級,現在開發App肯定都是需要適配6.0及其以上的版本了,Google對手機安全的越來越重視,我們開發者所要應對的主要就是新版本SDK帶來的一些變化,首先關注的就是權限機制的變化。關於權限機制的變化網上的內容很多參考android6.0運行權限處理本篇文章主要根據源碼來分析申請權限時一些注意的事項。

二、權限申請流程

1、Activity.checkSelfPermission(String permission)
2、Activity.requestPermissions(@NonNull String[] permissions, int requestCode)
3、Activity.shouldShowRequestPermissionRationale(@NonNull String permission)
4、Activity.onRequestPermissionsResult(int requestCode, @NonNull String[] permissions@NonNull int[] grantResults)

第一個方法是解析你當前需要申請的權限是否是被通過的,如果是允許的就返回 PERMISSION_GRANTED,第二個方法是請求權限,第三個方法是判斷當前的權限狀態是否是已經被拒過一次了,它在你第一次拒絕請求權限之後永遠拒絕權限之前這段時間內全部返回true,所以當用戶第一次拒絕權限之後再次請求時給用戶提示為什麼app需要這個權限、打消用戶的顧慮。第四個方法就不多說了,返回的是請求的結果。

本文主要分析的是requestPermissions這個 函數及其一些注意事項!

  */
    public final void requestPermissions(@NonNull String[] permissions, int requestCode) {
        if (mHasCurrentPermissionsRequest) {
            Log.w(TAG, "Can reqeust only one set of permissions at a time");
            // Dispatch the callback with empty arrays which means a cancellation.
            onRequestPermissionsResult(requestCode, new String[0], new int[0]);
            return;
        }
        Intent intent = getPackageManager().buildRequestPermissionsIntent(permissions);
        startActivityForResult(REQUEST_PERMISSIONS_WHO_PREFIX, intent, requestCode, null);
        mHasCurrentPermissionsRequest = true;
    }

這是android7.0的源碼裡面的。mHasCurrentPermissionsRequest這個是一個布爾值的flag,標記當前是否有正在請求的權限。因為方法是異步執行的,所以如果你在申請權限的時候連續兩次執行此方法,你會在方法第二次請求的時候他會直接執行onRequestPermissionsResult方法,返回的 permissions和grantResults都是長度為0的空數組,這是如果你在onRequestPermissionsResult不判斷長度直接取值會奔潰報數組越位,所以大家在返回結果處理的時候最好做一下長度不為0的判斷,最好不要在上次請求結果沒有返回的時候就再次執行新的權限請求,因為這樣是沒有意義的!

    private void dispatchRequestPermissionsResult(int requestCode, Intent data) {
        mHasCurrentPermissionsRequest = false;
        // If the package installer crashed we may have not data - best effort.
        String[] permissions = (data != null) ? data.getStringArrayExtra(
                PackageManager.EXTRA_REQUEST_PERMISSIONS_NAMES) : new String[0];
        final int[] grantResults = (data != null) ? data.getIntArrayExtra(
                PackageManager.EXTRA_REQUEST_PERMISSIONS_RESULTS) : new int[0];
        onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

dispatchRequestPermissionsResult方法分發處理的結果,這時mHasCurrentPermissionsRequest重新置為false,表示當前沒有正在請求的權限!所以為了防止同時多次調用requestPermissions方法可以添加一個布爾值作判斷,實現代碼如下

    private isRequesting=false;
    //做請求的統一入口
    private void requestMyPermission(String[] permissions, int requestCode) {
        if (!isRequesting) {
            isRequesting = true;
            ActivityCompat.requestPermissions(this, permissions, requestCode);
        }

    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if(isRequesting&&permissions.length!=0){
            isRequesting=false;
            //do you want
        }
    }

這樣就能避免連續多次請求導致無效請求和處理出錯的情況!

還有一點的是對於Fragment內的權限請求,最好用v4包中的Fragment,因為android.app.Fragment內的requestPermissions方法

Added in API level 23
void requestPermissions (String[] permissions, int requestCode),需要api23及其之上才能使用的。而v4包中的requestPermissions方法沒有版本要求,end~

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