在Android6.0以后開始,對於部分敏感的“危險”權限,需要在應用運行時向用戶申請,只有用戶允許的情況下這個權限才會被授予給應用。這對於用戶來說,無疑是一個提升安全性的做法。那么對於開發者,應該怎么做呢?
Android6.0規定的危險權限有下面這些:
Permission Group | Permissions |
---|---|
CALENDAR |
|
CAMERA |
|
CONTACTS |
|
LOCATION |
|
MICROPHONE |
|
PHONE |
|
SENSORS |
|
SMS |
|
STORAGE |
從一個例子入手吧。假如在App中需要進行撥打電話的操作,當點擊按鈕,直接撥出一個電話,代碼如下:
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:10086")); startActivity(intent);
但是如果你的編譯版本是23或者以上,那么Android Studio就會報出一個錯誤
提示我們要進行權限請求。
如果我們直接對這個錯誤進行自動修復,會在startActivity方法之前增加一段代碼用於權限檢查,如果當前沒有賦予該權限,則直接return結束方法:
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) { // TODO: Consider calling // ActivityCompat#requestPermissions // here to request the missing permissions, and then overriding // public void onRequestPermissionsResult(int requestCode, String[] permissions, // int[] grantResults) // to handle the case where the user grants the permission. See the documentation // for ActivityCompat#requestPermissions for more details. return; }
如果這個時候直接運行,你的APP照樣是沒有得到這個權限的,因為默認安裝的時候,這個權限會被關閉到,所以方法直接就返回了。要是需要在點擊按鈕的時候,直接向用戶請求權限,可以使用下面的方法:
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, REQUESTCODE);
這個時候,再重新運行App,會得到下面的一個界面來請求用戶權限:
允許:以后不再彈出請求框,直接允許應用獲得該權限
拒絕:下次需要時會重新彈出,直到用戶選擇允許,否則會不斷出現
那么問題就來了,如果用戶勾選了不再詢問並拒絕了請求會怎樣呢?答案是以后不會再彈出,並且默認拒絕權限請求,也就是說,應用再也不能獲得這個權限,除非用戶主動進入應用設置中重新授權。
為了更好的用戶體驗,可以在用戶選擇了不再詢問和拒絕之后,創建一個AlertDialog來詢問用戶是否需要重新授予權限,是的話,跳轉到應用設置界面。
當我們調用requestPermissions方法的時候,無論成功與否,都會將結果回調給Activity中的onRequestPermissionsResult方法中,我們可以通過重寫這個方法來處理結果:
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUESTCODE) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (!shouldShowRequestPermissionRationale(Manifest.permission.CALL_PHONE)) { AskForPermission(); } } } }
先判斷請求是否為我們所申請的,接着判斷SDK的版本是否高於或等於AndroidM(6.0),如果是,則調用shouldShowRequestPermissionRationale方法來檢查權限申請框是否會顯示,因為如果用戶選擇了不再詢問,則申請框會不出現,這個方法會返回false,如果申請框沒有出現,則創建一個AlertDialog來詢問用戶:
private void AskForPermission() { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("Need Permission!"); builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); builder.setPositiveButton("Settings", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); intent.setData(Uri.parse("package:" + getPackageName())); // 根據包名打開對應的設置界面 startActivity(intent); } }); builder.create().show(); }