這篇文章為大家系統(tǒng)的梳理一下 Android 權(quán)限相關(guān)的知識崩哩,在日常開發(fā)中言沐,我們都用過權(quán)限险胰,但是對于權(quán)限的一些細節(jié)我們可能掌握的還不夠全面矿筝,這篇文章會全面的為大家介紹權(quán)限相關(guān)的知識跋涣。當然,本篇文章依然是參考了 Google 的官方文檔:應(yīng)用權(quán)限奖年。
本文目錄
一陋守、認識 Android 權(quán)限
(一)Android 系統(tǒng)為什么需要權(quán)限利赋?
Android 系統(tǒng)設(shè)置權(quán)限的目的是保護 Android 用戶的隱私媚送。對于用戶的敏感數(shù)據(jù) Android 應(yīng)用程序必須向用戶申請授權(quán)后才能訪問(如聯(lián)系人和短信),另外還包括某些系統(tǒng)功能(如攝像頭易稠、麥克風)的權(quán)限咱扣。根據(jù)功能的不同涵防,系統(tǒng)可能會自動授予權(quán)限或提示用戶批準請求壮池。Android 安全架構(gòu)的一個核心設(shè)計要點是,在默認情況下硼补,沒有應(yīng)用程序可以執(zhí)行任何可能對其他應(yīng)用程序熏矿、操作系統(tǒng)或用戶造成不利影響的操作。這包括讀取或?qū)懭胗脩舻乃饺藬?shù)據(jù)(如聯(lián)系人或電子郵件)褪储、讀取或?qū)懭肓硪粋€應(yīng)用程序的文件鲤竹、執(zhí)行網(wǎng)絡(luò)訪問等等辛藻。
(二)權(quán)限分類
權(quán)限分為幾個保護級別。保護級別影響是否需要運行時權(quán)限請求:
- Normal permissions 正常權(quán)限
- Signature permissions 簽名權(quán)限
- Dangerous permissions 危險權(quán)限
需要我們了解的是正常權(quán)限和危險權(quán)限痘拆。
1.正常權(quán)限
正常的權(quán)限覆蓋了應(yīng)用程序需要訪問沙箱之外的數(shù)據(jù)或資源的區(qū)域氮墨,但這些區(qū)域?qū)τ脩綦[私或其他應(yīng)用程序的操作幾乎沒有風險规揪。例如,設(shè)置時區(qū)的權(quán)限是正常的權(quán)限字支。
如果應(yīng)用程序在它的清單中聲明它需要一個正常的權(quán)限堕伪,系統(tǒng)會在安裝時自動授予該權(quán)限月杉。系統(tǒng)不提示用戶授予正常權(quán)限抠艾,用戶也不能撤銷這些權(quán)限检号。
- 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_IGNORE_BATTERY_OPTIMIZATIONS
- 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
2.危險權(quán)限
危險權(quán)限包括應(yīng)用程序需要涉及用戶私人信息的數(shù)據(jù)或資源的區(qū)域齐苛,也包括可能影響用戶存儲的數(shù)據(jù)或其他應(yīng)用程序的操作的區(qū)域。例如馍驯,讀取用戶的聯(lián)系人是一種危險的權(quán)限汰瘫。如果一個應(yīng)用程序聲明它需要一個危險的權(quán)限,用戶必須顯式地授予該應(yīng)用程序權(quán)限趴乡。在用戶批準該權(quán)限之前蝗拿,應(yīng)用程序不能提供依賴于該權(quán)限的功能哀托。
要使用危險的權(quán)限,應(yīng)用程序必須在運行時提示用戶授予權(quán)限裙品。
(三)如何聲明一個權(quán)限市怎?
應(yīng)用程序必須通過在清單文件(AndroidManifest.xml
)中使用 <uses-permission>
標記來公布它需要的權(quán)限辛慰。例如聲明網(wǎng)絡(luò)訪問權(quán)限:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
//聲明網(wǎng)絡(luò)訪問權(quán)限
<uses-permission android:name="android.permission.INTERNET"/>
<application ...>
...
</application>
</manifest>
如果在應(yīng)用程序的清單文件中列出的是正常的權(quán)限(即不會對用戶隱私或設(shè)備操作造成太大風險的權(quán)限)帅腌,系統(tǒng)會自動將這些權(quán)限授予給應(yīng)用程序。
如果在應(yīng)用程序的清單中列出的是危險的權(quán)限(即可能影響用戶隱私或設(shè)備正常操作的權(quán)限)戚篙,則必須經(jīng)過用戶的同意才能授權(quán)相應(yīng)的權(quán)限岔擂。
(四)Android 不同版本對危險權(quán)限的處理方式
Android 請求用戶授予危險權(quán)限的方式取決于用戶設(shè)備上運行的 Android 版本浪耘,以及我們在應(yīng)用中設(shè)置的 targetSdkVersion
七冲。主要有兩種處理方式:
- 運行時請求:Android 6.0 以及更高的版本
- 安裝時請求:Android 5.1.1 以及更低的版本
- 運行時請求:
如果手機 Android 系統(tǒng)的版本是 6.0 (API級別23) 或者更高澜躺,而應(yīng)用程序的 targetSdkVersion
是 23 或者更高抒蚜,用戶在安裝時不會收到任何應(yīng)用程序權(quán)限通知削锰。應(yīng)用程序必須要求用戶在運行時授予危險的權(quán)限毕莱。當應(yīng)用程序請求權(quán)限時朋截,用戶會看到一個系統(tǒng)對話框,告訴用戶應(yīng)用程序試圖訪問哪個權(quán)限組唆姐。對話框包含一個拒絕和允許按鈕廓八。
如果用戶拒絕權(quán)限請求剧蹂,那么下一次應(yīng)用程序請求該權(quán)限時,對話框?qū)粋€復(fù)選框先巴,選中該復(fù)選框后伸蚯,用戶不會再收到權(quán)限申請?zhí)崾尽?/p>
下面通過申請拍照權(quán)限為例:
可以看到简烤,第一次彈框時選擇拒絕横侦,第二次彈框出現(xiàn)了一個“不再詢問”的復(fù)選框丈咐,勾選以后龙宏,再次拒絕银酗,則之后都不會再彈出權(quán)限申請的對話框徒像。
假如用戶選擇了“允許”锯蛀,也不能表示應(yīng)用就會一直擁有該權(quán)限次慢。用戶還可以進入系統(tǒng)設(shè)置頁面迫像,將之前那授予的權(quán)限關(guān)閉掉,因此菌羽,我們在開發(fā)中必須在運行時去檢查和申請相應(yīng)的權(quán)限注祖,以防止在運行時出現(xiàn) SecurityException
的錯誤均唉,導(dǎo)致應(yīng)用奔潰舔箭。
- 安裝時請求:
如果手機 Android 系統(tǒng)的版本是 5.1.1 (API級別22) 或者更低,而應(yīng)用程序的 targetSdkVersion
是 22 或者更低靴庆,系統(tǒng)會自動要求用戶在安裝時為應(yīng)用程序授予所有危險的權(quán)限炉抒。
如果用戶單擊
Accept
焰薄,應(yīng)用程序請求的所有權(quán)限都將被授予扒袖。如果用戶拒絕權(quán)限請求季率,系統(tǒng)將取消應(yīng)用程序的安裝。如果應(yīng)用程序更新需要額外的權(quán)限鞭光,用戶在更新應(yīng)用程序之前會被提示接受這些新的權(quán)限惰许。
(五)特殊的兩個權(quán)限
有兩個權(quán)限的行為不像正常權(quán)限和危險權(quán)限:SYSTEM_ALERT_WINDOW
和 WRITE_SETTINGS
這是兩個特別敏感的權(quán)限,所以大多數(shù)應(yīng)用程序不應(yīng)該使用它們佩伤。如果應(yīng)用程序需要這些權(quán)限之一畦戒,它必須在清單中聲明該權(quán)限结序,并發(fā)送一個意圖請求用戶的授權(quán)徐鹤。系統(tǒng)通過向用戶顯示詳細的管理屏幕來響應(yīng)這個意圖返敬。
以申請 SYSTEM_ALERT_WINDOW
為例:
step 1:首先在清單文件中聲明權(quán)限:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
step 2:申請權(quán)限(6.0 及其以上版本)
//在 6.0 以前的系統(tǒng)版本,懸浮窗權(quán)限是默認開啟的涛目,直接使用即可霹肝。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(context)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
startActivity(intent);
return;
}
}
(六)權(quán)限組
Android 系統(tǒng)對所有的危險權(quán)限進行了分組沫换,稱為 權(quán)限組
最铁。
權(quán)限組 | 權(quán)限 |
---|---|
CALENDAR | READ_CALENDAR WRITE_CALENDAR |
CAMERA | CAMERA |
CONTACTS | READ_CONTACTS WRITE_CONTACTS GET_ACCOUNTS |
LOCATION | ACCESS_FINE_LOCATION ACCESS_COARSE_LOCATION |
MICROPHONE | RECORD_AUDIO |
PHONE | READ_PHONE_STATE CALL_PHONE READ_CALL_LOG WRITE_CALL_LOG ADD_VOICEMAIL USE_SIP PROCESS_OUTGOING_CALLS |
SENSORS | BODY_SENSORS |
SMS | SEND_SMS RECEIVE_SMS READ_SMS RECEIVE_WAP_PUSH RECEIVE_MMS |
STORAGE | READ_EXTERNAL_STORAGE WRITE_EXTERNAL_STORAGE |
如果手機 Android 系統(tǒng)的版本是 6.0 (API級別23) 或者更高冷尉,而應(yīng)用程序的 targetSdkVersion
是 23 或者更高雀哨,則當應(yīng)用程序請求危險權(quán)限時,系統(tǒng)會有如下行為:
如果應(yīng)用程序當前在權(quán)限組中沒有任何權(quán)限怜庸,則系統(tǒng)向描述應(yīng)用程序希望訪問的權(quán)限組的用戶顯示權(quán)限請求對話框割疾。對話框沒有描述該組中的特定權(quán)限宏榕。例如侵佃,如果一個應(yīng)用程序請求READ_CONTACTS權(quán)限馋辈,系統(tǒng)對話框只告訴應(yīng)用程序需要訪問設(shè)備的聯(lián)系人。如果用戶給予批準叉抡,系統(tǒng)只會給應(yīng)用程序它所請求的權(quán)限褥民。
如果應(yīng)用程序已經(jīng)在同一權(quán)限組中被授予了另一個危險權(quán)限洗搂,系統(tǒng)會立即授予該權(quán)限耘拇,而不與用戶進行任何交互。例如秦驯,如果一個應(yīng)用程序之前請求并被授予了READ_CONTACTS權(quán)限译隘,然后它請求WRITE_CONTACTS固耘,系統(tǒng)立即授予該權(quán)限词身,而不向用戶顯示權(quán)限對話框。
上面是官方的原話葫笼,簡而言之就是:屬于同一組的危險權(quán)限將自動合并授予拗馒,用戶授予應(yīng)用某個權(quán)限組的權(quán)限诱桂,則應(yīng)用將獲得該權(quán)限組下的所有權(quán)限(前提是相關(guān)權(quán)限在 AndroidManifest.xml 中有聲明)。
然而事實真的如此嗎友绝?我們來試驗一下屬于同一個權(quán)限組下的 READ_CONTACTS
權(quán)限和 WRITE_CONTACTS
權(quán)限迁客。按照官方的說法哲泊,如果我先授權(quán)了 READ_CONTACTS
權(quán)限催蝗,那么 WRITE_CONTACTS
權(quán)限會被自動授予丙号,我們來看看實際運行的效果:
可以看到犬缨,當我們先授予了
READ_CONTACTS
權(quán)限后,再去申請 WRITE_CONTACTS
權(quán)限時刺彩,依舊彈出了對話框讓用戶授權(quán)创倔,這明顯和官方文檔說明的不一致畦攘。但是同時官方建議我們十电,不要將應(yīng)用程序的邏輯建立在這些權(quán)限組的結(jié)構(gòu)上,因為在未來的版本中罢绽,可能會將一個特定的權(quán)限從一個組移動到另一個組静盅,因此温亲,我們的代碼邏輯不應(yīng)該依賴權(quán)限組栈虚,而是應(yīng)該顯式地請求它需要的每個權(quán)限史隆,即使用戶已經(jīng)在同一組中授予了另一個權(quán)限泌射。
二熔酷、如何請求權(quán)限
每款 Android 應(yīng)用都在訪問受限的沙盒中運行。如果應(yīng)用需要使用其自己的沙盒外的資源或信息号显,則必須請求相應(yīng)權(quán)限押蚤。 要聲明應(yīng)用需要某項權(quán)限揽碘,可以在應(yīng)用清單中列出該權(quán)限园匹,然后在運行時請求用戶批準每項權(quán)限(適用于 Android 6.0 及更高版本)裸违。
(一)向清單文件添加權(quán)限
無論應(yīng)用需要什么權(quán)限累颂,都需要在清單文件中對權(quán)限進行聲明。系統(tǒng)會根據(jù)聲明權(quán)限的敏感程度采取不同的操作料饥。有些權(quán)限被視為“常規(guī)”權(quán)限岸啡,系統(tǒng)會在安裝應(yīng)用時立即授予這些權(quán)限巡蘸。還有些則被視為“危險”權(quán)限,需要用戶明確授予相應(yīng)訪問權(quán)限唯欣。
(二)檢查權(quán)限
如果應(yīng)用需要一項危險權(quán)限境氢,那么每次執(zhí)行需要該權(quán)限的操作時萍聊,都必須檢查自己是否具有該權(quán)限悦析。從 Android 6.0(API 級別 23)開始强戴,用戶可隨時從任何應(yīng)用撤消權(quán)限酌泰,即使應(yīng)用以較低的 API 級別為目標平臺也是如此陵刹。因此,即使應(yīng)用昨天使用了相機衰琐,也不能認為它今天仍具有該權(quán)限也糊。
要檢查應(yīng)用是否具有某項權(quán)限,請調(diào)用 ContextCompat.checkSelfPermission()
方法羡宙。例如狸剃,以下代碼段展示了如何檢查 Activity 是否具有向日歷寫入數(shù)據(jù)的權(quán)限:
if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.WRITE_CALENDAR)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
}
如果應(yīng)用具有此權(quán)限,該方法將返回 PERMISSION_GRANTED
狗热,并且應(yīng)用可以繼續(xù)操作钞馁。如果應(yīng)用不具備此權(quán)限,該方法將返回 PERMISSION_DENIED
僧凰,且應(yīng)用必須明確要求用戶授予權(quán)限探颈。
(三)請求權(quán)限
當應(yīng)用從 checkSelfPermission()
收到 PERMISSION_DENIED
時,需要提示用戶授予該權(quán)限训措。Android 提供了幾種可用來請求權(quán)限的方法(如 requestPermissions())伪节,如下面的代碼段所示。調(diào)用這些方法時绩鸣,會顯示一個無法自定義的標準 Android 對話框怀大。
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.READ_CONTACTS)) {
// Show an explanation 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; 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.
}
} else {
// Permission has already been granted
}
在某些情況下,需要幫助用戶理解為什么應(yīng)用需要某項權(quán)限呀闻。例如化借,如果用戶啟動一款攝影應(yīng)用,用戶或許不會對該應(yīng)用請求使用相機的權(quán)限感到驚訝总珠,但用戶可能不理解為什么該應(yīng)用想要訪問用戶的位置或聯(lián)系人屏鳍。在應(yīng)用請求權(quán)限之前勘纯,可以向用戶提供解釋局服。一種比較好的做法是在用戶之前拒絕過該權(quán)限請求的情況下提供解釋。我們通過調(diào)用 shouldShowRequestPermissionRationale()
方法來實現(xiàn)驳遵。如果用戶之前拒絕了該請求淫奔,該方法將返回 true。如果用戶之前拒絕了該權(quán)限并且選中了權(quán)限請求對話框中的不再詢問選項堤结,或者如果設(shè)備政策禁止該權(quán)限唆迁,該方法將返回 false(注意,如果用戶拒絕了該權(quán)限竞穷,并且勾選了“不再詢問”唐责,即使在返回false的邏輯中調(diào)用了requestPermissions方法,系統(tǒng)也不會再彈出選擇框)瘾带。
(四)處理權(quán)限請求響應(yīng)
@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;
}
// other 'case' lines to check for other
// permissions this app might request.
}
}
三鼠哥、自定義權(quán)限
(一)背景
Android 是一個特權(quán)分離的操作系統(tǒng),其中每個應(yīng)用程序都使用一個唯一的系統(tǒng)標識(Linux 用戶 ID 和 組 ID)運行看政。系統(tǒng)也被稱不同的部分朴恳,每個部分都有自己的標識。因此允蚣,Linux 將應(yīng)用程序彼此隔離于颖,并與系統(tǒng)隔離。應(yīng)用程序可以自定義權(quán)限來提供給其他應(yīng)用程序訪問自己的功能嚷兔。
(二)如何自定義權(quán)限
要自定義權(quán)限森渐,可以在 AndroidManifest.xml
中使用 <permission>
標簽來聲明做入。
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp" >
<permission
android:name="com.example.myapp.permission.DEADLY_ACTIVITY"
android:label="@string/permlab_deadlyActivity"
android:description="@string/permdesc_deadlyActivity"
android:permissionGroup="android.permission-group.COST_MONEY"
android:protectionLevel="dangerous" />
...
</manifest>
屬性解釋:
- name:自定義權(quán)限的名字。如果其他 app 引用該權(quán)限需要填寫這個名字同衣。
- lable:標簽母蛛,用于描述該權(quán)限保護的關(guān)鍵功能(盡量簡短)。顯示給用戶的乳怎,它的值可是一個 string 數(shù)據(jù)彩郊。
- description:描述,比 label 更長的對權(quán)限的描述蚪缀。值是通過 resource 文件中獲取的秫逝,不能直接寫 string 值。
- permissionGroup:權(quán)限組询枚,可選屬性违帆。在大多數(shù)情況下,應(yīng)該將其設(shè)置為一個標準系統(tǒng)組(android.Manifest.permission_group)金蜀,盡管可以自己定義一個組刷后。
- protectionLevel:保護級別,它是必須的屬性渊抄。
下面我們來寫一個具體的例子:我們在進程1中定義一個 Activity尝胆,并為該 Activity 設(shè)置訪問權(quán)限,然后讓進程2來訪問它护桦。
進程1:
AndroidManifest.xml 文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.chenyouyu.permissiondemo">
//自定義的權(quán)限含衔,權(quán)限級別為 normal
<permission
android:name="com.example.myapp.permission.SECOND_ACTIVITY"
android:label="abc"
android:description="@string/permdesc_SecondActivity"
android:permissionGroup="android.permission-group.COST_MONEY"
android:protectionLevel="normal" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
//為SecondActivity加上android:permission="com.example.myapp.permission.SECOND_ACTIVITY"
<activity
android:name=".SecondActivity"
android:exported="true"
android:permission="com.example.myapp.permission.SECOND_ACTIVITY">
<intent-filter>
<action android:name="com.cyy.jump" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
......
</manifest>
進程2:
AndroidManifest.xml 文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.chenyouyu.permissiondemo2">
//在AndroidManifest中聲明權(quán)限
<uses-permission android:name="com.example.myapp.permission.SECOND_ACTIVITY"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
MainActivity.java
Intent intent = new Intent();
intent.setAction("com.cyy.jump");
intent.addCategory(Intent.CATEGORY_DEFAULT);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
首先運行進程1,然后運行進程2二庵。
(三)自定義權(quán)限注意點
1.兩個應(yīng)用聲明了相同的權(quán)限
Android 不允許兩個不同的應(yīng)用定義一個相同名字的權(quán)限(除非這兩個應(yīng)用擁有相同的簽名)贪染,所以在命名的時候,需要特別注意催享。擁有相同自定義權(quán)限的軟件必須使用同樣的簽名杭隙,否則后一個程序無法安裝。
2.和應(yīng)用安裝順序的關(guān)系因妙。
場景:App A中聲明了權(quán)限PermissionA痰憎,App B中使用了權(quán)限PermissionA。
情況一:PermissionA的保護級別是normal或者dangerous
App B先安裝兰迫,App A后安裝信殊,此時App B無法獲取PermissionA的權(quán)限,從App B打開App A會報權(quán)限錯誤汁果。
App A先安裝涡拘,App B后安裝,從App B打開App A一切正常据德。
情況二:PermissionA的保護級別是signature或者signatureOrSystem
App B先安裝鳄乏,App A后安裝跷车,如果App A和App B是相同的簽名,那么App B可以獲取到PermissionA的權(quán)限橱野。如果App A和App B的簽名不同朽缴,則App B獲取不到PermissionA權(quán)限。即水援,對于相同簽名的app來說密强,不論安裝先后,只要是聲明了權(quán)限蜗元,請求該權(quán)限的app就會獲得該權(quán)限或渤。
這也說明了對于具有相同簽名的系統(tǒng)app來說,安裝過程不會考慮權(quán)限依賴的情況奕扣。安裝系統(tǒng)app時薪鹦,按照某個順序(例如名字排序,目錄位置排序等)安裝即可惯豆,等所有app安裝完了池磁,所有使用權(quán)限的app都會獲得權(quán)限。
3.權(quán)限的獲取以及版本兼容
Android6.0引入了動態(tài)權(quán)限楷兽,這個大家都知道了地熄。前面說到的自定義的權(quán)限的安全級別android:protectionLevel會影響權(quán)限在Android6.0+系統(tǒng)的使用
android:protectionLevel="normal",不需要動態(tài)申請
android:protectionLevel="dangerous"拄养,需要動態(tài)申請
參考文章: