Android動(dòng)態(tài)權(quán)限申請

從Android 6.0開始,權(quán)限不再是在manifest文件中粘貼一下即可,這時(shí)候權(quán)限也正式走進(jìn)大家的視野白筹。項(xiàng)目的6.0適配就是我做的,當(dāng)時(shí)沒有仔細(xì)總結(jié)谅摄,最近在另一個(gè)項(xiàng)目添加權(quán)限的時(shí)候發(fā)現(xiàn)徒河,同一個(gè)功能都沒有添加申請權(quán)限的代碼,一個(gè)會(huì)掛一個(gè)不會(huì)螟凭,花了幾個(gè)小時(shí)在這個(gè)小問題上虚青。因此多花點(diǎn)時(shí)間總結(jié)一下權(quán)限問題。

  1. Android系統(tǒng)權(quán)限的概念

Android是一個(gè)權(quán)限分隔的操作系統(tǒng)螺男,每個(gè)應(yīng)用都有獨(dú)特的系統(tǒng)標(biāo)識(shí)棒厘。一般情況下纵穿,應(yīng)用沒有權(quán)限執(zhí)行對其它應(yīng)用、系統(tǒng)奢人、用戶可能有不利影響的操作谓媒。每個(gè)應(yīng)用都在應(yīng)用沙盒中運(yùn)行,因此當(dāng)應(yīng)用需要使用沙盒未提供的功能時(shí)何乎,需要申請權(quán)限句惯,比如讀寫sd卡、訪問網(wǎng)絡(luò)支救、訪問其它應(yīng)用的數(shù)據(jù)抢野、讀寫聯(lián)系人、調(diào)用攝像頭等各墨。

權(quán)限在AndroidManifest.xml文件中聲明指孤,Android 6.0以前,有的APP一股腦聲明了各種各樣的權(quán)限贬堵,用戶可能沒有細(xì)看就安裝了恃轩,于是這些APP就可以為所欲為,偷雞摸狗黎做,無法無天叉跛。Android 6.0把權(quán)限分成正常權(quán)限和危險(xiǎn)權(quán)限,AndroidManifest中聲明的正常權(quán)限系統(tǒng)會(huì)自動(dòng)授予蒸殿,而危險(xiǎn)權(quán)限則需要在使用的時(shí)候用戶明確授予筷厘。

換句話說,就是Android 6.0以上的系統(tǒng)在第一次使用危險(xiǎn)權(quán)限的時(shí)候宏所,需要向用戶申請敞掘,征得用戶的同意。如果還是在沒有權(quán)限的情況下執(zhí)行操作楣铁,就會(huì)獲得Crash大禮包,錯(cuò)誤日志為java.lang.SecurityException: Permission Denial更扁。因此盖腕,應(yīng)用對危險(xiǎn)權(quán)限的申請,需要相應(yīng)的處理浓镜。

  1. 危險(xiǎn)權(quán)限和對應(yīng)的權(quán)限組

危險(xiǎn)權(quán)限都屬于權(quán)限組溃列,應(yīng)用在向用戶申請危險(xiǎn)權(quán)限時(shí),系統(tǒng)會(huì)彈對話框膛薛,描述應(yīng)用要訪問的權(quán)限組听隐,這時(shí)候用戶如果同意授權(quán),則權(quán)限組包含的所有權(quán)限都會(huì)被系統(tǒng)授予哄啄。比如雅任,應(yīng)用被授予READ_EXTERNAL_STORAGE權(quán)限之后风范,如果再申請WRITE_EXTERNAL_STORAGE權(quán)限,系統(tǒng)會(huì)立即授予該權(quán)限沪么。

危險(xiǎn)權(quán)限表格如下

權(quán)限組 權(quán)限
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
  1. 申請權(quán)限的正確姿勢
  • 需要申請的所有權(quán)限在AndroidManifest文件中聲明
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  • 使用時(shí)檢查權(quán)限硼婿,沒有權(quán)限則申請
        //使用兼容庫就無需判斷系統(tǒng)版本
        int hasWriteStoragePermission = ContextCompat.checkSelfPermission(getApplication(), Manifest.permission.WRITE_EXTERNAL_STORAGE);
        if (hasWriteStoragePermission == PackageManager.PERMISSION_GRANTED) {
                        //擁有權(quán)限,執(zhí)行操作
            initScan();
        }else{
                        //沒有權(quán)限禽车,向用戶請求權(quán)限
            ActivityCompat.requestPermissions(thisActivity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MyApplication.CODE_FOR_WRITE_PERMISSION);
        }
  • 覆寫onRequestPermissionsResult方法
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
                //通過requestCode來識(shí)別是否同一個(gè)請求
        if (requestCode == CODE_FOR_WRITE_PERMISSION){
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                //用戶同意寇漫,執(zhí)行操作
                initScan();
            }else{
                //用戶不同意,向用戶展示該權(quán)限作用
                if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                    new AlertDialog.Builder(thisActivity)
                            .setMessage(R.string.storage_permissions_remind)
                            .setPositiveButton("OK", (dialog1, which) ->
                                    ActivityCompat.requestPermissions(this,
                                            new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                                            EventConstConfig.CODE_FOR_CAMERA_PERMISSION))
                            .setNegativeButton("Cancel", null)
                            .create()
                            .show();
                }
            }
        }
    }

shouldShowRequestPermissionRationale方法返回值分幾種情況殉摔,怎么使用看應(yīng)用的具體交互需求州胳。

  1. 第一次請求該權(quán)限,返回false逸月。
  2. 請求過該權(quán)限并被用戶拒絕栓撞,返回true。
  3. 請求過該權(quán)限彻采,但用戶拒絕的時(shí)候勾選不再提醒腐缤,返回false。
  1. 申請權(quán)限的幾個(gè)小細(xì)節(jié)
  • 使用兼容庫
    checkSelfPermission肛响、requestPermissions等幾個(gè)權(quán)限相關(guān)的方法用v4包里的可以兼容6.0以下版本岭粤,否則需要包一層版本判斷。

  • targetSDKVersion的問題
    我遇到的問題就是這個(gè)特笋,有個(gè)細(xì)節(jié)沒注意到剃浇。Android系統(tǒng)觸發(fā)動(dòng)態(tài)申請權(quán)限的條件其實(shí)有兩個(gè),設(shè)備系統(tǒng)版本在Android 6.0以上并且targetSDKVersion>=23猎物。因此其實(shí)在targetSDKVersion版本小于23的情況下虎囚,即使在6.0以上的設(shè)備運(yùn)行也不會(huì)掛,但會(huì)在安裝時(shí)列出所有權(quán)限蔫磨,同6.0以下的設(shè)備淘讥。官方建議保持targetSDKVersion在最新的版本。

  1. 使用第三方庫easypermissions
    申請權(quán)限的第三方庫有很多堤如,但沒遇到特別簡潔的蒲列,也就沒有特地去研究和使用,避免導(dǎo)入太多第三方庫搀罢,easypermissions這個(gè)庫是其中一個(gè)項(xiàng)目用到的蝗岖,這里簡單的提一下。
  • 導(dǎo)入easypermissions
compile 'pub.devrel:easypermissions:0.1.9'
  • 檢查權(quán)限榔至,沒有就進(jìn)行申請
        if (!EasyPermissions.hasPermissions(this, Manifest.permission.CAMERA)) {
            EasyPermissions.requestPermissions(this, getString(R.string.camera_peemission_tip), CAMERA_REQUEST_CODE, Manifest.permission.CAMERA);
        }
  • 覆寫方法
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        // Forward results to EasyPermissions
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
    }

    @Override
    public void onPermissionsGranted(int requestCode, List<String> perms) {
//        light();
    }

    @Override
    public void onPermissionsDenied(int requestCode, List<String> perms) {
        Dialog dialog = new AlertDialog.Builder(this, R.style.MyAlertDialogStyle)
                .setTitle(R.string.tips)
                .setMessage(R.string.camera_peemission_tip)
                .setPositiveButton(R.string.to_open, (dialog2, which) -> {
                    startActivity(new Intent(Settings.ACTION_APPLICATION_SETTINGS));
                })
                .setNegativeButton(R.string.cancel, (dialog3, which) -> {
                    dialog3.dismiss();
                })
                .create();
        dialog.show();
    }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末抵赢,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌铅鲤,老刑警劉巖划提,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異彩匕,居然都是意外死亡腔剂,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門驼仪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來掸犬,“玉大人,你說我怎么就攤上這事绪爸⊥逅椋” “怎么了?”我有些...
    開封第一講書人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵奠货,是天一觀的道長介褥。 經(jīng)常有香客問我,道長递惋,這世上最難降的妖魔是什么柔滔? 我笑而不...
    開封第一講書人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮萍虽,結(jié)果婚禮上睛廊,老公的妹妹穿的比我還像新娘。我一直安慰自己杉编,他們只是感情好超全,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著邓馒,像睡著了一般嘶朱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上光酣,一...
    開封第一講書人閱讀 49,821評(píng)論 1 290
  • 那天疏遏,我揣著相機(jī)與錄音,去河邊找鬼救军。 笑死改览,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的缤言。 我是一名探鬼主播,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼视事,長吁一口氣:“原來是場噩夢啊……” “哼胆萧!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬榮一對情侶失蹤跌穗,失蹤者是張志新(化名)和其女友劉穎订晌,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蚌吸,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡锈拨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了羹唠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片奕枢。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖佩微,靈堂內(nèi)的尸體忽然破棺而出缝彬,到底是詐尸還是另有隱情,我是刑警寧澤哺眯,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布谷浅,位于F島的核電站,受9級(jí)特大地震影響奶卓,放射性物質(zhì)發(fā)生泄漏一疯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一夺姑、第九天 我趴在偏房一處隱蔽的房頂上張望墩邀。 院中可真熱鬧,春花似錦瑟幕、人聲如沸磕蒲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽辣往。三九已至,卻和暖如春殖卑,著一層夾襖步出監(jiān)牢的瞬間站削,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來泰國打工孵稽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留许起,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓菩鲜,卻偏偏與公主長得像园细,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子接校,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349

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