亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

詳解Android權(quán)限管理之Android 6.0運(yùn)行時(shí)權(quán)限及解決辦法

 更新時(shí)間:2016年11月23日 15:05:08   作者:總李寫代碼  
本篇文章主要介紹Android權(quán)限管理之Android 6.0運(yùn)行時(shí)權(quán)限及解決辦法,具有一定的參考價(jià)值,有興趣的可以了解一下。

前言:

今天還是圍繞著最近面試的一個(gè)熱門話題Android 6.0權(quán)限適配來(lái)總結(jié)學(xué)習(xí),其實(shí)Android 6.0權(quán)限適配我們公司是在今年5月份才開始做,算是比較晚的吧,不過(guò)現(xiàn)在Android 6.0以上設(shè)備越來(lái)越多了,所以Android 6.0 權(quán)限適配是必不可少的工作,這里主要介紹一下我們公司是如何做Android 6.0權(quán)限適配的。

Android 6.0以下非運(yùn)行時(shí)權(quán)限:

根據(jù)上面博客我們很清楚的知道,Android的權(quán)限其實(shí)就是為了程序之間更加的安全的訪問(wèn),所以權(quán)限有等級(jí)之分,比如:Normal 低風(fēng)險(xiǎn)權(quán)限 、Dangerous  高風(fēng)險(xiǎn)權(quán)限等,雖然有這種安全意識(shí),但是這些權(quán)限只會(huì)在安裝的時(shí)候被詢問(wèn)一次,一旦安裝之后,如果app申請(qǐng)了高風(fēng)險(xiǎn)權(quán)限的話,而且大部分用戶在安裝的時(shí)候很少去關(guān)注這些權(quán)限列表,再加上很多Android市場(chǎng)都有靜默安裝的功能用戶更加感知不到任何權(quán)限提示,就這樣app就有可能會(huì)在后臺(tái)做一些對(duì)用戶帶來(lái)傷害的事情。如下圖所示:

Android6.0運(yùn)行時(shí)權(quán)限:

鑒于6.0之前的版本權(quán)限管理相對(duì)不那么安全,所以Android 6.0 采用新的權(quán)限模型,只有在需要權(quán)限的時(shí)候,才告知用戶是否授權(quán),是在runtime時(shí)候授權(quán),而不是在原來(lái)安裝的時(shí)候 ,同時(shí)默認(rèn)情況下每次在運(yùn)行時(shí)打開頁(yè)面時(shí)候,需要先檢查是否有所需要的權(quán)限申請(qǐng)。這樣的用戶的自主性提高很多,比如用戶可以給APP賦予攝像的權(quán)限,也可以使用權(quán)限。
 

Android 6.0權(quán)限適配:

1.)不進(jìn)行適配造成的現(xiàn)象

先看下app module的build.gradle配置

 compileSdkVersion 24
 buildToolsVersion "24.0.2"
 defaultConfig {
  applicationId "com.whoislcj.rxpermissions"
  minSdkVersion 15
  targetSdkVersion 24
  versionCode 1
  versionName "1.0"
 }

由于Android 6.0 以上的權(quán)限變成了運(yùn)行時(shí)權(quán)限,也就是說(shuō)在需要使用某個(gè)權(quán)限的時(shí)候必須動(dòng)態(tài)去申請(qǐng)使用,直接訪問(wèn)直接導(dǎo)致app崩潰。

2.)早期的解決辦法 

其實(shí)判斷是否是需要運(yùn)行時(shí)權(quán)限的標(biāo)記就是targetSDKVersion,當(dāng)targetSDKVersion<23的時(shí)候,僅在安裝時(shí)賦予權(quán)限,使用時(shí)將不被提醒,當(dāng)targetSDKVersion≥23的時(shí)候才會(huì)使用新的運(yùn)行時(shí)權(quán)限規(guī)則。所有在最早遇見(jiàn)因權(quán)限未適配的導(dǎo)致的崩潰的時(shí)候,我們團(tuán)隊(duì)采用的解決辦法是將targetSDKVersion人為的降到小于23,這樣就變成了還是默認(rèn)使用權(quán)限,但是這種并不是Google所推薦使用的。

 compileSdkVersion 24
 buildToolsVersion "24.0.2"
 defaultConfig {
  applicationId "com.whoislcj.rxpermissions"
  minSdkVersion 15
  targetSdkVersion 22
  versionCode 1
  versionName "1.0"
 }

3.)判斷是否擁有該權(quán)限的使用權(quán)限

檢查是否擁有使用權(quán)

 public boolean isGranted(String permission) {
  return !isMarshmallow() || isGranted_(permission);
 }

判斷是否是Android 6.0以上

 private boolean isMarshmallow() {
  return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
 }

是否申請(qǐng)了該使用權(quán)限

 private boolean isGranted_(String permission) {
  int checkSelfPermission = ActivityCompat.checkSelfPermission(this, permission);
  return checkSelfPermission == PackageManager.PERMISSION_GRANTED;
 }

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

4.)申請(qǐng)使用權(quán)限

private void requestPermission(String permission, int requestCode) {
  if (!isGranted(permission)) {
   if (ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) {

   } else {
    ActivityCompat.requestPermissions(this, new String[]{permission}, requestCode);
   }
  } else {
   //直接執(zhí)行相應(yīng)操作了
  }
 }

shouldShowRequestPermissionRationale主要用于給用戶一個(gè)申請(qǐng)權(quán)限的解釋,該方法只有在用戶在上一次已經(jīng)拒絕過(guò)你的這個(gè)權(quán)限申請(qǐng)。也就是說(shuō),用戶已經(jīng)拒絕一次了,你又彈個(gè)授權(quán)框,你需要給用戶一個(gè)解釋,為什么要授權(quán),則使用該方法。requestCode這個(gè)需要在處理的回調(diào)的時(shí)候 一一對(duì)應(yīng)的。

5.)處理授權(quán)回調(diào)

@Override
 public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
  if (requestCode == CAMERA) {
   if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
    String jpgPath = getCacheDir() + "test.jpg";
    takePhotoByPath(jpgPath, 2);
   } else {
    // Permission Denied
    Toast.makeText(MainActivity.this, "您沒(méi)有授權(quán)該權(quán)限,請(qǐng)?jiān)谠O(shè)置中打開授權(quán)", Toast.LENGTH_SHORT).show();
   }
   return;
  }
  super.onRequestPermissionsResult(requestCode, permissions, grantResults);
 }

6.)完整的Activity示例
 

public class MainActivity extends AppCompatActivity {
 private static final int CAMERA = 2;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  findViewById(R.id.request_permission).setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
    requestPermission(Manifest.permission.CAMERA, CAMERA);
   }
  });
 }

 /**
  * 拍照,返回拍照文件的絕對(duì)路徑
  */
 private String takePhotoByPath(String filePath, int requestCode) {
  File file = new File(filePath);
  startActivityForResult(getTakePhotoIntent(file), requestCode);
  return file.getPath();
 }

 private Intent getTakePhotoIntent(File file) {
  if (file.exists()) {
   file.delete();
  }

  try {
   file.createNewFile();
  } catch (IOException e) {
   e.printStackTrace();
  }

  Uri uri = Uri.fromFile(file);
  Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
  intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
  return intent;
 }

 public boolean isGranted(String permission) {
  return !isMarshmallow() || isGranted_(permission);
 }

 private boolean isGranted_(String permission) {
  int checkSelfPermission = ActivityCompat.checkSelfPermission(this, permission);
  return checkSelfPermission == PackageManager.PERMISSION_GRANTED;
 }

 private boolean isMarshmallow() {
  return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
 }

 //shouldShowRequestPermissionRationale主要用于給用戶一個(gè)申請(qǐng)權(quán)限的解釋,該方法只有在用戶在上一次已經(jīng)拒絕過(guò)你的這個(gè)權(quán)限申請(qǐng)。也就是說(shuō),用戶已經(jīng)拒絕一次了,你又彈個(gè)授權(quán)框,你需要給用戶一個(gè)解釋,為什么要授權(quán),則使用該方法。
 private void requestPermission(String permission, int requestCode) {
  if (!isGranted(permission)) {
   if (ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) {

   } else {
    ActivityCompat.requestPermissions(this, new String[]{permission}, requestCode);
   }
  } else {
   //直接執(zhí)行相應(yīng)操作了
  }
 }

 @Override
 public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
  if (requestCode == CAMERA) {
   if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
    String jpgPath = getCacheDir() + "test.jpg";
    takePhotoByPath(jpgPath, 2);
   } else {
    // Permission Denied
    Toast.makeText(MainActivity.this, "您沒(méi)有授權(quán)該權(quán)限,請(qǐng)?jiān)谠O(shè)置中打開授權(quán)", Toast.LENGTH_SHORT).show();
   }
   return;
  }
  super.onRequestPermissionsResult(requestCode, permissions, grantResults);
 }

}

總結(jié):

本篇總結(jié)學(xué)習(xí)了Android 6.0的運(yùn)行時(shí)權(quán)限及如何適配的問(wèn)題,但是這個(gè)并不是我們公司目前最終的解決辦法,從上面可以看出實(shí)現(xiàn)起來(lái)還是蠻麻煩的,申請(qǐng)權(quán)限和處理回調(diào)在不同的地方代碼可讀性相對(duì)較差,我們最終的解決方案是采用RxJava+RxPermission的方式解決,下一篇將介紹一下如何使用RxPermission解決Android 6.0 權(quán)限適配問(wèn)題。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論