Android運(yùn)行權(quán)限機(jī)制(一)

首先我要感謝這么長(zhǎng)時(shí)間以來(lái),一直堅(jiān)持看我文章的同學(xué),是你們的支持點(diǎn)贊讓我有了繼續(xù)寫作的力量。感謝你們,本文還有一個(gè)小名,Android運(yùn)行權(quán)限機(jī)制從啥也不是,到誰(shuí)也不慣著,請(qǐng)?jiān)徫沂侨绱说亩罕取?/p>

先來(lái)介紹一下,Android6.0引入了動(dòng)態(tài)權(quán)限,目前權(quán)限分兩種,一種不涉及用戶隱私的敏感權(quán)限,還是直接在清單文件AndroidManifest.xml中定義,還有一種類似通訊錄,相冊(cè)這些觸碰到用戶隱私的權(quán)限需要?jiǎng)討B(tài)實(shí)時(shí)的去申請(qǐng),具體的需要申請(qǐng)動(dòng)態(tài)權(quán)限的如下表格。

權(quán)限 權(quán)限組 名稱
CALENDAR READ_CALENDAR

WRITE_CALENDAR
日歷
CAMERA CAMERA 相機(jī)
CONTACTS READ_CONTACTS

WRITE_CONTACTS

GET_ACCOUNTS
聯(lián)系人
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
電話
SMS SEND_SMS

RECEIVE_SMS

READ_SMS

RECEIVE_WAP_PUSH

RECEIVE_MMS
短信
STORAGE READ_EXTERNAL_STORAGE

WRITE_EXTERNAL_STORAGE
存儲(chǔ)

這里需要注意的是這些敏感權(quán)限一共分9組,如果需要使用某一組內(nèi)的權(quán)限,申請(qǐng)一次當(dāng)前組內(nèi)其他權(quán)限則不需要重復(fù)申請(qǐng)。

接下來(lái)梳理一下,申請(qǐng)動(dòng)態(tài)權(quán)限的流程,以打電話為例,場(chǎng)景是我寫了一個(gè)按鈕來(lái)?yè)艽螂娫挕?br> 1)在執(zhí)行敏感操作前,檢查是否已經(jīng)存在該權(quán)限,有則通過(guò),無(wú)則申請(qǐng)。

 public void requestPermissionAndCall(){
      //檢查權(quán)限是否存在
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.CALL_PHONE},PERMISSION_REQUEST_CODE);
    }else{
        callPhone();
    }
}

在申請(qǐng)權(quán)限的過(guò)程中,會(huì)彈窗讓用戶選擇,允許則直接撥打,拒絕則下次點(diǎn)擊時(shí)候繼續(xù)彈窗向用戶索取權(quán)限,不同的是拒絕后的彈窗會(huì)顯示不再詢問(wèn)。如下圖:


Screenshot_1531226146.png

2)系統(tǒng)提供了權(quán)限對(duì)話框的點(diǎn)擊回調(diào),后續(xù)操作可以在回調(diào)中完成

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        //首先在權(quán)限返回的回調(diào)中根據(jù)定義的PERMISSION_REQUEST_CODE確定是哪個(gè)權(quán)限
    if (requestCode == PERMISSION_REQUEST_CODE){
        //根據(jù)用戶點(diǎn)擊判斷,是否點(diǎn)擊授權(quán)或者拒絕,做不同的操作
        if (grantResults[0] ==PackageManager.PERMISSION_GRANTED){
            callPhone();
        }else{
           //拒絕
        }
        return;
    }

}

這里還存在一個(gè)問(wèn)題,如果用戶點(diǎn)擊了不再詢問(wèn)。那么打電話這個(gè)需求就掛掉了。但是用戶可能無(wú)意按錯(cuò)或者其他情況,就不好了。所以這里的不再詢問(wèn)也是可以捕捉的,可以進(jìn)行彈窗或者跳轉(zhuǎn)設(shè)置界面。接下來(lái)簡(jiǎn)單的修改一下上面的例子:

 @Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        //首先在權(quán)限返回的回調(diào)中根據(jù)定義的PERMISSION_REQUEST_CODE確定是哪個(gè)權(quán)限
    if (requestCode == PERMISSION_REQUEST_CODE){
        //根據(jù)用戶點(diǎn)擊判斷,是否點(diǎn)擊授權(quán)或者拒絕,做不同的操作
        if (grantResults[0] ==PackageManager.PERMISSION_GRANTED){
            callPhone();
        }else{
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage("您已拒絕當(dāng)前功能所需要的權(quán)限,無(wú)法正常工作");
            builder.create().show();
        }
        return;
    }

}

效果如下:


Screenshot_1531227303.png

閑言:

相機(jī)的動(dòng)態(tài)權(quán)限不用申請(qǐng)兼容android7.0版本可以轉(zhuǎn)戰(zhàn) https://blog.csdn.net/lmj623565791/article/details/72859156

本來(lái)是想用相機(jī)來(lái)演示權(quán)限,結(jié)果我用的android8.1的sdk,并不需要申請(qǐng)動(dòng)態(tài)權(quán)限,至于為什么上面文章說(shuō)的很清楚了,我又打算試試打電話,結(jié)果發(fā)現(xiàn)按照傳統(tǒng)的打電話的寫法:

 public void callPhone(String phoneNum) {
    Intent intent = new Intent(Intent.ACTION_CALL);
    Uri data = Uri.parse("tel:" + phoneNum);
    intent.setData(data);
    startActivity(intent);
}

在sdk27下, startActivity(intent)編譯就不通過(guò),提示沒(méi)有添加動(dòng)態(tài)權(quán)限,快捷鍵直接生成了權(quán)限的代碼:

   Intent intent = new Intent(Intent.ACTION_CALL);
    Uri data = Uri.parse("tel:" + phoneNum);
    intent.setData(data);
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
        // TODO: Consider calling
        //    ActivityCompat#requestPermissions
        // here to request the missing permissions, and then overriding
        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
        //                                          int[] grantResults)
        // to handle the case where the user grants the permission. See the documentation
        // for ActivityCompat#requestPermissions for more details.
        return;
    }
    startActivity(intent);
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容