前言:
最近突然喜歡上一句詩:“寵辱不驚,看庭前花開花落;去留無意,望天空雲捲雲舒。” 哈哈~,這個和今天的主題無關,最近只要不學習總覺得生活中少了點什麼,所以想著圍繞著最近面試過程中討論比較多的一個知識點Android 6.0 許可權適配問題來進行學習,不過我不想直接進入這個主題,所以選擇先去了解一下Android的Permission許可權機制及使用
許可權管理相關部落格:
- Android許可權管理之Permission許可權機制及使用
- Android許可權管理之Android 6.0執行時許可權及解決辦法
- Android許可權管理之RxPermission解決Android 6.0 適配問題
Android許可權機制:
許可權是一種安全機制。Android許可權主要用於限制應用程式內部某些具有限制性特性的功能使用以及應用程式之間的元件訪問。
Android許可權列表:
Android許可權列表可以參考這篇部落格:android許可權大全
Android許可權使用:
1.)在 AndroidManifest.xml <manifest>標籤內使用<uses-permission>宣告使用某一個許可權
<uses-permission android:name="string"/>
例如申請使用網路許可權
<uses-permission android:name="android.permission.INTERNET"/>
如果特定的許可權必須申明使用,如果沒有申請使用就會報出Permission Denial錯誤,例如訪問通訊錄報出如下錯誤
Caused by: java.lang.SecurityException: Permission Denial: reading com.androintacts.ContactsProvider2 uri content://contacts/data/phones from pid=23763, uid=10036 requires android.permission.READ_CONTACTS
解決此類錯誤我們只需根據提示新增對應的許可權即可
<uses-permission android:name="android.permission.READ_CONTACTS" />
2.)自定義許可權permission
雖然這種使用場景不多見,但是在有些特定的場景下出於安全考慮就需要自定義許可權了,比如兩個APP之間需要共享資料而採用了ContentProvider,此時我們需要對一個app訪問另外一個app的資料時需要新增許可權申請。自定義許可權通過<permission>標籤
<permission android:description=”string resource” android:icon=”drawable resource” android:label=”string resource” android:name=”string” android:permissionGroup=”string” android:protectionLevel=[“normal” | “dangerous” | “signature” | “signatureOrSystem”] />
-
android:description:對許可權的描述,比lable更加的詳細,介紹該許可權的相關使用情況,比如當使用者被詢問是否給其他應用該許可權時。注意描述應該使用的是string資源,而不是直接使用string串。
-
android:icon:用來標識該許可權的一個圖示。
-
android:label:許可權的一個給使用者展示的簡短描述。方便的來說,這個可以直接使用一個string字串來表示,但是如果要釋出的話,還是應該使用string資源來表示。
-
android:name:許可權的唯一名字,由於獨立性,一般都是使用包名加許可權名,該屬性是必須的,其他的可選,未寫的系統會指定預設值。
-
android:permissionGroup: 許可權所屬許可權組的名稱,並且需要在這個或其他應用中使用<permission-group>標籤提前宣告該名稱,如果沒有宣告,該許可權就不屬於該組。
-
android:protectionLevel:許可權的等級
關於android:protectionLevel:許可權的等級
-
normal 低風險許可權,只要申請了就可以使用(在AndroidManifest.xml中新增<uses-permission>標籤),安裝時不需要使用者確認;
-
dangerous 高風險許可權,安裝時需要使用者的確認才可使用;
-
signature 只有當申請許可權的應用程式的數字簽名與宣告此許可權的應用程式的數字簽名相同時(如果是申請系統許可權,則需要與系統簽名相同),才能將許可權授給它;
-
signatureOrSystem 簽名相同,或者申請許可權的應用為系統應用(在system image中),與signature類似,只是增加了rom中自帶的app的宣告 ,儘量不要使用該選項,因為signature已經適合絕大部分的情況。
對於普通和危險級別的許可權,我們稱之為低階許可權,應用申請即授予。其他兩級許可權,我們稱之為高階許可權或系統許可權。當應用試圖在沒有許可權的情況下做受限操作,應用將被系統殺掉以警示。系統應用可以使用任何許可權。許可權的宣告者可無條件使用該許可權。
根據上面的介紹我們實戰一下自定義許可權如下
<permission android:name="personprovider.permission.read" android:description="@string/personprovider_permission_read_desstring" android:icon="@mipmap/ic_launcher" android:label="@string/personprovider_permission_read_labestring" android:protectionLevel="normal"/> <permission android:name="personprovider.permission.write" android:description="@string/personprovider_permission_write_desstring" android:icon="@mipmap/ic_launcher" android:label="@string/personprovider_permission_write_labestring" android:protectionLevel="normal"/>
3.)自定義許可權組permission-group
為了方便管理某一特定功能的許可權,所以我會對許可權進行分組,這時我們需要通過<permission-group>自定義一個許可權組
<permission-group android:description="string resource" android:icon="drawable resource" android:label="string resource" android:name="string"/>
-
android:description 這個屬性用於給許可權組定義一個使用者可讀的說明性文字。這個文字應該比標籤更長、更詳細。這個屬性必須要引用一個字串資源,跟label屬性不一樣,它不能夠使用原生的字串。
-
android:icon 這個屬性定義了一個代表許可權的圖示。這個屬性要使用包含圖片定義的可繪製資源來定義。
-
android:label 這個屬性給許可權組定義了一個使用者可讀的名稱。為了開發方便,在開發時,可以直接使用原生的字串來設定這個屬性。但是,當應用程式正式釋出時,應該使用字串資源來設定,以便能夠像使用者介面中其他的字串一樣能夠被本地化。
-
android:name 這個屬性定義了許可權組的名稱,它是能夠分配給<permission>元素的permissionGroup屬性的名稱。
上面的許可權組我們可以自定義為下面這種方式:
<permission-group android:name="personprovider.permission-group" android:description="@string/personprovider_permission_group_desstring" android:icon="@mipmap/ic_launcher" android:label="@string/personprovider_permission_group_labelstring"/> <permission android:name="personprovider.permission.read" android:description="@string/personprovider_permission_read_desstring" android:icon="@mipmap/ic_launcher" android:label="@string/personprovider_permission_read_labestring" android:permissionGroup="personprovider.permission-group" android:protectionLevel="normal"/> <permission android:name="personprovider.permission.write" android:description="@string/personprovider_permission_write_desstring" android:icon="@mipmap/ic_launcher" android:label="@string/personprovider_permission_write_labestring" android:permissionGroup="personprovider.permission-group" android:protectionLevel="normal"/>
其他關於permission-tree這裡就不介紹了,這個至今沒有用到過,<permission-tree>是為一組permissions宣告瞭一個namespace。
4.)使用自定義許可權
申請許可權
<uses-permission android:name="personprovider.permission.read"/> <uses-permission android:name="personprovider.permission.write"/>
在宿主上宣告需要申請訪問許可權
<provider android:name=".PersonProvider" android:authorities="com.whoislcj.testsqlite.personprovider" android:enabled="true" android:exported="true" android:readPermission="personprovider.permission..read" android:writePermission="personprovider.permission..write"/>
總結:
本篇大致瞭解了Android的許可權permission以及如何使用和自定義許可權,下篇將總結學一下如何解決Android 6.0的許可權的適配問題。