Android6.0發佈後,其一系列新特新足夠讓咱們這些Android程序員興奮一段時間了。首先咱們先看看具體有哪些新特性:html
-鎖頻下語音搜索
-指紋識別
-更完整的應用權限管理
-Doze電量管理
-Now on Tap
-App linkjava
具體能夠參考Android 6.0有哪些新特性。android
上面六個新特性中更完整的應用權限管理
應該是和咱們開發者關係最密切的了,接下來咱們就來具體瞭解一下如何在Android 6.0上更好的使用Android系統權限。程序員
在Android 6.0中谷歌摒棄了以前的install time permissions model
取而代之的是runtime permissions model
。先來講說install time permissions model
,這個你們不陌生,就是當Android App安裝的時候會向用戶展現一坨權限,若是此時用戶選擇安裝,則表示用戶贊成將這些權限賦予App,若是用戶不一樣意那麼這個App就會取消安裝。runtime permissions model
就牛逼了,在App安裝的時候一樣會向用戶展現所須要的權限,而且在用戶選擇安裝App的時候並不表示用戶將這些權限賦予了App,而是須要App在運行階段主動去申請這些權限。這樣作的好處顯而易見,App對權限的申請對於用戶來講變得更加透明,並且用戶對App權限的控制也更加靈活。api
Android將系統權限分紅了四個保護等級normal
,dangerous
,signature
,signatureOrSystem
,其中最多見的是normal permission
和dangerous permission
兩類。數組
normal permission涵蓋的一系列權限的共同點是:App須要訪問App運行沙盒之外的數據或資源,可是這些資源對用戶的隱私或其餘App的危險性較小,下面列舉一下這些權限:ide
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
FLASHLIGHT
GET_PACKAGE_SIZE
INTERNET
KILL_BACKGROUND_PROCESSES
MODIFY_AUDIO_SETTINGS
NFC
READ_SYNC_SETTINGS
READ_SYNC_STATS
RECEIVE_BOOT_COMPLETED
REORDER_TASKS
REQUEST_INSTALL_PACKAGES
SET_TIME_ZONE
SET_WALLPAPER
SET_WALLPAPER_HINTS
TRANSMIT_IR
USE_FINGERPRINT
VIBRATE
WAKE_LOCK
WRITE_SYNC_SETTINGS
SET_ALARM
INSTALL_SHORTCUTthis
以上這些就是Android 6.0中全部的normal permissions
了。code
dangerous permissions 涵蓋的一系列權限的共同點是:這些權限會讀寫用戶的隱私信息,也可能會讀寫用戶存儲的數據或影響其餘App的正常運行。下面例舉出這些權限:
| 權限組 | 權限 |
| ---------- | ---------- |
| 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 |
以上這些權限就是Android6.0中全部的dangerous permissions
。orm
Runtime Permissions針對的是dangerous permissions
,normal permissions
仍是會在App安裝期間被默認賦予。
下面咱們就以STORAGE
組中的WRITE_EXTERNAL_STORAGE
爲例子,嘗試在Android 6.0中使用runtime permission
相關api。
咱們要作的事情很是簡單,在手機的存儲設備上新建一個hello.txt。
1.在AndroidManifest文件中添加以下權限生命
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
2.在MainActivity中添加以下方法:
//在sdcard上新建一個名爲fileName的文件 private void createFile(String fileName){ File sdcard = Environment.getExternalStorageDirectory(); File newFile = new File(sdcard,"/" + fileName) ; if(!newFile.exists()){ try { newFile.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } }
好的,若是沒有runtime permissions
這個概念的話,那其實這個功能已經完成了,咱們來看看它在Android 6.0以前的版本上的運行狀況,
首先是安裝時的界面:
它提示用戶該應用會修改會刪除SD卡的內容,若是此時用戶選擇安裝,那麼也就是默認將WRITE_EXTERNAL_STORAGE
這個權限賦予了該應用。
再來看運行結果:
看吧,文件直接就建立成功了,這樣真的是很危險的。
接下來再在Android6.0的機子上安裝這個應用,安裝截圖以下:
這個安裝界面和以前的同樣,也是向用戶展現了App所涉及的權限。
下面看運行結果:
這裏就出問題了,log顯示App沒有權限在SD卡上建立文件。這裏要再講一下runtime permissions
原理
對於權限分類中的
dangerous permissions
,runtime permissions要求App在運行的時候作權限請求,某則App則沒法得到相應請求。
接下來看一下怎麼在代碼中進行權限的申請:
public static final int EXTERNAL_STORAGE_REQ_CODE = 10 ; public void requestPermission(){ //判斷當前Activity是否已經得到了該權限 if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { //若是App的權限申請曾經被用戶拒絕過,就須要在這裏跟用戶作出解釋 if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { Toast.makeText(this,"please give me the permission",Toast.LENGTH_SHORT).show(); } else { //進行權限請求 ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, EXTERNAL_STORAGE_REQ_CODE); } } }
當進行權限申請,而且用戶作出選擇後會回調onRequestPermissionsResult這個方法,在這個方法中作相關處理
@Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case EXTERNAL_STORAGE_REQ_CODE: { // 若是請求被拒絕,那麼一般grantResults數組爲空 if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { //申請成功,進行相應操做 createFile("hello.txt"); } else { //申請失敗,能夠繼續向用戶解釋。 } return; } } }
到這裏runtime permissions
的權限申請操做就結束了,咱們看一下效果:
容許後會再次調用createFile("hello.txt")方法,此次文件會被成功建立。
其實還有一些內容須要寫,這裏先//TODO一下,但願以上內容對你有所幫助。