Android 6.0&運行時權(quán)限 筆記

  • 原生 API 的使用
  • 實踐中問題

首先介紹一下千劈,Android 6.0 的權(quán)限機制的變化大家都知道寝受,從原來安裝時一次性全部授權(quán)讶踪,變?yōu)樵谶\行時才向用戶申請授權(quán)凿傅。

當然在 6.0 也不是全部的權(quán)限都需要運行時授權(quán),現(xiàn)在的權(quán)限分為兩類:

  • Normal Permissions焰轻,一般不涉及用戶隱私臭觉,比如手機震動、訪問網(wǎng)絡(luò)等辱志。

  • Dangerous Permission蝠筑,涉及到用戶隱私的,比如訪問通訊錄等揩懒,這一類的權(quán)限就需要運行時授權(quán)菱肖。
    還有比較特別的一點是,這些危險權(quán)限是分組的旭从,比如第一組的權(quán)限和聯(lián)系人有關(guān)稳强,當我們獲取到用戶授予的permission:android.permission.WRITE_CONTACTS 權(quán)限時,同組下的權(quán)限就默認一起獲得和悦,不需要再次申請退疫。
    下面是危險權(quán)限一覽,不在這里的權(quán)限的申請和 6.0 以前是一樣的鸽素。

//聯(lián)系人
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.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:android.permission.ACCESS_COARSE_LOCATION
//存儲
group:android.permission-group.STORAGE
  permission:android.permission.READ_EXTERNAL_STORAGE
  permission:android.permission.WRITE_EXTERNAL_STORAGE
//麥克風(fēng)
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

然后是最后的效果圖:


Gif 演示

因為系統(tǒng)原生的 API 中褒繁,如果用戶選擇了「不再提示」則不會再彈出申請權(quán)限的對話框。
但是假設(shè)我的 APP 依靠藍牙向設(shè)備發(fā)送信息馍忽,但用戶未授予藍牙權(quán)限棒坏,則這個 APP 就無作為了燕差,所以要捕獲到這種情況并且彈出對話框。

還有一點比較重要的坝冕,下面一部分代碼在魅族徒探、小米等系統(tǒng)上是無效的,猜測是因為它們有自己的權(quán)限機制喂窟,關(guān)于這些情況的處理后面再說测暗。

原生 API 的實踐

參考官網(wǎng)中文教程:在運行時請求權(quán)限

  • 檢查權(quán)限
if(ContextCompat.checkSelfPermission(this,
         Manifest.permission.ACCESS_COARSE_LOCATION)
        != PackageManager.PERMISSION_GRANTED) {

}

checkSelfPermission() 方法傳入 context 和需要申請的權(quán)限,返回值:

public static final int PERMISSION_GRANTED = 0;
public static final int PERMISSION_DENIED = -1;

當為 PERMISSION_GRANTED 時則已經(jīng)獲取到權(quán)限磨澡。

  • 申請權(quán)限
ActivityCompat.requestPermissions(this,
               arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION), 10)

requestPermissions() 方法傳入 context碗啄,申請的權(quán)限的字符串數(shù)組,回調(diào)返回的參數(shù)稳摄。
所以該方法可以一次申請多個權(quán)限稚字,并且申請結(jié)果會回調(diào)到 Activity 的 onRequestPermissionsResult() 方法中。

@Override
public void onRequestPermissionsResult(int requestCode,
        String permissions[], int[] grantResults) {
    //requstCode 是 requestPermissions 傳入的第三個參數(shù)
    //permissions[] 是申請的權(quán)限的數(shù)組
    //grantResults[] 是申請的結(jié)果
}
  • 特殊的方法:
ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.ACCESS_COARSE_LOCATION))

方法傳入 context 和 權(quán)限名厦酬,如果用戶在申請權(quán)限對話框中拒絕了申請胆描,則該方法返回 true。
也就是當用戶拒絕了一次申請后弃锐,APP 再次申請的時候應(yīng)該解釋為什么需要申請該權(quán)限袄友。
還有就是如果用戶選擇了「不再提示」殿托,該方法返回 false霹菊。

  • 完整代碼

這里用上了 Kotlin 和 Anko,如果看不懂就該補習(xí)了支竹。

fun getPermission(){
  if (ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_COARSE_LOCATION)
          != PackageManager.PERMISSION_GRANTED) {
  
      if (ActivityCompat.shouldShowRequestPermissionRationale(this,
              Manifest.permission.ACCESS_COARSE_LOCATION)){

          //此時用戶已經(jīng)拒絕了一次申請旋廷,所以彈出對話框解釋申請的原因
          alert("申請開啟定位權(quán)限,如果不打開定位權(quán)限礼搁,將不能運行該 APP","申請權(quán)限"){
             positiveButton("同意",{
                 ActivityCompat.requestPermissions(act,
                         arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION), 10)
             })
          }.show()

      }else {
          ActivityCompat.requestPermissions(this,
                  arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION), 10)
      }
  }else{
      toast("已擁有權(quán)限")
  }
}

//申請方法的回調(diào)
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    if (requestCode == 10){
        //requestCode 為 10 時饶碘,才是對于申請方法的回調(diào)。
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED){
            toast("申請權(quán)限成功")
        }else{
            if (!ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.ACCESS_COARSE_LOCATION)) {
             
                //在回調(diào)中如果發(fā)現(xiàn)用戶拒絕了申請馒吴,則再一次彈出對話框
                //即使用戶選擇了「不再提示」這個對話框也會彈出
                alert("如果不打開定位權(quán)限扎运,將不能使用藍牙,是否跳轉(zhuǎn)到應(yīng)用詳情頁面", "申請權(quán)限") {
                    positiveButton("確定", {
                        //將會跳轉(zhuǎn)到應(yīng)用的詳情頁面
                        val localIntent = Intent()
                        localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                        localIntent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
                        localIntent.data = Uri.fromParts("package", packageName, null)
                        startActivity(localIntent)
                    })
                    negativeButton("取消", { dialog -> dialog.dismiss() })
                }.show()
            }
        }
    }
}

遇到的問題

就如上面說的,我在魅族和小米的手機上都試了一下饮戳,這里的代碼也不能說完全無用豪治,但是會出很多問題。

比如說在魅族的手機上(魅藍 note 5扯罐,F(xiàn)lyme 6.0.2.1A)负拟,無論授權(quán)與否,checkSelfPermission() 方法都只會返回 0歹河,也就是已授權(quán)的返回值 掩浙。

這種情況下花吟,比如我需要打開藍牙,那就直接執(zhí)行打開藍牙的方法厨姚,假如報錯衅澈、或者隔了一段時間后還是沒有打開,就彈出對話框提示用戶手動打開遣蚀。

if (mBluetoothAdapter == null){
   val bluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
   val bluetoothAdapter = bluetoothManager.adapter
}
var isEnable = bluetoothAdapter?.isEnabled ?: false
if(!isEnable){
  //嘗試申請權(quán)限
  bluetoothAdapter?.enable()
}
...
//延時五秒后再一次判斷
if (mBluetoothAdapter?.isEnabled == false){
  //跳轉(zhuǎn)到應(yīng)用詳情頁面
   val localIntent = Intent()
   localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
   localIntent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
   localIntent.data = Uri.fromParts("package", packageName, null)
   startActivity(localIntent)
}

這應(yīng)該是最笨的方法了矾麻,如果有更好的方法還請告知。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末芭梯,一起剝皮案震驚了整個濱河市险耀,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌玖喘,老刑警劉巖甩牺,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異累奈,居然都是意外死亡贬派,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進店門澎媒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來搞乏,“玉大人,你說我怎么就攤上這事戒努∏攵兀” “怎么了?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵储玫,是天一觀的道長侍筛。 經(jīng)常有香客問我,道長撒穷,這世上最難降的妖魔是什么匣椰? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮端礼,結(jié)果婚禮上禽笑,老公的妹妹穿的比我還像新娘。我一直安慰自己蛤奥,他們只是感情好佳镜,可當我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著喻括,像睡著了一般邀杏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天望蜡,我揣著相機與錄音唤崭,去河邊找鬼。 笑死脖律,一個胖子當著我的面吹牛谢肾,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播小泉,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼芦疏,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了微姊?” 一聲冷哼從身側(cè)響起酸茴,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎兢交,沒想到半個月后薪捍,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡配喳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年酪穿,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片晴裹。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡被济,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出涧团,到底是詐尸還是另有隱情只磷,我是刑警寧澤,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布少欺,位于F島的核電站喳瓣,受9級特大地震影響馋贤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一视卢、第九天 我趴在偏房一處隱蔽的房頂上張望巢株。 院中可真熱鬧,春花似錦犹芹、人聲如沸崎页。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽飒焦。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間牺荠,已是汗流浹背翁巍。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留休雌,地道東北人灶壶。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像杈曲,于是被迫代替她去往敵國和親驰凛。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內(nèi)容