Android6.0運行時權限處理-超簡單封裝

之前調試的時候,出現了一個問題,就是當我打開二維碼掃描界面的時候,對于一部分手機一直不會出現那個掃描框,這點我也很是郁悶,這不好整啊,畢竟二維碼界面是用的別人的,怎么改啊?這個時候我分析了一下原因,最后知道只有部分6.0的手機才會出現這種情況,那么這就簡單了。下面我就對關于6.0手機動態申請安全權限做一下講解:

對于6.0以下的權限及在安裝的時候,根據權限聲明產生一個權限列表,用戶只有在同意之后才能完成app的安裝,造成了我們想要使用某個app,就只能默認接受其一些不必要的權限,而在6.0以后,當app需要我們授予不恰當的權限的時候,我們可以予以拒絕。但是這些權限也是有限制的,比如說只是針對一些安全權限做動態授權處理,如打開手機攝像頭、打開聯系人、打開錄音等等,這些涉及到用戶安全權限的時候,就要我們開發者手動去請求用戶打開權限。廢話就到這里,下面看具體實現。

1、檢查權限:

if (ContextCompat.checkSelfPermission(thisActivity,

Manifest.permission.READ_CONTACTS)

!= PackageManager.PERMISSION_GRANTED) {

}else{

//

}

ContextCompat.checkSelfPermission,主要用于檢測某個權限是否已經被授予,方法返回值為PackageManager.PERMISSION_DENIED或者PackageManager.PERMISSION_GRANTED。當返回DENIED就需要進行申請授權了。

2、申請權限:

ActivityCompat.requestPermissions(thisActivity,

new String[]{Manifest.permission.READ_CONTACTS},

MY_PERMISSIONS_REQUEST_READ_CONTACTS);

第二個參數是需要申請的權限的字符串數組,第三個參數為請求碼,主要用于回調的時候檢測。可以從方法名requestPermissions以及第二個參數看出,是支持一次性申請多個權限的,系統會通過彈出對話框一個個的詢問用戶是否授權。

3、權限的申請回調:

@Override

public void onRequestPermissionsResult(int requestCode,

String permissions[], int[] grantResults) {

switch (requestCode) {

case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {

// If request is cancelled, the result arrays are empty.

if (grantResults.length > 0

&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {

// permission was granted, yay! Do the

// contacts-related task you need to do.

} else {

// permission denied, boo! Disable the

// functionality that depends on this permission.

}

return;

}

}

}

首先驗證請求碼并結合你的申請,然后驗證grantResults對應的申請的結果,如果你申請的權限數組有兩個權限,那么grantResults的length就為2

還有一點:

if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,

Manifest.permission.READ_CONTACTS))

// Show an expanation to the userasynchronously– don’t block

// this thread waiting for the user’s response! After the user

// sees the explanation, try again to request the permission.

}

這個方法就是給用戶一個權限申請作出必要的解釋,比如用戶第一次拒絕過你的權限申請,現在你又點擊拍照,那么久需要調用這個方法,作出一個解釋,解釋為什么需要拍照權限。

好了,到這里估計你會說,怎么感覺有點小麻煩呢! 沒錯,勞資也感覺是很麻煩啊,我的理念就是統統一條方法解決一個問題,那么,這時候上面的都不要再去看了,什么鬼東西,只需要在你的BaseActivity或者BaseFragment中添加幾行我的下面的代碼,然后調用的時候,就是一行代碼搞定。(上面的部分統統略去,下面的才是今天的主要)

在你的BaseActivity或者BaseFragment中添加幾行下面的代碼就行了:

private int mPermissionIdx = 0x10;//請求權限索引

private SparseArray mPermissions = new SparseArray<>();//請求權限運行列表

@SuppressLint("Override")

public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {

GrantedResult runnable = mPermissions.get(requestCode);

if (runnable == null) {

return;

}

if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

runnable.mGranted = true;

}

runOnUiThread(runnable);

}

public void requestPermission(String[] permissions, String reason, GrantedResult runnable) {

if(runnable == null){

return;

}

runnable.mGranted = false;

if (Build.VERSION.SDK_INT < 23 || permissions == null || permissions.length == 0) {

runnable.mGranted = true;//新添加

runOnUiThread(runnable);

return;

}

final int requestCode = mPermissionIdx++;

mPermissions.put(requestCode, runnable);

/*

是否需要請求權限

*/

boolean granted = true;

for (String permission : permissions) {

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

granted = granted && checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED;

}

}

if (granted) {

runnable.mGranted = true;

runOnUiThread(runnable);

return;

}

/*

是否需要請求彈出窗

*/

boolean request = true;

for (String permission : permissions) {

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

request = request && !shouldShowRequestPermissionRationale(permission);

}

}

if (!request) {

final String[] permissionTemp = permissions;

AlertDialog dialog = new AlertDialog.Builder(this)

.setMessage(reason)

.setPositiveButton("確定", new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

requestPermissions(permissionTemp, requestCode);

}

}

})

.setNegativeButton("取消", new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

dialog.dismiss();

GrantedResult runnable = mPermissions.get(requestCode);

if (runnable == null) {

return;

}

runnable.mGranted = false;

runOnUiThread(runnable);

}

}).create();

dialog.show();

} else {

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

requestPermissions(permissions, requestCode);

}

}

}

public static abstract class GrantedResult implements Runnable{

private boolean mGranted;

public abstract void onResult(boolean granted);

@Override

public void run(){

onResult(mGranted);

}

}

那么最最重要的來了,那就是用法咯:(往下接著看)

比如說你需要點擊一下拍照按鈕就打開系統的攝像頭進行拍照,那么就在你打開按鈕的監聽事件中這么寫:(比如說是在CarmerActivity中,繼承BaseActivity)

openCarmer.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

requestPermission(new String[]{Manifest.permission.CAMERA}, “請求設備相機權限”, new GrantedResult() {

@Override

public void onResult(boolean granted) {

if(granted){//表示用戶允許

createLocalStream();

}else {//用戶拒絕

Toast.makeText(MainActivity.this,”權限拒絕”,Toast.LENGTH_SHORT).show();

}

}

});

}

});

同樣的在fragment中一樣可以使用,即((AbsBaseActivity)getActivity()).requestPermission(...)這種方式即可,當首次彈出系統授權彈出框,如果用戶點擊拒絕的話,那么第二次再次需要該權限的話,會打開自定義的提示框且提示自定義的提示描述,所以動態授權還是非常的人性化的。最后提示一下,如果你覺得在應用內每次都是用到的時候才去授權比較麻煩,那么你也可以在用戶剛進入應用后的啟動頁面一次性開啟所有的安全權限,這種方式更加的簡便。

ok,大功告成!!!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,885評論 6 541
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,312評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,993評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,667評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,410評論 6 411
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,778評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,775評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,955評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,521評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,266評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,468評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,998評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,696評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,095評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,385評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,193評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,431評論 2 378

推薦閱讀更多精彩內容