1. 程式人生 > >Android檢查應用許可權是否被禁用,解決許可權被禁用時程式崩潰

Android檢查應用許可權是否被禁用,解決許可權被禁用時程式崩潰

一、問題描述

        在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();
}

如果是傳送簡訊等許可權,則可以通過判斷簡訊是否傳送成功判斷