Android6.0運(yùn)行時(shí)權(quán)限處理-超簡(jiǎn)單封裝

之前調(diào)試的時(shí)候,出現(xiàn)了一個(gè)問(wèn)題,就是當(dāng)我打開(kāi)二維碼掃描界面的時(shí)候,對(duì)于一部分手機(jī)一直不會(huì)出現(xiàn)那個(gè)掃描框,這點(diǎn)我也很是郁悶,這不好整啊,畢竟二維碼界面是用的別人的,怎么改啊?這個(gè)時(shí)候我分析了一下原因,最后知道只有部分6.0的手機(jī)才會(huì)出現(xiàn)這種情況,那么這就簡(jiǎn)單了。下面我就對(duì)關(guān)于6.0手機(jī)動(dòng)態(tài)申請(qǐng)安全權(quán)限做一下講解:

對(duì)于6.0以下的權(quán)限及在安裝的時(shí)候,根據(jù)權(quán)限聲明產(chǎn)生一個(gè)權(quán)限列表,用戶只有在同意之后才能完成app的安裝,造成了我們想要使用某個(gè)app,就只能默認(rèn)接受其一些不必要的權(quán)限,而在6.0以后,當(dāng)app需要我們授予不恰當(dāng)?shù)臋?quán)限的時(shí)候,我們可以予以拒絕。但是這些權(quán)限也是有限制的,比如說(shuō)只是針對(duì)一些安全權(quán)限做動(dòng)態(tài)授權(quán)處理,如打開(kāi)手機(jī)攝像頭、打開(kāi)聯(lián)系人、打開(kāi)錄音等等,這些涉及到用戶安全權(quán)限的時(shí)候,就要我們開(kāi)發(fā)者手動(dòng)去請(qǐng)求用戶打開(kāi)權(quán)限。廢話就到這里,下面看具體實(shí)現(xiàn)。

1、檢查權(quán)限:

if (ContextCompat.checkSelfPermission(thisActivity,

Manifest.permission.READ_CONTACTS)

!= PackageManager.PERMISSION_GRANTED) {

}else{

//

}

ContextCompat.checkSelfPermission,主要用于檢測(cè)某個(gè)權(quán)限是否已經(jīng)被授予,方法返回值為PackageManager.PERMISSION_DENIED或者PackageManager.PERMISSION_GRANTED。當(dāng)返回DENIED就需要進(jìn)行申請(qǐng)授權(quán)了。

2、申請(qǐng)權(quán)限:

ActivityCompat.requestPermissions(thisActivity,

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

MY_PERMISSIONS_REQUEST_READ_CONTACTS);

第二個(gè)參數(shù)是需要申請(qǐng)的權(quán)限的字符串?dāng)?shù)組,第三個(gè)參數(shù)為請(qǐng)求碼,主要用于回調(diào)的時(shí)候檢測(cè)。可以從方法名requestPermissions以及第二個(gè)參數(shù)看出,是支持一次性申請(qǐng)多個(gè)權(quán)限的,系統(tǒng)會(huì)通過(guò)彈出對(duì)話框一個(gè)個(gè)的詢問(wèn)用戶是否授權(quán)。

3、權(quán)限的申請(qǐng)回調(diào):

@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;

}

}

}

首先驗(yàn)證請(qǐng)求碼并結(jié)合你的申請(qǐng),然后驗(yàn)證grantResults對(duì)應(yīng)的申請(qǐng)的結(jié)果,如果你申請(qǐng)的權(quán)限數(shù)組有兩個(gè)權(quán)限,那么grantResults的length就為2

還有一點(diǎn):

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.

}

這個(gè)方法就是給用戶一個(gè)權(quán)限申請(qǐng)作出必要的解釋,比如用戶第一次拒絕過(guò)你的權(quán)限申請(qǐng),現(xiàn)在你又點(diǎn)擊拍照,那么久需要調(diào)用這個(gè)方法,作出一個(gè)解釋,解釋為什么需要拍照權(quán)限。

好了,到這里估計(jì)你會(huì)說(shuō),怎么感覺(jué)有點(diǎn)小麻煩呢! 沒(méi)錯(cuò),勞資也感覺(jué)是很麻煩啊,我的理念就是統(tǒng)統(tǒng)一條方法解決一個(gè)問(wèn)題,那么,這時(shí)候上面的都不要再去看了,什么鬼東西,只需要在你的BaseActivity或者BaseFragment中添加幾行我的下面的代碼,然后調(diào)用的時(shí)候,就是一行代碼搞定。(上面的部分統(tǒng)統(tǒng)略去,下面的才是今天的主要)

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

private int mPermissionIdx = 0x10;//請(qǐng)求權(quán)限索引

private SparseArray mPermissions = new SparseArray<>();//請(qǐng)求權(quán)限運(yùn)行列表

@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);

/*

是否需要請(qǐng)求權(quán)限

*/

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;

}

/*

是否需要請(qǐng)求彈出窗

*/

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);

}

}

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

比如說(shuō)你需要點(diǎn)擊一下拍照按鈕就打開(kāi)系統(tǒng)的攝像頭進(jìn)行拍照,那么就在你打開(kāi)按鈕的監(jiān)聽(tīng)事件中這么寫:(比如說(shuō)是在CarmerActivity中,繼承BaseActivity)

openCarmer.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

requestPermission(new String[]{Manifest.permission.CAMERA}, “請(qǐng)求設(shè)備相機(jī)權(quán)限”, new GrantedResult() {

@Override

public void onResult(boolean granted) {

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

createLocalStream();

}else {//用戶拒絕

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

}

}

});

}

});

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

ok,大功告成!!!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容