android 6.0以上爲了保護用戶的隱私,和以往被人詬病的權限機制,確立了新的權限機制。從 Android 6.0(API 級別 23)開始,用戶開始在應用運行時向其授予權限,而不是在應用安裝時授予。此方法能夠簡化應用安裝過程,由於用戶在安裝或更新應用時不須要授予權限。它還讓用戶能夠對應用的功能進行更多控制;例如,用戶能夠選擇爲相機應用提供相機訪問權限,而不提供設備位置的訪問權限。用戶能夠隨時進入應用的「Settings」屏幕調用權限。html
谷歌將權限分兩類:1.正常權限。2.危險權限。java
正常權限:android
危險權限:app
那麼對於一個應用要關注的就是那些危險權限,也就是咱們所說的敏感權限。下表列出來有關的危險權限。工具
權限名稱 |
1.calendar |
2.camera |
3.contacts |
4.location |
5.microphone |
6.phone |
7.senors |
8.sms |
9.storage |
兼容性來講,有如下細節:ui
1.低於API23 也就是系統6.0如下的,在manifest中註冊申明權限清單,則自動授予權限,可是用戶能夠去設置中心關閉權限,可是不會引發應用運行異常code
2.API23系統6.0以上的,須要在使用的時候去申請,沒有申請就去使用則會引發應用運行異常。權限失效會致使 SecurityException
。htm
3.一開始是6.0如下系統應用,作了動態權限之後,會自動授予原先已有的權限,若是有新增的危險權限,須要作申請。blog
4.一開始就作了動態權限,再換回到6.0如下編譯環境,新的apk沒法安裝。get
下面以一個流程圖說明問題。
危險權限的表單以下:
申請權限的工具類以下:
package com.nfdaily.nfplus.util; import android.Manifest; import android.app.Activity; import android.content.pm.PackageManager; import android.os.Build; import android.support.v4.app.ActivityCompat; /** * Created by xilinch on 2017/5/3. * 對關鍵的權限進行申請 calendar /camera/ contacts/location/microphone /phone/senors/sms/storage * 增長對版本號的判斷,大於等於23 (6.0)以上才進行權限的申請 */ public class UtilRequestPermissions { /** * 撥打電話的請求碼 */ public static final int REQUEST_CODE_CALL_PHONE = 0x9001; /** * 存儲 */ public static final int REQUEST_CODE_READ_EXTERNAL_STORAGE = 0x9002; /** * 發送短信 */ public static final int REQUEST_CODE_SEND_SMS = 0x9003; /** * 傳感器 */ public static final int REQUEST_CODE_BODY_SENSORS = 0x9004; /** * 錄音 */ public static final int REQUEST_CODE_RECORD_AUDIO = 0x9005; /** * 定位 */ public static final int REQUEST_CODE_ACCESS_COARSE_LOCATION = 0x9006; /** * 相機 */ public static final int REQUEST_CODE_CAMERA = 0x9007; /** * 讀取日曆 */ public static final int REQUEST_CODE_READ_CALENDAR = 0x9008; /** * 錄音 */ public static final int REQUEST_CODE_READ_CONTACTS = 0x9009; /** * 請求權限 * @param activity * @param permission * @param requestCode */ public static void requestPermission(Activity activity, String[] permission, int requestCode){ ActivityCompat.requestPermissions(activity, permission, requestCode); } /** * 檢查權限 * @param activity * @param permission * @return */ public static boolean checkSelfPermission(Activity activity, String permission){ boolean isGranted = ActivityCompat.checkSelfPermission(activity, permission) == PackageManager.PERMISSION_GRANTED; return isGranted; } /** * 日曆 * @param activity * @param requestCode */ public static void requestPermissionCalendar(Activity activity,int requestCode){ if(Build.VERSION.SDK_INT >= 23){ if(requestCode == 0){ requestPermission(activity, new String[]{Manifest.permission.READ_CALENDAR}, REQUEST_CODE_READ_CALENDAR); } else { requestPermission(activity, new String[]{Manifest.permission.READ_CALENDAR}, requestCode); } } } /** * 照相 * @param activity * @param requestCode */ public static void requestPermissionCamera(Activity activity,int requestCode){ if(Build.VERSION.SDK_INT >= 23){ if(requestCode == 0){ requestPermission(activity, new String[]{Manifest.permission.CAMERA}, REQUEST_CODE_CAMERA); } else { requestPermission(activity, new String[]{Manifest.permission.CAMERA}, requestCode); } } } /** * 聯繫人 * @param activity * @param requestCode */ public static void requestPermissionContacts(Activity activity,int requestCode){ if(Build.VERSION.SDK_INT >= 23){ if(requestCode == 0){ requestPermission(activity, new String[]{Manifest.permission.READ_CONTACTS}, REQUEST_CODE_READ_CONTACTS); } else { requestPermission(activity, new String[]{Manifest.permission.READ_CONTACTS}, requestCode); } } } /** * 定位 * @param activity * @param requestCode */ public static void requestPermissionLocation(Activity activity,int requestCode){ if(Build.VERSION.SDK_INT >= 23){ if(requestCode == 0){ requestPermission(activity, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_CODE_ACCESS_COARSE_LOCATION); } else { requestPermission(activity, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, requestCode); } } } /** * 錄音 * @param activity * @param requestCode */ public static void requestPermissionMicrophone(Activity activity,int requestCode){ if(Build.VERSION.SDK_INT >= 23){ if(requestCode == 0){ requestPermission(activity, new String[]{Manifest.permission.RECORD_AUDIO}, REQUEST_CODE_RECORD_AUDIO); } else { requestPermission(activity, new String[]{Manifest.permission.RECORD_AUDIO}, requestCode); } } } /** * 傳感器 * @param activity * @param requestCode */ public static void requestPermissionSensors(Activity activity,int requestCode){ if(Build.VERSION.SDK_INT >= 23){ if(requestCode == 0){ requestPermission(activity, new String[]{Manifest.permission.BODY_SENSORS}, REQUEST_CODE_BODY_SENSORS); } else { requestPermission(activity, new String[]{Manifest.permission.BODY_SENSORS}, requestCode); } } } /** * 短信 * @param activity * @param requestCode */ public static void requestPermissionSms(Activity activity,int requestCode){ if(Build.VERSION.SDK_INT >= 23){ if(requestCode == 0){ requestPermission(activity, new String[]{Manifest.permission.SEND_SMS}, REQUEST_CODE_SEND_SMS); } else { requestPermission(activity, new String[]{Manifest.permission.SEND_SMS}, requestCode); } } } /** * 存儲 * @param activity * @param requestCode */ public static void requestPermissionStorage(Activity activity,int requestCode){ if(Build.VERSION.SDK_INT >= 23){ if(requestCode == 0){ requestPermission(activity, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_CODE_READ_EXTERNAL_STORAGE); } else { requestPermission(activity, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, requestCode); } } } /** * 電話 有關,包括READ_PHONE_STATE /CALL_PHONE /READ_CALL_LOG/WRTITE_CALL_LOG/ADD_VOICEMAIL/USE_SIP/PROCESS_OUTGOING_CALLS * @param activity * @param requestCode */ public static void requestPermissionPhone(Activity activity,int requestCode){ if(Build.VERSION.SDK_INT >= 23){ if(requestCode == 0){ requestPermission(activity, new String[]{Manifest.permission.READ_PHONE_STATE}, REQUEST_CODE_CALL_PHONE); } else { requestPermission(activity, new String[]{Manifest.permission.READ_PHONE_STATE}, requestCode); } } } }
在下一部分將描述項目中實際處理的狀況以及對比京東和淘寶的處理方案。