【從 0 開(kāi)始開(kāi)發(fā)一款直播 APP】13 Android 6.0 運(yùn)行時(shí)權(quán)限

本文為菜鳥(niǎo)窩作者蔣志碧的連載乳幸∨缕罚“從 0 開(kāi)始開(kāi)發(fā)一款直播 APP ”系列來(lái)聊聊時(shí)下最火的直播 APP治笨,如何完整的實(shí)現(xiàn)一個(gè)類(lèi)"騰訊直播"的商業(yè)化項(xiàng)目

一考婴、前言

Android 6.0 版本(Api 23) 及其以上系統(tǒng)引入運(yùn)行時(shí)權(quán)限 — 默認(rèn)所有涉及用戶(hù)隱私的權(quán)限都被關(guān)閉,我們?cè)?AndroidManifest.xml 中申請(qǐng)權(quán)限之后杆麸,依然還需要?jiǎng)討B(tài)申請(qǐng)權(quán)限搁进,不然每次安裝完APP后,就需要在「設(shè)置 -> 應(yīng)用 -> APP」中打開(kāi)所需權(quán)限昔头。

Android 系統(tǒng)包含默認(rèn)的授權(quán)提示框饼问,但是仍需要我們?cè)O(shè)置自己的頁(yè)面,原因的系統(tǒng)提供的授權(quán)框會(huì)有不再提示選項(xiàng)揭斧。如果用戶(hù)選擇莱革,則無(wú)法觸發(fā)授權(quán)提示峻堰,使用自定義的提示頁(yè)面,可以給予用戶(hù)手動(dòng)修改授權(quán)的指導(dǎo)盅视。

統(tǒng)一授權(quán)

如果設(shè)備運(yùn)行的是 Android 5.1(API 級(jí)別 22)或更低版本捐名,并且應(yīng)用的 targetSdkVersion 是 22 或更低版本,則系統(tǒng)會(huì)在用戶(hù)安裝應(yīng)用時(shí)要求用戶(hù)授予權(quán)限闹击。如果將新權(quán)限添加到更新的應(yīng)用版本镶蹋,系統(tǒng)會(huì)在用戶(hù)更新應(yīng)用時(shí)要求授予該權(quán)限。用戶(hù)一旦安裝應(yīng)用赏半,他們撤銷(xiāo)權(quán)限的唯一方式是卸載應(yīng)用贺归。

運(yùn)行時(shí)權(quán)限

如果設(shè)備運(yùn)行的是 Android 6.0(API 級(jí)別 23)或更高版本,并且應(yīng)用的 targetSdkVersion 是 23 或更高版本断箫,則應(yīng)用在運(yùn)行時(shí)向用戶(hù)請(qǐng)求權(quán)限拂酣。用戶(hù)可隨時(shí)調(diào)用權(quán)限,因此應(yīng)用在每次運(yùn)行時(shí)均需檢查自身是否具備所需的權(quán)限仲义。

二婶熬、權(quán)限分組

Android 6.0 引入運(yùn)行時(shí)權(quán)限,所有權(quán)限仍然需要在 AndroidManifest 中聲明光坝,但是當(dāng)訪問(wèn)需要的權(quán)限時(shí),活動(dòng)或片段必須驗(yàn)證權(quán)限已被授予或使用支持庫(kù)的調(diào)用請(qǐng)求缺少的權(quán)限甥材。

權(quán)限分為三類(lèi):

正常(Normal Protection)權(quán)限
危險(xiǎn)(Dangerous)權(quán)限
特殊(Particular)權(quán)限
其它權(quán)限(一般很少用到)

正常權(quán)限

正常權(quán)限」涵蓋應(yīng)用需要訪問(wèn)其沙盒外部數(shù)據(jù)或資源盯另,但對(duì)用戶(hù)隱私或其他應(yīng)用操作風(fēng)險(xiǎn)很小的區(qū)域。例如洲赵,設(shè)置時(shí)區(qū)的權(quán)限就是正常權(quán)限鸳惯。如果應(yīng)用聲明其需要正常權(quán)限,系統(tǒng)會(huì)自動(dòng)向應(yīng)用授予該權(quán)限叠萍。

正常權(quán)限具有如下特點(diǎn)

1芝发、對(duì)用戶(hù)隱私?jīng)]用較大影響或者不會(huì)帶來(lái)安全問(wèn)題

2、安裝之后就被賦予這些權(quán)限苛谷,不需要顯示提醒用戶(hù)辅鲸,用戶(hù)也不能取消這些權(quán)限


危險(xiǎn)權(quán)限

危險(xiǎn)權(quán)限涵蓋應(yīng)用需要涉及用戶(hù)隱私信息的數(shù)據(jù)或資源,或者可能對(duì)用戶(hù)存儲(chǔ)的數(shù)據(jù)或其他應(yīng)用的操作產(chǎn)生影響的區(qū)域腹殿。例如独悴,能夠讀取用戶(hù)的聯(lián)系人屬于危險(xiǎn)權(quán)限。如果應(yīng)用聲明其需要危險(xiǎn)權(quán)限锣尉,則用戶(hù)必須明確向應(yīng)用授予該權(quán)限刻炒。

權(quán)限組

所有危險(xiǎn)的 Android 系統(tǒng)權(quán)限都屬于權(quán)限組。如果設(shè)備運(yùn)行的是 Android 6.0(API 級(jí)別 23)自沧,并且應(yīng)用的 targetSdkVersion是 23 或更高版本坟奥,則當(dāng)用戶(hù)請(qǐng)求危險(xiǎn)權(quán)限時(shí)系統(tǒng)會(huì)發(fā)生以下行為:

如果應(yīng)用請(qǐng)求其清單中列出的危險(xiǎn)權(quán)限,而應(yīng)用目前在權(quán)限組中沒(méi)有任何權(quán)限,則系統(tǒng)會(huì)向用戶(hù)顯示一個(gè)對(duì)話框爱谁,描述應(yīng)用要訪問(wèn)的權(quán)限組晒喷。對(duì)話框不描述該組內(nèi)的具體權(quán)限。例如管行,如果應(yīng)用請(qǐng)求 READ_CONTACTS 權(quán)限厨埋,系統(tǒng)對(duì)話框只說(shuō)明該應(yīng)用需要訪問(wèn)設(shè)備的聯(lián)系信息。如果用戶(hù)批準(zhǔn)捐顷,系統(tǒng)將向應(yīng)用授予其請(qǐng)求的權(quán)限荡陷。

如果應(yīng)用請(qǐng)求其清單中列出的危險(xiǎn)權(quán)限,而應(yīng)用在同一權(quán)限組中已有另一項(xiàng)危險(xiǎn)權(quán)限迅涮,則系統(tǒng)會(huì)立即授予該權(quán)限废赞,而無(wú)需與用戶(hù)進(jìn)行任何交互。例如叮姑,如果某應(yīng)用已經(jīng)請(qǐng)求并且被授予了 READ_CONTACTS 權(quán)限唉地,然后它又請(qǐng)求 WRITE_CONTACTS,系統(tǒng)將立即授予該權(quán)限传透。

任何權(quán)限都可屬于一個(gè)權(quán)限組,包括正常權(quán)限和應(yīng)用定義的權(quán)限朱盐。但權(quán)限組僅當(dāng)權(quán)限危險(xiǎn)時(shí)才影響用戶(hù)體驗(yàn)群嗤。可以忽略正常權(quán)限的權(quán)限組兵琳。

如果設(shè)備運(yùn)行的是 Android 5.1(API 級(jí)別 22)或更低版本狂秘,并且應(yīng)用的 targetSdkVersion 是 22 或更低版本,則系統(tǒng)會(huì)在安裝時(shí)要求用戶(hù)授予權(quán)限躯肌。再次強(qiáng)調(diào)者春,系統(tǒng)只告訴用戶(hù)應(yīng)用需要的權(quán)限組,而不告知具體權(quán)限清女。


特殊權(quán)限

有許多權(quán)限其行為方式與正常權(quán)限及危險(xiǎn)權(quán)限都不同钱烟。SYSTEM_ALERT_WINDOW 和 WRITE_SETTINGS 特別敏感,因此大多數(shù)應(yīng)用不應(yīng)該使用它們嫡丙。如果某應(yīng)用需要其中一種權(quán)限忠售,必須在清單中聲明該權(quán)限,并且發(fā)送請(qǐng)求用戶(hù)授權(quán)的 intent迄沫。系統(tǒng)將向用戶(hù)顯示詳細(xì)管理屏幕稻扬,以響應(yīng)該 intent。

SYSTEM_ALERT_WINDOW 設(shè)置懸浮窗

WRITE_SETTINGS 修改系統(tǒng)設(shè)置

SYSTEM_ALERT_WINDOW

允許應(yīng)用使用類(lèi)型 TYPE_APPLICATION_OVERLAY 創(chuàng)建窗口羊瘩,該窗口顯示在所有其他應(yīng)用程序的頂端泰佳。極少的應(yīng)用程序應(yīng)該使用這個(gè)權(quán)限盼砍,這些窗口用于與用戶(hù)的系統(tǒng)級(jí)交互。

Note:如果是 API 23 及其以上版本逝她,用戶(hù)必須通過(guò)權(quán)限管理向應(yīng)用程顯示權(quán)限浇坐。 應(yīng)用程序通過(guò)發(fā)送 ACTION_MANAGE_OVERLAY_PERMISSION action 的隱式 intent 請(qǐng)求用戶(hù)的批準(zhǔn)。 該應(yīng)用程序可以通過(guò)調(diào)用 Settings.canDrawOverlays() 來(lái)檢查是否具有此授權(quán)黔宛。

請(qǐng)求 SYSTEM_ALERT_WINDOW 權(quán)限

private static final int REQUEST_CODE_SYSTEM_ALERT_WINDOW = 1;
private  void requestAlertWindowPermission() {
    Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
    intent.setData(Uri.parse("package:" + getPackageName()));
    startActivityForResult(intent, REQUEST_CODE_SYSTEM_ALERT_WINDOW);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_CODE_SYSTEM_ALERT_WINDOW) {
        if (Settings.canDrawOverlays(this)) {
          Log.i(TAG, "ACTION_MANAGE_OVERLAY_PERMISSION granted");
        }
    }
}

注意:

使用 Action 的 Settings.ACTION_MANAGE_OVERLAY_PERMISSION 啟動(dòng)隱式 Intent近刘。
使用 "package:" + getPackageName() 攜帶 APP 包名信息
使用 Settings.canDrawOverlays(this) 判斷授權(quán)結(jié)果

WRITE_SETTINGS

允許應(yīng)用程序讀取或?qū)懭胂到y(tǒng)設(shè)置。

Note:如果是 API 23 及其以上版本臀晃,則用戶(hù)必須通過(guò)權(quán)限管理向應(yīng)用程序顯式授予該權(quán)限觉渴。 應(yīng)用程序通過(guò)發(fā)送 ACTION_MANAGE_WRITE_SETTINGS 的 action 的隱式 Intent 來(lái)請(qǐng)求用戶(hù)的批準(zhǔn)。 該應(yīng)用程序可以通過(guò)調(diào)用 Settings.System.canWrite() 來(lái)檢查是否具有此授權(quán)徽惋。

請(qǐng)求 WRITE_SETTINGS 權(quán)限

private static final int REQUEST_CODE_WRITE_SETTINGS = 2;
private void requestWriteSettings() {
    Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
    intent.setData(Uri.parse("package:" + getPackageName()));
    startActivityForResult(intent, REQUEST_CODE_WRITE_SETTINGS );
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_CODE_WRITE_SETTINGS) {
        if (Settings.System.canWrite(this)) {
            Log.i(LOGTAG, "WRITE_SETTINGS granted" );
        }
    }
}

注意:

使用 Action 的 Settings.ACTION_MANAGE_WRITE_SETTINGS 啟動(dòng)隱式 Intent案淋。
使用 "package:" + getPackageName() 攜帶 APP 包名信息
使用 Settings.canDrawOverlays(this) 判斷授權(quán)結(jié)果

關(guān)于這兩個(gè)特殊權(quán)限,一般不建議應(yīng)用申請(qǐng)险绘。

三踢京、申請(qǐng)權(quán)限的主要方法

Android 6.0 運(yùn)行時(shí)權(quán)限申請(qǐng)位于 package android.support.v4.app 包中。主要方法有三個(gè):

**1宦棺、權(quán)限通過(guò) ActivityCompat 類(lèi)的 checkSelfPermission() 方法判斷是否有所需權(quán)限瓣距。
**
**2、權(quán)限請(qǐng)求是通過(guò) ActivityCompat 類(lèi)中的 requestPermissions() 方法代咸,在OnRequestPermissionsResultCallback # onRequestPermissionsResult() 方法中回調(diào)蹈丸。
**
3、應(yīng)用程序可以提供一個(gè)額外的合理的使用權(quán)限調(diào)用 Activitycompat # shouldShowRequestPermissionRationale() 方法侣背。Android 原生系統(tǒng)中白华,如果第二次彈出權(quán)限申請(qǐng)的對(duì)話框慨默,會(huì)出現(xiàn)「以后不再?gòu)棾觥沟奶崾究蚍纺停绻脩?hù)勾選了,你再申請(qǐng)權(quán)限厦取,則 shouldShowRequestPermissionRationale() 返回 true潮太,意思是說(shuō)要給用戶(hù)一個(gè)解釋?zhuān)嬖V用戶(hù)為什么要這個(gè)權(quán)限。

四虾攻、運(yùn)行時(shí)權(quán)限示例

以照相機(jī)權(quán)限為例铡买。

1、在 AndroidManifest.xml 文件中申請(qǐng)所需要的權(quán)限霎箍。

<uses-permission android:name="android.permission.CAMERA"/>

2奇钞、在 gradle 中修改 targetSdkVersion 大于或等于 23。

3漂坏、開(kāi)始申請(qǐng)權(quán)限景埃。

權(quán)限檢查

PublishPresenter.java # checkPublishPermission()

@Override
public boolean checkPublishPermission(Activity activity) {
    //1媒至、ActivityCompat.checkSelfPermission() 判斷權(quán)限
    if (Build.VERSION.SDK_INT >= 23) {
        List<String> permissions = new ArrayList<>();
        if (PackageManager.PERMISSION_GRANTED != ActivityCompat.checkSelfPermission(activity, Manifest.permission.CAMERA)) {
            permissions.add(Manifest.permission.CAMERA);
        }
        //2、ActivityCompat.requestPermissions() 申請(qǐng)權(quán)限
        if (permissions.size() != 0) {
           ActivityCompat.requestPermissions(activity
                            , permissions.toArray(new String[0]),
                            Constants.WRITE_PERMISSION_REQ_CODE);
          return false;
        }
     }
  return true;
}

方法回調(diào)

PublishActivity.java # onRequestPermissionsResult()

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode){
        case Constants.WRITE_PERMISSION_REQ_CODE:
            for (int ret:grantResults){
                if (ret != PackageManager.PERMISSION_GRANTED){
                    return;
                }
            }
            mPermission = true;
            break;
        default:
            break;
    }
}

五谷徙、運(yùn)行效果

當(dāng)進(jìn)入該界面拒啰,系統(tǒng)就會(huì)判斷是否具有照相機(jī)權(quán)限,沒(méi)有則會(huì)彈出對(duì)話框提示用戶(hù)添加權(quán)限完慧。


詳情請(qǐng)轉(zhuǎn)至 GitHub

參考:

http://www.what21.com/article/a_3_1483187432030.html

http://droidyue.com/blog/2016/01/17/understanding-marshmallow-runtime-permission/

https://developer.android.com/guide/topics/security/permissions.html?hl=zh-cn#normal-dangerous

擼這個(gè)項(xiàng)目的一半谋旦,你就是大神 , 戳http://mp.weixin.qq.com/s/ZagocTlDfxZpC2IjUSFhHg

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市屈尼,隨后出現(xiàn)的幾起案子册着,更是在濱河造成了極大的恐慌,老刑警劉巖鸿染,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件指蚜,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡涨椒,警方通過(guò)查閱死者的電腦和手機(jī)摊鸡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蚕冬,“玉大人免猾,你說(shuō)我怎么就攤上這事《谌龋” “怎么了猎提?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)旁蔼。 經(jīng)常有香客問(wèn)我锨苏,道長(zhǎng),這世上最難降的妖魔是什么棺聊? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任伞租,我火速辦了婚禮,結(jié)果婚禮上限佩,老公的妹妹穿的比我還像新娘葵诈。我一直安慰自己,他們只是感情好祟同,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布作喘。 她就那樣靜靜地躺著,像睡著了一般晕城。 火紅的嫁衣襯著肌膚如雪泞坦。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,031評(píng)論 1 285
  • 那天砖顷,我揣著相機(jī)與錄音贰锁,去河邊找鬼主之。 笑死,一個(gè)胖子當(dāng)著我的面吹牛李根,可吹牛的內(nèi)容都是我干的槽奕。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼房轿,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼粤攒!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起囱持,我...
    開(kāi)封第一講書(shū)人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤夯接,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后纷妆,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體盔几,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年掩幢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了逊拍。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡际邻,死狀恐怖芯丧,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情世曾,我是刑警寧澤缨恒,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站轮听,受9級(jí)特大地震影響骗露,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜血巍,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一萧锉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧藻茂,春花似錦驹暑、人聲如沸玫恳。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)京办。三九已至掀序,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間惭婿,已是汗流浹背不恭。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工叶雹, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人换吧。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓折晦,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親沾瓦。 傳聞我的和親對(duì)象是個(gè)殘疾皇子满着,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

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