遇到一個比較奇葩的問題粱坤,特此記錄:
動態(tài)權(quán)限校驗 Android 6.0 的 oppo & vivo 手機(jī)時痕慢,始終返回 權(quán)限已被允許
但是當(dāng)真正用到該權(quán)限時,卻又彈出權(quán)限申請框抑堡。
ContextCompat.checkSelfPermission(container.activity, Manifest.permission.CAMERA);
// 返回值
0
// 而權(quán)限校驗的變量
public static final int PERMISSION_GRANTED = 0;
public static final int PERMISSION_DENIED = -1;
// 進(jìn)行判斷時摆出,下面表示已允許
PackageManager.PERMISSION_GRANTED;
很顯然,返回的始終是 允許首妖,但是在使用時仍會彈出權(quán)限申請框偎漫。
解決
竊以為,是廠商管家之類的對權(quán)限的獲取進(jìn)行了修改有缆。
- 進(jìn)行偽權(quán)限判斷(延時判斷象踊,超時則默認(rèn)沒有權(quán)限,而不進(jìn)行下一步操作)
- 進(jìn)入下一頁棚壁,但是因為沒有權(quán)限杯矩,無法使用相關(guān)功能,直到獲取到權(quán)限
- 進(jìn)入下一頁袖外,在訪問權(quán)限失敗的地方 finish 掉當(dāng)前頁面
private void startPreview() {
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
previewing = true;
} catch (Exception e) {
Toast.makeText(this, R.string.connect_vedio_device_fail, Toast.LENGTH_SHORT).show();
shutdownCamera();
e.printStackTrace();
// 訪問失斒仿 (沒有權(quán)限),退出當(dāng)前頁面
finish();
}
}
@SuppressLint("NewApi")
private boolean initCamera() {
try {
if (multiCamera) {
camera = Camera.open(cameraId);
} else {
camera = Camera.open();
}
} catch (RuntimeException e) {
LogUtil.e(TAG, "init camera failed: " + e);
Toast.makeText(this, R.string.connect_vedio_device_fail, Toast.LENGTH_SHORT).show();
// 訪問失斅椤(沒有權(quán)限)逆害,退出當(dāng)前頁面
finish();
return false;
}
不盡之意
需要注意的是,獲取存儲權(quán)限后蚣驼,寫入文件時不同機(jī)型處理也不相同魄幕。
華為手機(jī)寫入文件時,路徑不存在會自動創(chuàng)建
而vivo 和 oppo 會報錯颖杏,會閃退纯陨。FileNotFoundException
新的問題(2018.10.11)
開始錄制時,需要計時器計時展示。
當(dāng)vivo手機(jī) 調(diào)用 audioRecord.startRecording() 時翼抠,權(quán)限管家監(jiān)測到錄音咙轩,彈出權(quán)限彈窗。
在等待選擇允許還是禁止錄音權(quán)限的時候阴颖,界面已經(jīng)變?yōu)殇浿浦袪顟B(tài)活喊,計時器開始跑了起來!
最困擾我們的量愧,就是無法監(jiān)測 vivo 或 oppo 的軟件管家是否賦予了權(quán)限钾菊,如果可以,就不需要這么多繞圈圈的方法了偎肃。
解決方法
想到了一個釜底抽薪的辦法煞烫,我們沒辦法監(jiān)測軟件管家的權(quán)限授予,卻可以監(jiān)測是否已經(jīng)開始錄音累颂!
比如滞详,監(jiān)測 當(dāng)前錄音狀態(tài)是否開始,或者是否產(chǎn)生了錄音文件紊馏。
采用第一種方法料饥,監(jiān)測錄音狀態(tài),是否已開始錄音
try {
// 必須執(zhí)行 startRecording 朱监,才能讓軟件管家監(jiān)測到錄音岸啡,從而彈出權(quán)限彈窗。
recorder!!.startRecording()
} catch (e: IllegalStateException) {
e.printStackTrace()
} finally {
// 在 finally 中進(jìn)行錄音狀態(tài)判斷赌朋,是否已經(jīng)開始錄音凰狞。狀態(tài)為開始錄音,才進(jìn)行下一步操作沛慢。
if (recorder?.recordingState() == AudioRecord.RECORDSTATE_RECORDING) {
startRecord()
}
}
源碼中赡若,錄音狀態(tài)有兩種,一目了然
/**
* indicates AudioRecord recording state is not recording
*/
public static final int RECORDSTATE_STOPPED = 1; // matches SL_RECORDSTATE_STOPPED
/**
* indicates AudioRecord recording state is recording
*/
public static final int RECORDSTATE_RECORDING = 3;// matches SL_RECORDSTATE_RECORDING
看到一篇校驗權(quán)限的文章团甲,感覺不錯逾冬,記錄下來,希望有用躺苦。