Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android6.0權限系統

Android6.0權限系統

編輯:關於Android編程

Android權限系統是一個非常重要的安全問題,因為它只有在安裝時會詢問一次。一旦軟件本安裝之後,應用程序可以在用戶毫不知情的情況下使用這些權限來獲取所有的內容。

很多壞蛋會通過這個安全缺陷來收集用戶的個人信息並使用它們來做壞事的情況就不足為奇了。

Android團隊也意識到了這個問題。在經過了7年後,權限系統終於被重新設置了。從Anroid 6.0(API Level 23)開始,應用程序在安裝時不會被授予任何權限,取而代之的是在運行時應用回去請求用戶授予對應的權限。這樣可以讓用戶能更好的去控制應用功能。例如,一個用戶可能會同一個拍照應用使用攝像頭的權限,但是不同授權它獲取設備位置的權限。用戶可以在任何時候通過去應用的設置頁面來撤銷授權。

imagevcDgo6w8Y29kZT5ub3JtYWw8L2NvZGU+us08Y29kZT5kYW5nZXJvdXM8L2NvZGU+OjwvcD4NCjxjb2RlPk5vcm1hbCBQZXJtaXNzaW9uczwvY29kZT6yu9Do0qrTw7un1rG908rayKijrMjnufvE47XE06bTw9Tax+W1pc7EvP7W0Mn5w/fBy05vcm1hbCBQZXJtaXNzaW9uc2CjrM+1zbO74dfUtq/K2siouMPIqM/eoaMgPGNvZGU+RGFuZ2Vyb3VzIFBlcm1pc3Npb25zPC9jb2RlPr/J0tTIw9Om08O78cih08O7p7XEy73Iy8r9vt2ho8jnufvE47XE06bTw9Tax+W1pc7EvP7W0Mnqx+vByzxjb2RlPkRhbmdlcm91cyBQZXJtaXNzaW9uczwvY29kZT6jrMTHvs2x2NDr0qrTw7unwLTK2siouPjTptPDoaMNCjxwPjxjb2RlPk5vcm1hbCBQZXJtaXNzaW9uczwvY29kZT46PGJyIC8+DQo8Y29kZT5Ob3JtYWwgUGVybWlzc2lvbjwvY29kZT7Kx7Wx08O7p7Cy17C78rj80MLTptPDyrGjrM+1zbO9q8ra0+jTptPDy/nH68fztcTIqM/eo6zT1rPGzqo8Y29kZT5QUk9URUNUSU9OX05PUk1BTDwvY29kZT6jqLCy17DKscrayKi1xNK7wOC7+bG+yKjP3qOpoaO4w8DgyKjP3ta70OjSqtTaPGNvZGU+bWFuaWZlc3Q8L2NvZGU+zsS8/tbQyfnD97y0v8mjrLCy17DKsb7NytrIqKOssrvQ6NKqw7+0zsq508PKsb340NC87LLpo6y2+MfS08O7p7K7xNzIoc/70tTJz8rayKihozwvcD4NCkFDQ0VTU19MT0NBVElPTl9FWFRSQV9DT01NQU5EUyBBQ0NFU1NfTkVUV09SS19TVEFURSBBQ0NFU1NfTk9USUZJQ0FUSU9OX1BPTElDWSBBQ0NFU1NfV0lGSV9TVEFURSBCTFVFVE9PVEggQkxVRVRPT1RIX0FETUlOIEJST0FEQ0FTVF9TVElDS1kgQ0hBTkdFX05FVFdPUktfU1RBVEUgQ0hBTkdFX1dJRklfTVVMVElDQVNUX1NUQVRFIENIQU5HRV9XSUZJX1NUQVRFIERJU0FCTEVfS0VZR1VBUkQgRVhQQU5EX1NUQVRVU19CQVIgR0VUX1BBQ0tBR0VfU0laRSBJTlNUQUxMX1NIT1JUQ1VUIElOVEVSTkVUIEtJTExfQkFDS0dST1VORF9QUk9DRVNTRVMgTU9ESUZZX0FVRElPX1NFVFRJTkdTIE5GQyBSRUFEX1NZTkNfU0VUVElOR1MgUkVBRF9TWU5DX1NUQVRTIFJFQ0VJVkVfQk9PVF9DT01QTEVURUQgUkVPUkRFUl9UQVNLUyBSRVFVRVNUX0lHTk9SRV9CQVRURVJZX09QVElNSVpBVElPTlMgUkVRVUVTVF9JTlNUQUxMX1BBQ0tBR0VTIFNFVF9BTEFSTSBTRVRfVElNRV9aT05FIFNFVF9XQUxMUEFQRVIgU0VUX1dBTExQQVBFUl9ISU5UUyBUUkFOU01JVF9JUiBVTklOU1RBTExfU0hPUlRDVVQgVVNFX0ZJTkdFUlBSSU5UIFZJQlJBVEUgV0FLRV9MT0NLIFdSSVRFX1NZTkNfU0VUVElOR1MNCjxwPs/CzbzOqjxjb2RlPkRhbmdlcm91cyBwZXJtaXNzaW9ucyBhbmQgcGVybWlzc2lvbiBncm91cHM8L2NvZGU+OjwvcD4NCjxwPjxpbWcgYWx0PQ=="image" src="/uploadfile/Collfiles/20160616/20160616090644102.png" title="\" />

在所有的Android版本中,你的應用都需要在manifest文件中聲明normaldangerous權限。然而聲明所影響的效果會因系統版本和你應用的target SDK lever有關:

如果設備運行的是Android 5.1或者之前的系統,或者應用的targetSdkVersion是22或者之前版本:如果你在manifest中聲明了dangerous permission,用戶需要在安裝應用時授權這些權限。如果用戶不授權這些權限,系統就不會安裝該應用。(我試了下發現即使targetSdkVersion是22及以下,在6.0的手機上時,如果你安裝時你不同意一些權限,也仍然可以安裝的) 如果設備運行的是Android 6.0或者更高的系統,並且你應用的targetSdkVersion是23或者更高:應用必須在manifest文件中申請這些權限,而且必須要在運行時對所需要的dangerous permission申請授權。用戶可以統一或者拒絕授權,並且及時用戶拒絕了授權,應用在無法使用一些功能的情況下也要保證能繼續運行。

也就是說新的運行時權限僅當我們設置targetSdkVersion是23及以上時才會起作用。
如果你的targtSdkVersion低於23,那將被認為該應用沒有經過android 6.0的測試,當該應用被安裝到了6.0的手機上時,仍然會使用之前的舊權限規則,在安裝時會提示所有需要的權限(這樣做是有道理的,不然對於之前開發的應用,我們都要立馬去修改讓它適應6.0,來不及的話就導致6.0的手機都無法使用了,顯然Android開發團隊不會考慮不到這種情況),當然用戶可以在安裝的界面不允許一些權限,那當程序使用到了這些權限時,會崩潰嗎?答案是在Android 6.0及以上的手機會直接crash,但是在23之前的手機上不會crash

所以如果你的應用沒有支持運行時權限的功能,那千萬不要講targetSdkVersion設置為23,否則就麻煩了。

注意:Android 6.0(API Level 23)開始,即使應用的targetSdkVersion是比較低的版本,但是用戶仍然可以在任何時候撤銷對應用的授權。所以不管應用的targetSdkVerison是什麼版本,你都要測試你的應用在不能獲取權限時能不能正常運行。

下面介紹下如何使用Android Support Library來檢查和請求權限。Android框架在6.0開始也提供了相同的方法。然而使用support包會比較簡單,因為這樣你就不需要在請求方法時判斷當前的系統版本。(後面說的這幾個類都是android.support.v4中的)

檢查權限

如果應用需要使用dangerous permission,在任何時候執行需要該權限的操作時你都需要檢查是否已經授權。用戶可能會經常取消授權,所以即使昨天應用已經使用了攝像頭,這也不能保證今天仍然有使用攝像頭的權限。

為了檢查是否可以使用該權限,調用ContextCompat.checkSelfPermission()
例如:

// Assume thisActivity is the current activity
int permissionCheck = ContextCompat.checkSelfPermission(thisActivity,
        Manifest.permission.WRITE_CALENDAR);

如果應用有該權限,該方法將返回PackageManager.PERMISSION_GRANTED,應用可以進行相關的操作。如果應用不能使用該權限,該方法將返回PERMISSION_DENIED,這是應用將必須要向用戶申請該權限。

申請使用權限

如果應用需要使用清單文件中申明的dangerous permission,它必須要向用戶申請來授權。Android提供了幾種申請授權的方法。使用這些方法時將會彈出一個標准的系統對話框,該對話框不能自定義。

說明為什麼應用需要使用這些權限

在一些情況下,你可能需要幫助用力理解為什麼需要該權限。例如,一個用戶使用了一個照相的應用,用戶不會奇怪為什麼應用申請使用攝像頭的權限,但是用戶可能會不理解為什麼應用需要獲取位置或者聯系人的權限。在請求一個權限之前,你需要該用戶一個說明。一定要切記不要通過說明來壓倒用戶。如果你提供了太多的說明,用戶可能會感覺沮喪並且會卸載它。

一個你需要提供說明的合適時機就是在用戶之前已經不同意授權該權限的情況下。如果一個用戶繼續嘗試使用需要權限的功能時,但是之前確禁止了該權限的請求,這就可能是因為用戶不理解為什麼該功能需要使用該權限。在這種情況下,提供一個說明是非常合適的。

為了能找到用戶可能需要說明的情況,android提供了一個工具類方法ActivityCompat.shouldShowRequestPermissionRationale().。如果應用之前申請了該權限但是用戶拒絕授權後該方法會返回true。(在Android 6.0之前調用的時候會直接返回false)

注意:如果用戶之前拒絕了權限申請並且選擇了請求權限對話框中的Don’t ask again選項,該方法就會返回false。如果設備策略禁止了該應用使用該權限,該方法也會返回false。(我測試的時候發現請求權限的對話框中並沒有Don’t asdk again這一項)
image

申請需要的權限

如果應用沒有所需的權限時,應用必須調用ActivityCompat.requestPermissions (Activity activity,
String[] permissions,
int requestCode)
方法來申請對用的權限。參數傳遞對應所需的權限以及一個整數型的request code來標記該權限申請。 該方法是異步的:該方法會立即返回,在用戶響應了請求權限的對話框之後,系統會調用對用的回調方法來通知結果,並且會傳遞在reqeustPermissions()方法中的request code。(在Android 6.0之前調用的時候會直接去調用onRequestPermissionsResult()的回調方法)
如圖:
image

下面是檢查是否讀取聯系人權限,並且在必要時申請權限的代碼:

// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
                Manifest.permission.READ_CONTACTS)
        != PackageManager.PERMISSION_GRANTED) {

    // Should we show an explanation?
    if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
            Manifest.permission.READ_CONTACTS)) {

        // Show an expanation to the user *asynchronously* -- don't block
        // this thread waiting for the user's response! After the user
        // sees the explanation, try again to request the permission.

    } else {

        // No explanation needed, we can request the permission.

        ActivityCompat.requestPermissions(thisActivity,
                new String[]{Manifest.permission.READ_CONTACTS},
                MY_PERMISSIONS_REQUEST_READ_CONTACTS);

        // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
        // app-defined int constant. The callback method gets the
        // result of the request.
    }
}

注意:當調用requestPermissions()方法時,系統會顯示一個標准的對話框。應用不能指定或者改變該對話框。如果你想提供一些信息或者說明給用戶,你需要在調用requestPermissions()之前處理。

處理請求權限的的結果

如果應用申請權限,系統會顯示一個對話框。當用戶相應後,系統會調用應用中的onRequestPermissionsResult (int requestCode,
String[] permissions,
int[] grantResults)
方法並傳遞用戶的操作結果。在應用中必須要重寫該方法來查找授權了什麼權限。該回調方法會傳遞你在requestPermisssions()方法中傳遞的request code。直接在Activity或者Fragment中重寫onRequestPermissionsResult()方法即可。例如,申請READ_CONTACTS的權限可能會有下面的回到方法:

@Override
public void onRequestPermissionsResult(int requestCode,
        String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay! Do the
                // contacts-related task you need to do.

            } else {

                // permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
            return;
        }

        // other 'case' lines to check for other
        // permissions this app might request
    }
}

系統提示的對話框會描述應用所需的permission groud。它不會列出特定的權限。例如,如果你申請了READ_CONTACTS權限,系統的對話框只會說你的應用需要獲取設備的聯系人信息。用戶只需要授權每個permission group一次。如果你應用需要申請其他任何一個在該permission group中的權限時,系統會自動授權。在申請這些授權時,系統會像用戶明確通過系統對話框統一授權時一樣去調用onRequestPermissionsResult()方法並且傳遞PERMISSION_GRANTED參數。

注意:雖然用戶已經授權了同一permission group中其他的任何權限,但是應用仍然需要明確申請每個需要的權限。例外,permission group中的權限在以後可能會發生變化。

例如,假設在應用的manifest文件中同時聲明了READ_CONTACTSWRITE_CONTACTS權限。如果你申請READ_CONTACTS權限而且用戶同意了該權限,如果你想繼續申請WRITE_CONTACTS權限,系統不會與用戶有任何交互就會直接進行授權。

如果用戶拒絕了一個權限申請,你的應用進行合適的處理。例如,你的應用可能顯示一個對話框來表明無法執行用戶請求的需要該權限的操作。

如果系統向用戶申請權限授權,用戶選擇了讓系統以後不要再申請該權限。 在這種情況下,應用在任何時間調用reqeustPermissions()方法來再次申請權限時,系統都會直接拒絕該請求。系統會直接調用onRequestPermissionResult()回調方法並且傳遞PERMISSION_DENIED參數,和用戶明確拒絕應用申請該權限時一樣。 這就意味著在你調用requestPermissions()方法是,你無法確定是否會和用戶有直接的交互操作。

示例代碼:


final private int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124;

private void insertDummyContactWrapper() {
    List permissionsNeeded = new ArrayList();

    final List permissionsList = new ArrayList();
    if (!addPermission(permissionsList, Manifest.permission.ACCESS_FINE_LOCATION))
        permissionsNeeded.add("GPS");
    if (!addPermission(permissionsList, Manifest.permission.READ_CONTACTS))
        permissionsNeeded.add("Read Contacts");
    if (!addPermission(permissionsList, Manifest.permission.WRITE_CONTACTS))
        permissionsNeeded.add("Write Contacts");

    if (permissionsList.size() > 0) {
        if (permissionsNeeded.size() > 0) {
            // Need Rationale
            String message = "You need to grant access to " + permissionsNeeded.get(0);
            for (int i = 1; i < permissionsNeeded.size(); i++)
                message = message + ", " + permissionsNeeded.get(i);
            showMessageOKCancel(message,
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
                                    REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
                        }
                    });
            return;
        }
        requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
                REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
        return;
    }

    insertDummyContact();
}

private boolean addPermission(List permissionsList, String permission) {
    if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
        permissionsList.add(permission);
        // Check for Rationale Option
        if (!shouldShowRequestPermissionRationale(permission))
            return false;
    }
    return true;
}

上面講到的都是Activity中的使用方法,那Fragment中怎麼授權呢?
如果在Fragment中使用,用v13包中的FragmentCompat.requestPermissions()FragmentCompat.shouldShowRequestPermissionRationale()

Fragment中申請權限,不要使用ActivityCompat.requestPermissions, 直接使用Fragment.requestPermissions方法,
否則會回調到ActivityonRequestPermissionsResult。但是雖然你使用Fragment.requestPermissions方法,也照樣回調不到Fragment.onRequestPermissionsResult中。這是AndroidBug,詳見,Google已經在23.3.0修復了該問題,所以要盡快升級。

所以升級到23.3.0及以上就沒問題了。如果不升級該怎麼處理呢?就是在Activity.onRequestPermissionsResult方法中去手動調用每個Fragment的方法(當然你要判斷下權限個數,不然申請一個權限的情況下會重復調用).

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    List fragments = getSupportFragmentManager().getFragments();
    if (fragments != null) {
        for (Fragment fragment : fragments) {
            fragment.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }
}

我簡單的寫了一個工具類:

public class PermissionUtil {
    /**
     * 在調用需要權限的功能時使用該方法進行檢查。
     *
     * @param activity
     * @param requestCode
     * @param iPermission
     * @param permissions
     */
    public static void checkPermissions(Activity activity, int requestCode, IPermission iPermission, String... permissions) {
        handleRequestPermissions(activity, requestCode, iPermission, permissions);
    }

    public static void checkPermissions(Fragment fragment, int requestCode, IPermission iPermission, String... permissions) {
        handleRequestPermissions(fragment, requestCode, iPermission, permissions);
    }

    public static void checkPermissions(android.app.Fragment fragment, int requestCode, IPermission iPermission, String... permissions) {
        handleRequestPermissions(fragment, requestCode, iPermission, permissions);
    }

    /**
     * 在Actvitiy或者Fragment中重寫onRequestPermissionsResult方法後調用該方法。
     *
     * @param activity
     * @param requestCode
     * @param permissions
     * @param grantResults
     * @param iPermission
     */
    public static void onRequestPermissionsResult(Activity activity, int requestCode, String[] permissions,
                                                  int[] grantResults, IPermission iPermission) {
        requestResult(activity, requestCode, permissions, grantResults, iPermission);

    }

    public static void onRequestPermissionsResult(Fragment fragment, int requestCode, String[] permissions,
                                                  int[] grantResults, IPermission iPermission) {
        requestResult(fragment, requestCode, permissions, grantResults, iPermission);
    }

    public static void onRequestPermissionsResult(android.app.Fragment fragment, int requestCode, String[] permissions,
                                                  int[] grantResults, IPermission iPermission) {
        requestResult(fragment, requestCode, permissions, grantResults, iPermission);
    }

    public static  void requestPermission(T t, int requestCode, String... permission) {
        List permissions = new ArrayList<>();
        for (String s : permission) {
            permissions.add(s);
        }
        requestPermissions(t, requestCode, permissions);
    }

    /**
     * 在檢查權限後自己處理權限說明的邏輯後調用該方法,直接申請權限。
     *
     * @param t
     * @param requestCode
     * @param permissions
     * @param 
     */
    public static  void requestPermission(T t, int requestCode, List permissions) {
        if (permissions == null || permissions.size() == 0) {
            return;
        }
        requestPermissions(t, requestCode, permissions);
    }

    public static boolean checkSelfPermission(Context context, String permission) {
        if (context == null || TextUtils.isEmpty(permission)) {
            throw new IllegalArgumentException("invalidate params: the params is null !");
        }

        context = context.getApplicationContext();

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
            int result = ContextCompat.checkSelfPermission(context, permission);
            if (PackageManager.PERMISSION_DENIED == result) {
                return false;
            }
        }

        return true;
    }

    private static  void handleRequestPermissions(T t, int requestCode, IPermission iPermission, String... permissions) {
        if (t == null || permissions == null || permissions.length == 0) {
            throw new IllegalArgumentException("invalidate params");
        }
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
            Activity activity = getActivity(t);
            List deniedPermissions = getDeniedPermissions(activity, permissions);
            if (deniedPermissions != null && deniedPermissions.size() > 0) {

                List rationalPermissions = new ArrayList<>();
                for (String deniedPermission : deniedPermissions) {
                    if (ActivityCompat.shouldShowRequestPermissionRationale(activity,
                            deniedPermission)) {
                        rationalPermissions.add(deniedPermission);
                    }
                }

                boolean showRational = false;
                if (iPermission != null) {
                    showRational = iPermission.showRational(requestCode);
                }

                if (rationalPermissions.size() > 0 && showRational) {
                    if (iPermission != null) {
                        iPermission.onRational(requestCode, deniedPermissions);
                    }
                } else {
                    requestPermissions(t, requestCode, deniedPermissions);
                }
            } else {
                if (iPermission != null) {
                    iPermission.onGranted(requestCode);
                }
            }
        } else {
            if (iPermission != null) {
                iPermission.onGranted(requestCode);
            }
        }
    }

    @Nullable
    private static  Activity getActivity(T t) {
        Activity activity = null;
        if (t instanceof Activity) {
            activity = (Activity) t;
        } else if (t instanceof Fragment) {
            activity = ((Fragment) t).getActivity();
        } else if (t instanceof android.app.Fragment) {
            activity = ((android.app.Fragment) t).getActivity();
        }
        return activity;
    }

    @TargetApi(Build.VERSION_CODES.M)
    private static  void requestPermissions(T t, int requestCode, List deniedPermissions) {
        if (deniedPermissions == null || deniedPermissions.size() == 0) {
            return;
        }
        // has denied permissions
        if (t instanceof Activity) {
            ((Activity) t).requestPermissions(deniedPermissions.toArray(new String[deniedPermissions.size()]), requestCode);
        } else if (t instanceof Fragment) {
            ((Fragment) t).requestPermissions(deniedPermissions.toArray(new String[deniedPermissions.size()]), requestCode);
        } else if (t instanceof android.app.Fragment) {
            ((android.app.Fragment) t).requestPermissions(deniedPermissions.toArray(new String[deniedPermissions.size()]), requestCode);
        }
    }

    private static List getDeniedPermissions(Context context, String... permissions) {
        if (context == null || permissions == null || permissions.length == 0) {
            return null;
        }
        List denyPermissions = new ArrayList<>();
        for (String permission : permissions) {
            if (!checkSelfPermission(context, permission)) {
                denyPermissions.add(permission);
            }
        }
        return denyPermissions;
    }


    private static  void requestResult(T t, int requestCode, String[] permissions,
                                          int[] grantResults, IPermission iPermission) {
        List deniedPermissions = new ArrayList<>();
        for (int i = 0; i < grantResults.length; i++) {
            if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                deniedPermissions.add(permissions[i]);
            }
        }
        if (deniedPermissions.size() > 0) {
            if (iPermission != null) {
                iPermission.onDenied(requestCode);
            }
        } else {
            if (iPermission != null) {
                iPermission.onGranted(requestCode);
            }
        }
    }

}

interface IPermission {
    void onGranted(int requestCode);

    void onDenied(int requestCode);

    void onRational(int requestCode, List permissions);

    /**
     * 是否需要提示用戶該權限的作用,提示後需要再調用requestPermission()方法來申請。
     *
     * @return true 為提示,false為不提示
     */
    boolean showRational(int requestCode);
}

使用方法:

public class MainFragment extends Fragment implements View.OnClickListener {
    private Button mReqCameraBt;
    private Button mReqContactsBt;
    private Button mReqMoreBt;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_main, container, false);
        findView(view);
        initView();
        return view;
    }

    private void findView(View view) {
        mReqCameraBt = (Button) view.findViewById(R.id.bt_requestCamera);
        mReqContactsBt = (Button) view.findViewById(R.id.bt_requestContacts);
        mReqMoreBt = (Button) view.findViewById(R.id.bt_requestMore);
    }

    private void initView() {
        mReqCameraBt.setOnClickListener(this);
        mReqContactsBt.setOnClickListener(this);
        mReqMoreBt.setOnClickListener(this);
    }


    public static final int REQUEST_CODE_CAMERA = 0;
    public static final int REQUEST_CODE_CONTACTS = 1;
    public static final int REQUEST_CODE_MORE = 2;

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        PermissionUtil.onRequestPermissionsResult(this, requestCode, permissions, grantResults, mPermission);
    }

    public void requestCamera() {
        PermissionUtil.checkPermissions(this, REQUEST_CODE_CAMERA, mPermission, Manifest.permission.CAMERA);
    }

    public void requestReadContacts() {
        PermissionUtil.checkPermissions(this, REQUEST_CODE_CONTACTS, mPermission, Manifest.permission.READ_CONTACTS);
    }

    public void requestMore() {
        PermissionUtil.checkPermissions(this, REQUEST_CODE_MORE, mPermission, Manifest.permission.READ_CONTACTS, Manifest.permission.READ_CALENDAR, Manifest.permission.CALL_PHONE);
    }

    private void showPermissionTipDialog(final int requestCode, final List permissions) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setMessage("I want you permissions");
        builder.setTitle("Hello Permission");
        builder.setPositiveButton("確認", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                PermissionUtil.requestPermission(MainFragment.this, requestCode, permissions);
            }
        });
        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });
        builder.create().show();
    }

    public IPermission mPermission = new IPermission() {
        @Override
        public void onGranted(int requestCode) {
            Toast.makeText(getActivity(), "onGranted :" + requestCode, Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onDenied(int requestCode) {
            Toast.makeText(getActivity(), "onDenied :" + requestCode, Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onRational(int requestCode, List permission) {
            showPermissionTipDialog(requestCode, permission);
        }

        @Override
        public boolean showRational(int requestCode) {
            switch (requestCode) {
                case REQUEST_CODE_MORE:
                    return true;

                default:
                    break;
            }
            return false;
        }
    };

    @Override
    public void onClick(View v) {
        int id = v.getId();
        switch (id) {
            case R.id.bt_requestCamera:
                requestCamera();
                break;
            case R.id.bt_requestContacts:
                requestReadContacts();
                break;
            case R.id.bt_requestMore:
                requestMore();
                break;
        }
    }
}

 

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