您好,登錄后才能下訂單哦!
歡迎訪問我的個人博客 傳送門
從 Android 6.0(API 級別 23)開始,用戶開始在應用運行時向其授予權限,而不是在應用安裝時授予。此方法可以簡化應用安裝過程,因為用戶在安裝或更新應用時不需要授予權限。它還讓用戶可以對應用的功能進行更多控制;例如,用戶可以選擇為相機應用提供相機訪問權限,而不提供設備位置的訪問權限。用戶可以隨時進入應用的“Settings”屏幕調用權限。
系統權限分為幾個保護級別。需要了解的兩個最重要保護級別是正常權限和危險權限,如果應用聲明其需要正常權限,系統會自動向應用授予該權限,如:訪問網絡。如果應用聲明其需要危險權限,則用戶必須明確向應用授予該權限,如:訪問聯系人、讀寫權限。
官網可查 點擊查詢
ACCESS_LOCATION_EXTRA_COMMANDS
ACCESS_NETWORK_STATE
ACCESS_NOTIFICATION_POLICY
ACCESS_WIFI_STATE
BLUETOOTH
BLUETOOTH_ADMINbaidu_push
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
可通過adb 命令獲取 adb shell pm list permissions -d -g
group:android.permission-group.RCS_PERMISSION
group:com.google.android.gms.permission.CAR_INFORMATION
permission:com.google.android.gms.permission.CAR_VENDOR_EXTENSION
permission:com.google.android.gms.permission.CAR_MILEAGE
permission:com.google.android.gms.permission.CAR_FUEL
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.ANSWER_PHONE_CALLS
permission:android.permission.READ_PHONE_NUMBERS
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:com.google.android.gms.permission.CAR_SPEED
permission:android.permission.ACCESS_COARSE_LOCATION
group:android.permission-group.STORAGE
permission:android.permission.READ_EXTERNAL_STORAGE
permission:android.permission.WRITE_EXTERNAL_STORAGE
group:com.sina.weibo.permission-group
permission:com.sina.weibo.permission.USER
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
從上面的權限列表中可以看出危險權限都是分組的,如果應用請求其清單中列出的危險權限,而應用在同一權限組中已有另一項危險權限,則系統會立即授予該權限,而無需與用戶進行任何交互。例如,如果某應用已經請求并且被授予了 READ_CONTACTS 權限,然后它又請求 WRITE_CONTACTS,系統將立即授予該權限。
這里以申請日歷讀寫權限為例
<uses-permission android:name="android.permission.READ_CALENDAR"/>
<uses-permission android:name="android.permission.WRITE_CALENDAR"/>
private fun checkPermissions(): Boolean {
return when (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_CALENDAR)) {
PackageManager.PERMISSION_GRANTED -> {//有此權限
true
}
PackageManager.PERMISSION_DENIED -> {//無此權限
false
}
else -> false
}
}
這里用到系統提供的 ContextCompat.checkSelfPermission 方法,用于檢測某個權限是否已經被授予,方法返回值為 PackageManager.PERMISSION_GRANTED 表示已權限,為PackageManager.PERMISSION_DENIED 表示無此權限需要進行申請授權。
<span id = "requestPermission"></span>
private fun requestPermissions() {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.READ_CALENDAR)) {
// 是否需要向用戶解釋為何申請權限
toast(this,"需要此權限管理日歷")
} else {
ActivityCompat.requestPermissions(this,
arrayOf(Manifest.permission.READ_CALENDAR),
1)
}
}
ActivityCompat.shouldShowRequestPermissionRationale 方法 用于在實際顯示權限對話框之前是否顯示一個對正在請求權限的解釋,在app第一次安裝的時候。這個方法會返回false,因此你可以直接請求任何需要的權限。
如果用戶以前拒絕了一個請求,則分為兩種情況:
ActivityCompat.requestPermissions 方法 用于申請權限,第二個參數為 所需權限數組,也就是可申請一個,或多個權限。第三個參數為 requestCode 回調的時候使用
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
1 -> {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
toast(this, "已授權")
} else {
toast(this, "未授權")
}
}
else -> {
}
}
}
處理權限要實現 onRequestPermissionsResult 方法,該方法有三個參數
完整的代碼如下:
fun click(view: View?) {
when (view?.id) {
R.id.bt_query_permissions -> when (checkPermissions()) {
true -> toast(this, "有權限")
false -> toast(this, "無權限")
}
R.id.bt_request_permissions -> requestPermissions()
}
}
private fun checkPermissions(): Boolean {
return when (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_CALENDAR)) {
PackageManager.PERMISSION_GRANTED -> {//有此權限
true
}
PackageManager.PERMISSION_DENIED -> {//無此權限
false
}
else -> false
}
}
private fun requestPermissions() {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.READ_CALENDAR)) {
toast(this,"需要此權限管理日歷")
} else {
ActivityCompat.requestPermissions(this,
arrayOf(Manifest.permission.READ_CALENDAR),
1)
}
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
1 -> {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
toast(this, "已授權")
} else {
toast(this, "未授權")
}
}
else -> {
}
}
}
RxPermissions 是一個基于 RxJava 實現的權限框架,比使用 Android 自帶的 API 方便很多,可擴展性高。GitHub 地址
這里以 Rxjava2 為例
repositories {
jcenter() // If not already there
}
dependencies {
//compile 'com.tbruyelle.rxpermissions:rxpermissions:0.9.4@aar' // Rxjava1
compile 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.4@aar' // Rxjava2
compile "io.reactivex.rxjava2:rxjava:2.1.7"
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
}
request 可申請一個或多個權限 直接返回是否授權成功
val rxPermissions = RxPermissions(this)
rxPermissions.request(Manifest.permission.READ_CALENDAR)
.subscribe({ t ->
if (t) {
toast(this, "已授權")
} else {
toast(this, "未授權")
}
})
requestEach or ensureEach 來分別獲取每一個權限請求的結果
rxPermissions.requestEach(Manifest.permission.READ_CALENDAR, Manifest.permission.CAMERA)
.subscribe({ t ->
when {
t.granted -> toast(this, "${t.name} 已授權")
t.shouldShowRequestPermissionRationale -> toast(this, "${t.name} 未授權")
else -> toast(this, "${t.name} 已拒絕,并不提示")
}
})
這里的 shouldShowRequestPermissionRationale 參照上文 權限申請
權限申請的坑還有很多,特別是在國產手機上有各種各樣的bug,這個就要具體踩坑,具體解決了
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。