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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...