Android 6.0 運行時權(quán)限處理解析

1.概述


不知道大家有沒有遇到過這種情況器一,開發(fā)app的時候發(fā)現(xiàn)自己手機選擇照片是正常的课锌,測試那邊的一臺手機怎么搞都不行,然后查看版本之后才發(fā)現(xiàn)是6.0的手機祈秕。
  
  隨著Android 6.0 7.0 我們開發(fā)者所要應(yīng)對的主要就是新版本SDK帶來的一些變化渺贤,既然是程序員那么我們肯定就特別關(guān)注開發(fā)部分的變化,其中之一就是權(quán)限處理请毛。那么在6.0及以上版本我們的危險權(quán)限都需要在運行的時候去申請志鞍,之前都是在清單文件中配置即可,現(xiàn)在就不行了需要加代碼申請方仿。
  

這里寫圖片描述

2.運行時權(quán)限的檢測


2.1. Android6.0之后的權(quán)限差別
  
  對于6.0以下的權(quán)限及在安裝的時候固棚,根據(jù)權(quán)限聲明產(chǎn)生一個權(quán)限列表街州,用戶只有在同意之后才能完成app的安裝。而在6.0以后玻孟,我們可以直接安裝,當(dāng)app需要權(quán)限是會給予用戶提示用戶可以選擇同意和拒絕鳍征。

新的權(quán)限機制更好的保護了用戶的隱私黍翎,Google將權(quán)限分為兩類,一類是Normal Permissions艳丛,這類權(quán)限一般不涉及用戶隱私匣掸,是不需要用戶進行授權(quán)的,比如訪問網(wǎng)絡(luò)等氮双;另一類是Dangerous Permission碰酝,一般是涉及到用戶隱私的,需要用戶進行授權(quán)戴差,比如讀取sdcard送爸、打電話等等。

看幾個Normal Permissions:

INTERNET
GET_PACKAGE_SIZE
ACCESS_NETWORK_STATE
ACCESS_NOTIFICATION_POLICY
ACCESS_WIFI_STATE
CHANGE_WIFI_STATE
VIBRATE

看幾組Dangerous Permissions:

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
  
group:android.permission-group.CAMERA
  permission:android.permission.CAMERA

group:android.permission-group.STORAGE
  permission:android.permission.READ_EXTERNAL_STORAGE
  permission:android.permission.WRITE_EXTERNAL_STORAGE

你會發(fā)現(xiàn)dangerous permissions暖释,危險權(quán)限都是一組一組的袭厂,這是個什么概念呢?又或是有什么用呢球匕?如果app運行在Android 6.x的機器上纹磺,對于授權(quán)機制是這樣的。如果你申請某個危險的權(quán)限亮曹,假設(shè)你的app早已被用戶授權(quán)了同一組的某個危險權(quán)限橄杨,那么系統(tǒng)會立即授權(quán),而不需要用戶去點擊授權(quán)照卦。比如你的app對READ_CONTACTS已經(jīng)授權(quán)了式矫,當(dāng)你的app申請WRITE_CONTACTS時,系統(tǒng)會直接授權(quán)通過窄瘟。此外衷佃,對于申請時彈出的dialog上面的文本說明也是對整個權(quán)限組的說明,而不是單個權(quán)限(ps:這個dialog是不能進行定制的)蹄葱。
  
  
2.2. 代碼變化

2.2.1.之前寫都是老套路直接上代碼(已電話撥打為例):

        Intent intent = new Intent(Intent.ACTION_CALL);
        Uri data = Uri.parse("tel:" + mPhoneNumber);
        intent.setData(data);
        startActivity(intent);

2.2.2.但是現(xiàn)在不行啦氏义,我們需要去檢測該權(quán)限有沒有背用戶授予過,如果沒有則需要申請打電話權(quán)限图云,如果有授予過可以直接撥打電話惯悠。
ContextCompat.checkSelfPermission:檢測權(quán)限
ActivityCompat.requestPermissions:申請權(quán)限

// ContextCompat.checkSelfPermission()
// 方法返回值為PackageManager.PERMISSION_DENIED或者PackageManager.PERMISSION_GRANTED。
// 當(dāng)返回GRANTED表示有該權(quán)限竣况,DENIED表示沒有該權(quán)限克婶。

if(ContextCompat.checkSelfPermission(this,Manifest.permission.CALL_PHONE)
    != PackageManager.PERMISSION_GRANTED){
    
            // 沒有該權(quán)限 申請打電話權(quán)限
            //  三個參數(shù) 第一個參數(shù)是 Context , 第二個參數(shù)是用戶需要申請的權(quán)限字符串?dāng)?shù)組,第三個參數(shù)是請求碼 主要用來處理用戶選擇的返回結(jié)果
            
            ActivityCompat.requestPermissions(this,new String[]{"Manifest.permission.CALL_PHONE"},CALL_PHONE_REQUEST_CODE);
        }else {
            // 有該權(quán)限,直接打電話
            Intent intent = new Intent(Intent.ACTION_CALL);
            Uri data = Uri.parse("tel:" + 137XXXXXXXX);
            intent.setData(data);
            startActivity(intent);
        }

2.2.3. 處理回調(diào)
  如果用戶同意或是拒絕那么會回調(diào)onRequestPermissionsResult()情萤,別看錯了不是onActivityResult()

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        if(requestCode == CALL_PHONE_REQUEST_CODE){
            if (grantResults !=null&&grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission Granted  通過  打電話
                
                Intent intent = new Intent(Intent.ACTION_CALL);
                Uri data = Uri.parse("tel:" + 137XXXXXXXX);
                intent.setData(data);
                startActivity(intent);
            } else {
                // Permission Denied   被拒絕
                Toast.makeText(this,"權(quán)限被拒絕了",Toast.LENGTH_SHORT).show();
            }
        }
    }

2.2.4. 簡單的例子

public class MainActivity extends AppCompatActivity {
    // 打電話權(quán)限申請的請求碼
    private static final int CALL_PHONE_REQUEST_CODE = 0x0011;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void phoneClick(View view){
        if(ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE)
                != PackageManager.PERMISSION_GRANTED){
            Toast.makeText(this, "申請權(quán)限", Toast.LENGTH_SHORT).show();
            ActivityCompat.requestPermissions(this,
                    new String[]{"Manifest.permission.CALL_PHONE"}, CALL_PHONE_REQUEST_CODE);
        }else {
            callPhone();
        }
    }

    /**
    * 撥打電話
    **/
    private void callPhone() {
        Intent intent = new Intent(Intent.ACTION_CALL);
        Uri data = Uri.parse("tel:147****2514");
        intent.setData(data);
        startActivity(intent);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if(requestCode == CALL_PHONE_REQUEST_CODE){
            if (grantResults !=null&&grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission Granted
                callPhone();
            } else {
                // Permission Denied
                Toast.makeText(this,"權(quán)限被拒絕了",Toast.LENGTH_SHORT).show();
            }
        }
    }
}

上面就是6.0以上的版本運行時權(quán)限處理鸭蛙,但是我們會發(fā)現(xiàn)一個問題,如果都得這么干那需要些多少代碼量筋岛?下面我們就利用反射加注解的方式封裝我們的權(quán)限處理框架娶视,請看這里Android 6.0 運行時權(quán)限封裝框架

這里寫圖片描述

  
  項目的代碼不能夠發(fā)給大家,里面涉及到后臺接口以及數(shù)據(jù)加密睁宰,如果大家感興趣可以看一下我錄的視頻:http://pan.baidu.com/s/1bpqqkGn 肪获。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市柒傻,隨后出現(xiàn)的幾起案子孝赫,更是在濱河造成了極大的恐慌,老刑警劉巖红符,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件青柄,死亡現(xiàn)場離奇詭異,居然都是意外死亡违孝,警方通過查閱死者的電腦和手機刹前,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來雌桑,“玉大人喇喉,你說我怎么就攤上這事⌒?樱” “怎么了拣技?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長耍目。 經(jīng)常有香客問我膏斤,道長,這世上最難降的妖魔是什么邪驮? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任莫辨,我火速辦了婚禮,結(jié)果婚禮上毅访,老公的妹妹穿的比我還像新娘沮榜。我一直安慰自己,他們只是感情好喻粹,可當(dāng)我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布蟆融。 她就那樣靜靜地躺著,像睡著了一般守呜。 火紅的嫁衣襯著肌膚如雪型酥。 梳的紋絲不亂的頭發(fā)上山憨,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天,我揣著相機與錄音弥喉,去河邊找鬼郁竟。 笑死,一個胖子當(dāng)著我的面吹牛由境,可吹牛的內(nèi)容都是我干的枪孩。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼藻肄,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了拒担?” 一聲冷哼從身側(cè)響起嘹屯,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎从撼,沒想到半個月后州弟,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡低零,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年婆翔,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片掏婶。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡啃奴,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出雄妥,到底是詐尸還是另有隱情最蕾,我是刑警寧澤,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布老厌,位于F島的核電站瘟则,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏枝秤。R本人自食惡果不足惜醋拧,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望淀弹。 院中可真熱鬧丹壕,春花似錦、人聲如沸垦页。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽痊焊。三九已至盏袄,卻和暖如春忿峻,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背辕羽。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工逛尚, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人刁愿。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓绰寞,卻偏偏與公主長得像,于是被迫代替她去往敵國和親铣口。 傳聞我的和親對象是個殘疾皇子滤钱,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,055評論 2 355

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