詳解Android許可權管理之Android 6.0運行時許可權及解決辦法_Android

來源:互聯網
上載者:User

前言:

今天還是圍繞著最近面試的一個熱門話題Android 6.0許可權適配來總結學習,其實Android 6.0許可權適配我們公司是在今年5月份才開始做,算是比較晚的吧,不過現在Android 6.0以上裝置越來越多了,所以Android 6.0 許可權適配是必不可少的工作,這裡主要介紹一下我們公司是如何做Android 6.0許可權適配的。

Android 6.0以下非運行時許可權:

根據上面部落格我們很清楚的知道,Android的許可權其實就是為了程式之間更加的安全的訪問,所以許可權有等級之分,比如:Normal 低風險許可權 、Dangerous  高風險許可權等,雖然有這種安全意識,但是這些許可權只會在安裝的時候被詢問一次,一旦安裝之後,如果app申請了高風險許可權的話,而且大部分使用者在安裝的時候很少去關注這些許可權列表,再加上很多Android市場都有靜默安裝的功能使用者更加感知不到任何許可權提示,就這樣app就有可能會在後台做一些對使用者帶來傷害的事情。如下圖所示:

Android6.0運行時許可權:

鑒於6.0之前的版本許可權管理相對不那麼安全,所以Android 6.0 採用新的許可權模型,只有在需要許可權的時候,才告知使用者是否授權,是在runtime時候授權,而不是在原來安裝的時候 ,同時預設情況下每次在運行時開啟頁面時候,需要先檢查是否有所需要的許可權申請。這樣的使用者的自主性提高很多,比如使用者可以給APP賦予攝像的許可權,也可以使用許可權。
 

Android 6.0許可權適配:

1.)不進行適配造成的現象

先看下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 以上的許可權變成了運行時許可權,也就是說在需要使用某個許可權的時候必須動態去申請使用,直接存取直接導致app崩潰。

2.)早期的解決辦法 

其實判斷是否是需要運行時許可權的標記就是targetSDKVersion,當targetSDKVersion<23的時候,僅在安裝時賦予許可權,使用時將不被提醒,當targetSDKVersion≥23的時候才會使用新的運行時許可權規則。所有在最早遇見因許可權未適配的導致的崩潰的時候,我們團隊採用的解決辦法是將targetSDKVersion人為的降到小於23,這樣就變成了還是預設使用許可權,但是這種並不是Google所推薦使用的。

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

3.)判斷是否擁有該許可權的使用許可權

檢查是否擁有使用權

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

判斷是否是Android 6.0以上

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

是否申請了該使用許可權

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

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

4.)申請使用許可權

private void requestPermission(String permission, int requestCode) {  if (!isGranted(permission)) {   if (ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) {   } else {    ActivityCompat.requestPermissions(this, new String[]{permission}, requestCode);   }  } else {   //直接執行相應操作了  } }

shouldShowRequestPermissionRationale主要用於給使用者一個申請許可權的解釋,該方法只有在使用者在上一次已經拒絕過你的這個許可權申請。也就是說,使用者已經拒絕一次了,你又彈個授權框,你需要給使用者一個解釋,為什麼要授權,則使用該方法。requestCode這個需要在處理的回調的時候 一一對應的。

5.)處理授權回調

@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, "您沒有授權該許可權,請在設定中開啟授權", 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);   }  }); } /**  * 拍照,返回拍照檔案的絕對路徑  */ 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主要用於給使用者一個申請許可權的解釋,該方法只有在使用者在上一次已經拒絕過你的這個許可權申請。也就是說,使用者已經拒絕一次了,你又彈個授權框,你需要給使用者一個解釋,為什麼要授權,則使用該方法。 private void requestPermission(String permission, int requestCode) {  if (!isGranted(permission)) {   if (ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) {   } else {    ActivityCompat.requestPermissions(this, new String[]{permission}, requestCode);   }  } else {   //直接執行相應操作了  } } @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, "您沒有授權該許可權,請在設定中開啟授權", Toast.LENGTH_SHORT).show();   }   return;  }  super.onRequestPermissionsResult(requestCode, permissions, grantResults); }}

總結:

本篇總結學習了Android 6.0的運行時許可權及如何適配的問題,但是這個並不是我們公司目前最終的解決辦法,從上面可以看出實現起來還是蠻麻煩的,申請許可權和處理回調在不同的地方代碼可讀性相對較差,我們最終的解決方案是採用RxJava+RxPermission的方式解決,下一篇將介紹一下如何使用RxPermission解決Android 6.0 許可權適配問題。

以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支援雲棲社區。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.