Android檢查應用許可權是否被禁用,解決許可權被禁用時程式崩潰
阿新 • • 發佈:2019-02-05
一、問題描述
在Android開發中,往往會用到許多諸如攝像頭、錄音等許可權。但是,我們都知道,小米、魅族等定製系統,或者360等安全軟體在程式請求開啟相機、錄音等操作時,會先彈出對話方塊提示使用者是否允許程式執行這些操作,如果使用者選擇允許則接下來的操作一切正常,如果使用者選擇拒絕之後,程式後面的工作將無法正常允許,甚至崩潰。
那麼如何判斷使用者是拒絕還是允許了該許可權呢?
二、錯誤的判斷方式
在我到網上搜索這個問題的過程中,搜到了很多如下的判斷方式,然而這其實是無效的(),先貼出程式碼看一下:
boolean permission = (PackageManager.PERMISSION_GRANTED == getPackageManager() .checkPermission("android.permission.CAMERA", getPackageName())); if (permission) { Toast.makeText(this, "有這個許可權", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(this, "沒有這個許可權", Toast.LENGTH_SHORT).show(); }
如上,這段程式碼其實只是判斷了你的程式是否在manifest檔案中聲明瞭某許可權,並無法判斷使用者是否拒絕了某許可權。
三、問題研究
當我們開啟系統的應用許可權管理或者安全軟體的許可權管理時,可以看到程式申請的許可權列表,但是一些敏感許可權都是有3種狀態的,即“允許”、“提醒”、“禁用”。所以我們需要的不是判斷許可權是否在manifest檔案中聲明瞭沒有,而是判斷程式的許可權狀態到底是允許還是禁用。
然而,只有在安卓 6.0 之上才有這樣的方法可以判斷這個狀態。
四、正確的解決方式
1.動態許可權申請(Android 6.0 以上)
在 onCreate() 方法中呼叫許可權檢查,如果未擁有許可權則動態申請許可權
private void checkPermission() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { String[] permissions = new String[]{Manifest.permission.CAMERA}; int i = ContextCompat.checkSelfPermission(this, permissions[0]); if (i != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, permissions, 200); return; } } }
還需要新增一個回撥方法
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[]
grantResults) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && requestCode == 200) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
initFragment();
} else {
Toast.makeText(this, "請在設定中開啟許可權後繼續", Toast.LENGTH_SHORT).show();
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivityForResult(intent, 200);
}
}
}
2.使用 try-catch 這種暴力的解決方法吧
將相應程式碼 try-catch 起來,然後在catch塊中提示使用者開啟相應許可權。
try {
mCamera = Camera.open(0); // 任意可能被拒絕許可權程式崩潰的程式碼
} catch (RuntimeException e) {
e.printStackTrace();
Toast.makeText(getActivity(), "請開啟xx許可權", Toast.LENGTH_LONG).show();
}
如果是傳送簡訊等許可權,則可以通過判斷簡訊是否傳送成功判斷