http://blog.csdn.net/qq_34767498/article/details/51814669
Android 6.0 運(yùn)行時(shí)權(quán)限簡(jiǎn)潔封裝
寫(xiě)在前面:
Android M 中有一個(gè)比較重要的知識(shí)點(diǎn)就是運(yùn)行時(shí)權(quán)限了,關(guān)于運(yùn)行時(shí)權(quán)限的文章和封裝庫(kù)目前也出現(xiàn)了不少,在開(kāi)發(fā)的過(guò)程中始終覺(jué)得運(yùn)行時(shí)權(quán)限這塊的代碼可以進(jìn)一步封裝一下,讓其使用起來(lái)能再簡(jiǎn)潔一點(diǎn),并且還不容易出錯(cuò)。關(guān)于 Android 運(yùn)行時(shí)權(quán)限的知識(shí)就不多講解了,可以參考下面的一些資料:
Android 6.0 運(yùn)行時(shí)權(quán)限處理完全解析
知識(shí)點(diǎn)比較簡(jiǎn)單,大致了解和使用過(guò)后,就來(lái)開(kāi)始我的這次封裝之旅吧。
現(xiàn)在直觀的看看封裝之后的使用,是不是清爽很多?
@OnClick(R.id.tv_toolbar_right)publicvoidonClick(){? ? ? ? performRequestPermissions(getString(R.string.permission_desc),newString[]{Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION}? ? ? ? ? ? ? ? , PER_REQUEST_CODE,newPermissionsResultListener() {@OverridepublicvoidonPermissionGranted(){? ? ? ? ? ? ? ? ? ? ? ? Toast.makeText(MainActivity.this,"已申請(qǐng)權(quán)限", Toast.LENGTH_LONG).show();? ? ? ? ? ? ? ? ? ? }@OverridepublicvoidonPermissionDenied(){? ? ? ? ? ? ? ? ? ? ? ? Toast.makeText(MainActivity.this,"拒絕申請(qǐng)權(quán)限", Toast.LENGTH_LONG).show();? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? });? ? }
我將運(yùn)行時(shí)權(quán)限封裝到 BaseActivity 中,MainActivty 繼承BaseActivity,調(diào)用 performRequestPermissions 方法,此時(shí)我不用再去做一些判斷,只需要穿入四個(gè)參數(shù)即可。當(dāng)然你為了在 6.0 以下保證應(yīng)用正常運(yùn)行,你依然需要像以前一樣,在清單文件中申明要使用的權(quán)限。
首先我需要一個(gè)接口做通信:
publicinterfacePermissionsResultListener{voidonPermissionGranted();voidonPermissionDenied();}
然后把邏輯代碼封裝在 BaseActivity 里面:
publicclassBaseActivityextendsAppCompatActivity{privatePermissionsResultListener mListener;privateintmRequestCode;/**? ? * 其他 Activity 繼承 BaseActivity 調(diào)用 performRequestPermissions 方法? ? *? ? *@paramdesc? ? ? ? 首次申請(qǐng)權(quán)限被拒絕后再次申請(qǐng)給用戶的描述提示? ? *@parampermissions 要申請(qǐng)的權(quán)限數(shù)組? ? *@paramrequestCode 申請(qǐng)標(biāo)記值? ? *@paramlistener? ? 實(shí)現(xiàn)的接口? ? */protectedvoidperformRequestPermissions(String desc, String[] permissions,intrequestCode, PermissionsResultListener listener){if(permissions ==null|| permissions.length ==0) {return;? ? ? ? }? ? ? ? mRequestCode = requestCode;? ? ? ? mListener = listener;if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {if(checkEachSelfPermission(permissions)) {// 檢查是否聲明了權(quán)限r(nóng)equestEachPermissions(desc, permissions, requestCode);? ? ? ? ? ? }else{// 已經(jīng)申請(qǐng)權(quán)限if(mListener !=null) {? ? ? ? ? ? ? ? ? ? mListener.onPermissionGranted();? ? ? ? ? ? ? ? }? ? ? ? ? ? }? ? ? ? }else{if(mListener !=null) {? ? ? ? ? ? ? ? mListener.onPermissionGranted();? ? ? ? ? ? }? ? ? ? }? ? }/**? ? * 申請(qǐng)權(quán)限前判斷是否需要聲明? ? *? ? *@paramdesc? ? *@parampermissions? ? *@paramrequestCode? ? */privatevoidrequestEachPermissions(String desc, String[] permissions,intrequestCode){if(shouldShowRequestPermissionRationale(permissions)) {// 需要再次聲明showRationaleDialog(desc, permissions, requestCode);? ? ? ? }else{? ? ? ? ? ? ActivityCompat.requestPermissions(BaseActivity.this, permissions, requestCode);? ? ? ? }? ? }/**? ? * 彈出聲明的 Dialog? ? *? ? *@paramdesc? ? *@parampermissions? ? *@paramrequestCode? ? */privatevoidshowRationaleDialog(String desc,finalString[] permissions,finalintrequestCode){finalAlertDialog.Builder builder =newAlertDialog.Builder(this);? ? ? ? builder.setTitle(getString(R.string.tips))? ? ? ? ? ? ? ? .setMessage(desc)? ? ? ? ? ? ? ? .setPositiveButton(getResources().getString(R.string.confrim),newDialogInterface.OnClickListener() {@OverridepublicvoidonClick(DialogInterface dialogInterface,inti){? ? ? ? ? ? ? ? ? ? ? ? ActivityCompat.requestPermissions(BaseActivity.this, permissions, requestCode);? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? })? ? ? ? ? ? ? ? .setNegativeButton(getResources().getString(R.string.cancle),newDialogInterface.OnClickListener() {@OverridepublicvoidonClick(DialogInterface dialogInterface,inti){? ? ? ? ? ? ? ? ? ? ? ? dialogInterface.dismiss();? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? })? ? ? ? ? ? ? ? .setCancelable(false)? ? ? ? ? ? ? ? .show();? ? }/**? ? * 再次申請(qǐng)權(quán)限時(shí),是否需要聲明? ? *? ? *@parampermissions? ? *@return*/privatebooleanshouldShowRequestPermissionRationale(String[] permissions){for(String permission : permissions) {if(ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) {returntrue;? ? ? ? ? ? }? ? ? ? }returnfalse;? ? }/**? ? * 檢察每個(gè)權(quán)限是否申請(qǐng)? ? *? ? *@parampermissions? ? *@returntrue 需要申請(qǐng)權(quán)限,false 已申請(qǐng)權(quán)限? ? */privatebooleancheckEachSelfPermission(String[] permissions){for(String permission : permissions) {if(ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {returntrue;? ? ? ? ? ? }? ? ? ? }returnfalse;? ? }/**? ? * 申請(qǐng)權(quán)限結(jié)果的回調(diào)? ? *? ? *@paramrequestCode? ? *@parampermissions? ? *@paramgrantResults? ? */@OverridepublicvoidonRequestPermissionsResult(intrequestCode, @NonNull String[] permissions, @NonNullint[] grantResults){super.onRequestPermissionsResult(requestCode, permissions, grantResults);if(requestCode == mRequestCode) {if(checkEachPermissionsGranted(grantResults)) {if(mListener !=null) {? ? ? ? ? ? ? ? ? ? mListener.onPermissionGranted();? ? ? ? ? ? ? ? }? ? ? ? ? ? }else{// 用戶拒絕申請(qǐng)權(quán)限if(mListener !=null) {? ? ? ? ? ? ? ? ? ? mListener.onPermissionDenied();? ? ? ? ? ? ? ? }? ? ? ? ? ? }? ? ? ? }? ? }/**? ? * 檢查回調(diào)結(jié)果? ? *? ? *@paramgrantResults? ? *@return*/privatebooleancheckEachPermissionsGranted(int[] grantResults){for(intresult : grantResults) {if(result != PackageManager.PERMISSION_GRANTED) {returnfalse;? ? ? ? ? ? }? ? ? ? }returntrue;? ? }}
每一個(gè)方法都有注釋,邏輯也相對(duì)簡(jiǎn)單,就是我會(huì)遍歷每個(gè)數(shù)組中申請(qǐng)的權(quán)限,如果需要申請(qǐng)就去申請(qǐng),然后再處理一下回調(diào)的結(jié)果,其中還有對(duì)用戶拒絕,然后再次申請(qǐng)彈出 Dialog 的處理。
如果在 Fragment 中使用,只是改變了一下參數(shù)封到 BaseFragment 中,這里就不貼代碼了,都已經(jīng)上傳github
BaseActivity:
BaseFragment:
如有問(wèn)題,繼續(xù)交流~