本文和大家分享的主要是android
相機權(quán)限適配中常見的一些坑,一起來看看吧,希望對大家
學習android有所幫助。
我們都知道,google
在
6.0
以后加強了應用權(quán)限的管理,我們也能通過標準的方法去申請權(quán)限,但是由于一些廠商的修改,在適配過程中我們會遇到各種各樣的問題。在
6.0
之前,也可能會因為用戶的一些設置導致我們無法獲取權(quán)限。
6.0以下系統(tǒng)
·
打開系統(tǒng)相機常規(guī)來說不需要相機權(quán)限。但是如果手機
root
了,并且使用獲得
root
權(quán)限
(
未獲取
root
權(quán)限設置不起作用
)
的安全管理(如
LBE
,開啟主動防御后)軟件管理權(quán)限,此時就會出現(xiàn)一些問題。比如:在我們的軟件調(diào)用系統(tǒng)相機拍照時,這些安全管理的軟件會攔截這個請求,然后根據(jù)我們的設置(第一次請求時一般彈窗詢問)允許、詢問或者拒絕權(quán)限,此時如果是拒絕了,我們將無法調(diào)用系統(tǒng)相機!而此時如果用戶勾選了記住選擇并拒絕,那么我們將無法調(diào)用系統(tǒng)相機并且在下一次請求時沒有任何提示!
·
由于掃描二維碼不是常規(guī)的打開系統(tǒng)的相機界面,所以就算是在
6.0
以下也要判斷權(quán)限,一般通過如下方法判斷是否擁有相機權(quán)限
/**
*
通過嘗試打開相機的方式判斷有無拍照權(quán)限(在
6.0
以下使用擁有
root
權(quán)限的管理軟件可以管理權(quán)限)
*
*
@return
*/
public
static boolean cameraIsCanUse() {
boolean isCanUse =
true;
Camera mCamera =
null;
try {
mCamera = Camera.open();
Camera.Parameters mParameters = mCamera.getParameters();
mCamera.setParameters(mParameters);
}
catch (
Exception e) {
isCanUse =
false;
}
if (mCamera !=
null) {
try {
mCamera.release();
}
catch (
Exception e) {
e.printStackTrace();
return isCanUse;
}
}
return isCanUse;
}
·
根據(jù)上面的代碼,我們想是不是可以用來解決問題一。因為通過調(diào)用以上代碼,如果無法打開相機
(
返回
false)
則說明沒有了相機權(quán)限。
·
但是,在測試過程中發(fā)現(xiàn),
LBE
如果開啟了主動防御,能正確的控制權(quán)限,但是沒有開啟主動防御,任憑你怎么設置權(quán)限都是沒用的,就算你在
LBE
中拒絕了相機權(quán)限但還是能打開系統(tǒng)相機的(也就是說沒有開啟主動防御這些設置是不生效的,不知道為什么還允許用戶設置)!
·
而且,如果關(guān)閉了
LBE
的主動防御再去應用調(diào)用相機,雖然上面的代碼會返回
false
,但是,這時候還是可以調(diào)用系統(tǒng)相機的!
·
綜上,在
6.0
以下系統(tǒng),我們可以選擇這樣做,在調(diào)用二維碼的地方使用上述代碼去判斷是否能打開相機,調(diào)用系統(tǒng)相機界面拍照則無需判斷(因為只有
root
過的手機才能攔截這個請求),如果用戶
root
過,我們沒法得到正確的判斷,所以只能選擇放棄了!
6.0及以上系統(tǒng)
·6.0
開始,應用中使用敏感權(quán)限需要通過用戶的允許,所以,我們需要下面這樣一個工具類來獲取權(quán)限(直接上代碼,代碼中有解釋):
/**
*
從
fragment
檢查權(quán)限,如果傳入的
fragment
是
null
,則后面請求權(quán)限時會調(diào)用
ActivityCompat
*
的方法
*
*
檢查
6.0
及以上版本時,應用是否擁有某個權(quán)限,擁有則返回
true
,未擁有則再判斷上次
*
用戶是否拒絕過該權(quán)限的申請(拒絕過則
shouldShowRequestPermissionRationale
返回
* true——
這里有些手機如紅米
(
紅米
pro)
永遠返回
false
*
這里的處理是彈一個對話框引導用戶去應用的設置界面打開權(quán)限,返回
false
時這里執(zhí)行
* requestPermissions
方法,此方法會顯示系統(tǒng)默認的一個權(quán)限授權(quán)提示對話框,并在
* Activity
或
Fragment
的
onRequestPermissionsResult
得到回調(diào),注意方法中的
requestCode
*
要與此處相同)
*
* @param fragment
:如果
fragment
不為
null
則調(diào)用
fragment
的方法申請權(quán)限(因為有些手機
*
上在
Fragment
調(diào)用
ActivityCompat
的 方法申請權(quán)限得不到回調(diào),例如紅米手機)
* @param activity
:用于彈出提示窗和獲取權(quán)限
* @param permission
:對應的權(quán)限名稱,如:
Manifest.permission.CAMERA
* @param hint
:引導用戶進入設置界面對話框的提示文字
* @param requestCode
:請求碼,對應
Activity
或
Fragment
的
onRequestPermissionsResult
*
方法的
requestCode
* @return
:
true-
擁有對應的權(quán)限
false
:未擁有對應的權(quán)限
*/
public
static boolean checkPermission(Fragment fragment,
final Activity activity, String permission,
String hint, int requestCode) {
//
檢查權(quán)限
if (ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(activity, permission)) {
//
顯示我們自定義的一個窗口引導用戶開啟權(quán)限
showPermissionSettingDialog(activity, hint);
}
else {
//
申請權(quán)限
if (fragment ==
null) {
ActivityCompat.requestPermissions(activity,
new String[]{permission},
requestCode);
}
else {
fragment.requestPermissions(
new String[]{permission},
requestCode);
}
}
return
false;
}
else { //
已經(jīng)擁有權(quán)限
return
true;
}
}
·
通過注釋我們也可以看到,在一些手機上如果按照
google
的寫法,也會出現(xiàn)一些問題。但是在測試過程中使用模擬器并沒有出現(xiàn)這樣的問題。
·
問題
1
:在模擬器上,無論在
activity
還是
Fragment
中,調(diào)用
ActivityCompat.requestPermissions
去申請權(quán)限都能得到回調(diào)。而在小米手機上,如果在
Fragment
中調(diào)用申請權(quán)限的方法,必須使用
Fragment
的
requestPermissions
方法去申請權(quán)限才能在
Fragment
中得到回調(diào)。由于沒有條件,所以只測試了紅米手機
(
紅米
pro)
,其他手機暫時不清楚!
·
問題
2
:在小米上,
shouldShowRequestPermissionRationale
始終返回
false
·
問題
3
:在應用運行的過程中,如果去系統(tǒng)的設置里面關(guān)閉了應用的某個權(quán)限,再回來應用時會閃退(前提是前面這個權(quán)限是使用過的)!可以參考我的另一篇文章解決:
http://www.jianshu.com/p/8c08080220f1
,測試過程發(fā)現(xiàn),QQ
運行過程中,在設置界面手動關(guān)閉了他的某個界面,他竟不會重啟,而且毫無卡頓,雖然微信沒有顯式的重啟,但是在恢復界面過程中會有明顯的卡頓,而支付寶則直接重啟應用!
來源:簡書