Android 6.0 運行時許可權處理完全解析

来源:http://www.cnblogs.com/8hao/archive/2016/03/04/5241924.html
-Advertisement-
Play Games

一、概述 隨著Android 6.0發佈以及普及,我們開發者所要應對的主要就是新版本SDK帶來的一些變化,首先關註的就是許可權機制的變化。對於6.0的幾個主要的變化,查看查看官網的這篇文章http://developer.android.com/intl/zh-cn/about/versions/ma


一、概述

隨著Android 6.0發佈以及普及,我們開發者所要應對的主要就是新版本SDK帶來的一些變化,首先關註的就是許可權機制的變化。對於6.0的幾個主要的變化,查看查看官網的這篇文章http://developer.android.com/intl/zh-cn/about/versions/marshmallow/android-6.0-changes.html,其中當然包含Runtime Permissions

ok,本篇文章目的之一就是對運行時許可權處理的一個介紹,以及對目前許可權相關的庫的一些瞭解。

當然非常推薦閱讀官網許可權相關文章:

本文也是在上述文章基礎上理解、實驗以及封裝。

二、運行時許可權的變化及特點

對於6.0以下的許可權及在安裝的時候,根據許可權聲明產生一個許可權列表,用戶只有在同意之後才能完成app的安裝,造成了我們想要使用某個app,就要默默忍受其一些不必要的許可權(比如是個app都要訪問通訊錄、簡訊等)。而在6.0以後,我們可以直接安裝,當app需要我們授予不恰當的許可權的時候,我們可以予以拒絕(比如:單機的象棋對戰,請求訪問任何許可權,我都是不同意的)。當然你也可以在設置界面對每個app的許可權進行查看,以及對單個許可權進行授權或者解除授權。

新的許可權機制更好的保護了用戶的隱私,Google將許可權分為兩類,一類是Normal Permissions,這類許可權一般不涉及用戶隱私,是不需要用戶進行授權的,比如手機震動、訪問網路等;另一類是Dangerous Permission,一般是涉及到用戶隱私的,需要用戶進行授權,比如讀取sdcard、訪問通訊錄等。

  • Normal Permissions如下

 

          Java  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 ACCESS_LOCATION_EXTRA_COMMANDS ACCESS_NETWORK_STATE ACCESS_NOTIFICATION_POLICY ACCESS_WIFI_STATE BLUETOOTH BLUETOOTH_ADMIN BROADCAST_STICKY CHANGE_NETWORK_STATE CHANGE_WIFI_MULTICAST_STATE CHANGE_WIFI_STATE DISABLE_KEYGUARD EXPAND_STATUS_BAR GET_PACKAGE_SIZE INSTALL_SHORTCUT INTERNET KILL_BACKGROUND_PROCESSES MODIFY_AUDIO_SETTINGS NFC READ_SYNC_SETTINGS READ_SYNC_STATS RECEIVE_BOOT_COMPLETED REORDER_TASKS REQUEST_INSTALL_PACKAGES SET_ALARM SET_TIME_ZONE SET_WALLPAPER SET_WALLPAPER_HINTS TRANSMIT_IR UNINSTALL_SHORTCUT USE_FINGERPRINT VIBRATE WAKE_LOCK WRITE_SYNC_SETTINGS

 

  • Dangerous Permissions:

 

          Java  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 group:android.permission-group.CONTACTS   permission:android.permission.WRITE_CONTACTS   permission:android.permission.GET_ACCOUNTS   permission:android.permission.READ_CONTACTS   group:android.permission-group.PHONE   permission:android.permission.READ_CALL_LOG   permission:android.permission.READ_PHONE_STATE   permission:android.permission.CALL_PHONE   permission:android.permission.WRITE_CALL_LOG   permission:android.permission.USE_SIP   permission:android.permission.PROCESS_OUTGOING_CALLS   permission:com.android.voicemail.permission.ADD_VOICEMAIL   group:android.permission-group.CALENDAR   permission:android.permission.READ_CALENDAR   permission:android.permission.WRITE_CALENDAR   group:android.permission-group.CAMERA   permission:android.permission.CAMERA   group:android.permission-group.SENSORS   permission:android.permission.BODY_SENSORS   group:android.permission-group.LOCATION   permission:android.permission.ACCESS_FINE_LOCATION   permission:android.permission.ACCESS_COARSE_LOCATION   group:android.permission-group.STORAGE   permission:android.permission.READ_EXTERNAL_STORAGE   permission:android.permission.WRITE_EXTERNAL_STORAGE   group:android.permission-group.MICROPHONE   permission:android.permission.RECORD_AUDIO   group:android.permission-group.SMS   permission:android.permission.READ_SMS   permission:android.permission.RECEIVE_WAP_PUSH   permission:android.permission.RECEIVE_MMS   permission:android.permission.RECEIVE_SMS   permission:android.permission.SEND_SMS   permission:android.permission.READ_CELL_BROADCASTS

可以通過adb shell pm list permissions -d -g進行查看。

看到上面的dangerous permissions,會發現一個問題,好像危險許可權都是一組一組的,恩,沒錯,的確是這樣的,

那麼有個問題:分組對我們的許可權機制有什麼影響嗎?

的確是有影響的,如果app運行在Android 6.x的機器上,對於授權機制是這樣的。如果你申請某個危險的許可權,假設你的app早已被用戶授權了同一組的某個危險許可權,那麼系統會立即授權,而不需要用戶去點擊授權。比如你的app對READ_CONTACTS已經授權了,當你的app申請WRITE_CONTACTS時,系統會直接授權通過。此外,對於申請時彈出的dialog上面的文本說明也是對整個許可權組的說明,而不是單個許可權(ps:這個dialog是不能進行定製的)。

不過需要註意的是,不要對許可權組過多的依賴,儘可能對每個危險許可權都進行正常流程的申請,因為在後期的版本中這個許可權組可能會產生變化。

三、相關API

好在運行時相關的API也比較簡單,所以適配起來並不會非常痛苦。

API的講解就跟著申請許可權步驟一起了:

  1. 在AndroidManifest文件中添加需要的許可權。這個步驟和我們之前的開發並沒有什麼變化,試圖去申請一個沒有聲明的許可權可能會導致程式崩潰。
  2. 檢查許可權
              Java  
    1 2 3 4 5 6 if (ContextCompat.checkSelfPermission(thisActivity,                 Manifest.permission.READ_CONTACTS)         != PackageManager.PERMISSION_GRANTED) { }else{     // }

    這裡涉及到一個API,ContextCompat.checkSelfPermission,主要用於檢測某個許可權是否已經被授予,方法返回值為PackageManager.PERMISSION_DENIED或者PackageManager.PERMISSION_GRANTED。當返回DENIED就需要進行申請授權了。
  3. 申請授權
              Java  
    1 2 3 ActivityCompat.requestPermissions(thisActivity,                 new String[]{Manifest.permission.READ_CONTACTS},                 MY_PERMISSIONS_REQUEST_READ_CONTACTS);

    該方法是非同步的,第一個參數是Context;第二個參數是需要申請的許可權的字元串數組;第三個參數為requestCode,主要用於回調的時候檢測。可以從方法名requestPermissions以及第二個參數看出,是支持一次性申請多個許可權的,系統會通過對話框逐一詢問用戶是否授權。
  4. 處理許可權申請回調
                Java  
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 @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;         }     } }

    ok,對於許可權的申請結果,首先驗證requestCode定位到你的申請,然後驗證grantResults對應於申請的結果,這裡的數組對應於申請時的第二個許可權字元串數組。如果你同時申請兩個許可權,那麼grantResults的length就為2,分別記錄你兩個許可權的申請結果。如果申請成功,就可以做你的事情了~

當然,到此我們的許可權申請的不走,基本介紹就如上述。不過還有個API值得提一下:

          Java  
1 2 3 4 5 6 7 8 // Should we show an explanation? if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,         Manifest.permission.READ_CONTACTS))     // Show an expanation to the user *asynchronously* -- don't block     // this thread waiting for the user's response! After the user     // sees the explanation, try again to request the permission.   }

這個API主要用於給用戶一個申請許可權的解釋,該方法只有在用戶在上一次已經拒絕過你的這個許可權申請。也就是說,用戶已經拒絕一次了,你又彈個授權框,你需要給用戶一個解釋,為什麼要授權,則使用該方法。

那麼將上述幾個步驟結合到一起就是:

            Java  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 // Here, thisActivity is the current activity if (ContextCompat.checkSelfPermission(thisActivity,                 Manifest.permission.READ_CONTACTS)         != PackageManager.PERMISSION_GRANTED) {       // Should we show an explanation?     if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,             Manifest.permission.READ_CONTACTS)) {           // Show an expanation to the user *asynchronously* -- don't block         // this thread waiting for the user's response! After the user         // sees the explanation, try again to request the permission.       } else {           // No explanation needed, we can request the permission.           ActivityCompat.requestPermissions(thisActivity,                 new String[]{Manifest.permission.READ_CONTACTS},                 MY_PERMISSIONS_REQUEST_READ_CONTACTS);           // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an         // app-defined int constant. The callback method gets the         // result of the request.     } }

 

四、簡單的例子

這裡寫一個簡單的例子,針對於運行時許可權。相信大家在最開始接觸Android的時候,都利用Intent實驗了打電話、發簡訊等功能。

我們看看直接撥打電話在Android 6.x的設備上許可權需要如何處理。

當然代碼非常簡單:

            Java  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Notification是Android中很理想的一種顯示提示信息的方法,它可以將應用程式的信息傳遞到我們的Android桌面狀態欄,採用這種消息傳遞方式不會影響到用戶對手機的正常使用。而且Notification不僅僅可以傳遞文字信息,還可以傳遞圖片信息,甚至可以將我們的控制項追加到上面,只要用戶不
  • 自己的學習筆記。
  • 轉載自並做少量添加:http://www.cnblogs.com/playing/archive/2011/04/07/2008620.html Layout對於迅速的搭建界面和提高界面在不同解析度的屏幕上的適應性具有很大的作用。這裡簡要介紹Android的Layout和研究一下它的實現。 Andr
  • 原文出處: codingZero 歡迎分享原創到伯樂頭條 導語 不會使用block的iOS程式員,不是一個合格的程式員學會了block,你再也不想用繁瑣的代理block沒有你想象中的那麼難,不要害怕,不要畏懼,勇敢嘗試筆者入行iOS時已經是ARC的天下,所以這裡只說ARC環境下的使用 什麼是bloc
  • Android Studio 優秀插件系列: Android Studio 優秀插件(一):GsonFormat Android Studio 優秀插件(二): Parcelable Code Generator -------------------------------------------
  • 自己的學習筆記。
  • 一般比較短小的音樂(如游戲中的打鬥、按鍵音效等)則要通過playEffect來播放。
  • 問題 大家都知道,在iOS里的AlertView不會阻塞後續代碼的執行,但如果有時候需要這樣做該怎麼辦呢? 解決方案 通過回調 也就是把後續要執行的代碼放到回調函數中去,可以參見 "UIAlertView Blocks" ,我今天要重點說明的是下麵這種方式。 使用RunLoop 我們都主線程上的Ru
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...