這幾天嘗試着用Android Studio寫一個小工具的時候遇到了一個動態權限申請的問題。權限的申請使用的語句為:
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.SEND_SMS}, MY_PERMISSIONS_REQUEST_SEND_SMS);
其中MY_PERMISSIONS_REQUEST_SEND_SMSjava
為申請的一個int型的變量,用於指代權限代碼,相比數字更易於程序維護。
為了判斷程序是否已擁有某種權限,可以使用以下方法:
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.SEND_SMS) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.SEND_SMS}, MY_PERMISSIONS_REQUEST_SEND_SMS); } else { }
使用上述語句即可完成權限的申請。但為了判斷用戶是否同意了該權限,需要使用onRequestPermissionsResult
接口來判斷。問題就出在這里,按照之前的寫法寫出后會在彈出權限的申請后立馬閃退。
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.SEND_SMS) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.SEND_SMS}, MY_PERMISSIONS_REQUEST_SEND_SMS); } else { }
經排查發現使用這種情況會在判斷grantResults[0] == PackageManager.PERMISSION_GRANTED
這一語句的時候出現數組非法的情況。這是因為用戶還沒有對彈出的權限對話框做出選擇,但該事件已經被觸發,此時的grantResult是一個空數組,判斷他的第一個元素是否為1就會出現exception:

對於使用switch語句的另一種寫法也可能出現類似情況。
這里的解決方案是將條件判斷改為grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED
,增加一個對grantResult的長度判斷,排除空數組的情況,即可正常處理用戶的反饋。可以使用以下語句:
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (requestCode == MY_PERMISSIONS_REQUEST_SEND_SMS) { if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // Permission Granted } else if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_DENIED) { // Permission Denied } else { super.onRequestPermissionsResult(requestCode, permissions, grantResults); } } }
此后即可正常處理后續事件。

由於在Android API 6.0之后不能再像以前一樣,在AndroidManifest.xml里加上權限即可使用相關權限,只能通過動態的方式申請權限,關於這一部分的更多使用可以參考Google官方給出一個動態權限申請的實例文檔:https://github.com/googlesamples/android-RuntimePermissions
來源:https://billc.io/2019/01/android-request-permission-issue/