亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android 運行時權限管理最佳實踐

發布時間:2020-07-20 23:32:13 來源:網絡 閱讀:6071 作者:腦洞不夠大 欄目:移動開發

歡迎訪問我的個人博客 傳送門

從 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,系統將立即授予該權限。

請求權限

這里以申請日歷讀寫權限為例

1.在 AndroidMainifest 中聲明所需權限
<uses-permission android:name="android.permission.READ_CALENDAR"/>
<uses-permission android:name="android.permission.WRITE_CALENDAR"/>
2.檢查權限
  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>

3.申請權限
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,因此你可以直接請求任何需要的權限。
如果用戶以前拒絕了一個請求,則分為兩種情況:

  • 如果用戶僅拒絕沒有點不再提示,這個方法將返回 true
  • 如果用戶拒絕并點擊不再提示,這個方法將返回 false

ActivityCompat.requestPermissions 方法 用于申請權限,第二個參數為 所需權限數組,也就是可申請一個,或多個權限。第三個參數為 requestCode 回調的時候使用

4.處理權限申請回調
 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 方法,該方法有三個參數

  • requestCode 和申請權限時 requestCode 對應,
  • permissions 申請的權限數組
  • grantResults 申請結果

完整的代碼如下:

    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 -> {
            }
        }
    }

Android 運行時權限管理最佳實踐 Android 運行時權限管理最佳實踐

推薦使用 RxPermissions

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 參照上文 權限申請

Android 運行時權限管理最佳實踐

最后

權限申請的坑還有很多,特別是在國產手機上有各種各樣的bug,這個就要具體踩坑,具體解決了

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

兴和县| 萝北县| 临清市| 嘉鱼县| 南郑县| 白银市| 宝清县| 石屏县| 余江县| 精河县| 舒城县| 宜兰市| 潜山县| 尼玛县| 台北市| 陈巴尔虎旗| 文昌市| 屏东县| 溧阳市| 阳山县| 南宁市| 礼泉县| 庆阳市| 拉萨市| 宣化县| 安岳县| 县级市| 巴中市| 如东县| 阿拉善右旗| 宁城县| 曲周县| 周至县| 远安县| 三明市| 应用必备| 盘锦市| 海丰县| 西和县| 阆中市| 开化县|