日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > Android >内容正文

Android

Android权限申请的学习实践

發(fā)布時(shí)間:2024/9/21 Android 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android权限申请的学习实践 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1.引子

在換到Android手機(jī)之前,對(duì)Android系統(tǒng)的印象是這系統(tǒng)app的跑馬場(chǎng),app可以任意索取各種權(quán)限,隨意竊取各種隱私,換手機(jī)后才知道Android系統(tǒng)對(duì)權(quán)限的管理已有很大的改觀,索取的每個(gè)危險(xiǎn)權(quán)限都需要提示用戶,當(dāng)然Android只是盡可能提示用戶,還是存在著用戶不同意就不給用的情況。

權(quán)限管理的改進(jìn)給開發(fā)者增加了一定工作量,申請(qǐng)危險(xiǎn)權(quán)限不再是簡(jiǎn)單的在AndroidManifest.xml添加一行代碼的事,而是需要提示用戶進(jìn)行動(dòng)態(tài)申請(qǐng)。了解動(dòng)態(tài)申請(qǐng)之后,覺(jué)得沒(méi)多復(fù)雜,但不了解時(shí),只知道在網(wǎng)上拷貝現(xiàn)成代碼片段,碰到需要申請(qǐng)新的權(quán)限就不知道從何下手。我曾經(jīng)粘貼了幾段動(dòng)態(tài)申請(qǐng)權(quán)限代碼,就是因?yàn)椴涣私庠?#xff0c;只會(huì)復(fù)制粘貼,代碼雖然能夠運(yùn)行,但無(wú)比臃腫。

為此通過(guò)此文梳理Android權(quán)限,以便掌握Android權(quán)限管理,拒絕做Copy工程師。

2.權(quán)限的作用

權(quán)限的目的是保護(hù)Android用戶的隱私。作為一個(gè)可以任意定制的開源系統(tǒng),權(quán)限真是用戶隱私最后的屏障,Android系統(tǒng)要求,在默認(rèn)情況下,任何應(yīng)用程序無(wú)權(quán)執(zhí)行會(huì)對(duì)其他應(yīng)用程序、操作系統(tǒng)或用戶產(chǎn)生不利影響的任何操作。包括讀寫用戶的私人數(shù)據(jù)(例如聯(lián)系人或電子郵件),讀寫其他應(yīng)用程序的文件,訪問(wèn)網(wǎng)絡(luò)等等。要執(zhí)行這些操作,Android應(yīng)用必須獲得對(duì)應(yīng)的權(quán)限。

Android有上百種權(quán)限,可分為三大類,一類是普通權(quán)限,一類是簽名權(quán)限,還有一類是危險(xiǎn)權(quán)限。

其中普通權(quán)限是指那些不會(huì)威脅到用戶安全和隱私的權(quán)限,例如設(shè)置鬧鐘權(quán)限。授予app普通權(quán)限只需要在AndroidManifest.xml文件里聲明,系統(tǒng)會(huì)自動(dòng)授權(quán),不需要用戶確認(rèn),用戶也無(wú)法做撤銷操作。

第二種是簽名權(quán)限,這類權(quán)限同樣是在應(yīng)用安裝時(shí)由系統(tǒng)授予,不過(guò)并不是無(wú)條件授予,想使用權(quán)限的應(yīng)用程序必須與定義該權(quán)限的應(yīng)用程序使用相同的證書才行,例如應(yīng)用A使用證書A簽名,定義了一個(gè)簽名權(quán)限,應(yīng)用B想使用這個(gè)權(quán)限,必須由證書A簽名。簽名權(quán)限使用的場(chǎng)景如一個(gè)公司有多個(gè)app,為了能讓這些app能夠相互調(diào)用,但不希望被外部app調(diào)用,就可以通過(guò)自定義一個(gè)簽名調(diào)用權(quán)限實(shí)現(xiàn)。

最后再來(lái)看第三類危險(xiǎn)權(quán)限,危險(xiǎn)權(quán)限之所以被危險(xiǎn),是因?yàn)檫@類權(quán)限涉及到用戶個(gè)人敏感數(shù)據(jù)資源,或者影響用戶存儲(chǔ)的數(shù)據(jù)或者其他應(yīng)用程序的數(shù)據(jù),例如讀取用戶聯(lián)系人,打開麥克風(fēng)等,江湖上一直有傳言,目前許多app會(huì)偷偷打開麥克風(fēng)竊聽(tīng)用戶對(duì)話,然后根據(jù)對(duì)話內(nèi)容精準(zhǔn)推送廣告,這類傳言像是都市傳說(shuō),因?yàn)榫哂猩衩匦阅軓V泛傳播,要知道,原版Android系統(tǒng)中,應(yīng)用索取危險(xiǎn)權(quán)限必須需要向用戶提示,在用戶許可之前,應(yīng)用是無(wú)法獲取權(quán)限的。不過(guò)Android系統(tǒng)畢竟是開源的,將原生Android權(quán)限管理功能修改倒是有可能雖然用戶沒(méi)同意,但app仍可以獲得權(quán)限,這話題就在本文之外了,個(gè)人認(rèn)為有其他更好的方法來(lái)竊取隱私,竊聽(tīng)對(duì)話是成本較高的那種,用起來(lái)不值得。

如前所述,權(quán)限有上百種,一一記住不現(xiàn)實(shí),其實(shí)我們只要知道哪些是危險(xiǎn)權(quán)限,危險(xiǎn)權(quán)限之外都是普通權(quán)限。

危險(xiǎn)權(quán)限總共9個(gè)分組,24個(gè)權(quán)限,如果我們申請(qǐng)的權(quán)限不在這個(gè)表中,那就說(shuō)明是普通權(quán)限,而權(quán)限分組意思是組內(nèi)的這些權(quán)限同屬于一個(gè)組,用戶同意授權(quán)一個(gè)權(quán)限組,則組內(nèi)的所有權(quán)限都會(huì)授予,比如,應(yīng)用被授予READ_EXTERNAL_STORAGE權(quán)限之后,如果再申請(qǐng)WRITE_EXTERNAL_STORAGE權(quán)限,系統(tǒng)會(huì)立即授予該權(quán)限,不再向用戶提示。

3.申請(qǐng)權(quán)限步驟和示例

  • 普通權(quán)限申請(qǐng)很簡(jiǎn)單,只需要在AndroidManifest.xml文件申請(qǐng)即可,例如申請(qǐng)?jiān)O(shè)置鬧鈴的權(quán)限
  • <uses-permission android:name="android.permission.SET_ALARM" />
  • 簽名權(quán)限申請(qǐng)類似,只需要修飾protectionLevel成signature即可,例如設(shè)置一個(gè)自定義權(quán)限成簽名權(quán)限,代碼如下,其他應(yīng)用申請(qǐng)這個(gè)權(quán)限時(shí)必須具有相同的簽名才能授予<permissionandroid:name="com.test.permission.act"android:protectionLevel="signature"/>
  • 申請(qǐng)危險(xiǎn)權(quán)限重點(diǎn)說(shuō)一下,一方面和普通權(quán)限一樣,仍需要在AndroidManifest.xml文件聲明,另一方面,還需要額外動(dòng)態(tài)申請(qǐng)。下面以申請(qǐng)存儲(chǔ)讀寫權(quán)限來(lái)作為例子說(shuō)明。
    • 在AndroidManifest文件中聲明,這一步不可少

      <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
      • 在應(yīng)用啟動(dòng)代碼中檢查權(quán)限,確認(rèn)應(yīng)用是否已經(jīng)擁有讀寫存儲(chǔ)的權(quán)限。這部分是在代碼中實(shí)現(xiàn)了,所以叫動(dòng)態(tài)申請(qǐng)。Android中使用ContextCompat.checkSelfPermission()檢查權(quán)限的授權(quán)情況,這個(gè)方法第一個(gè)參數(shù)是上下文Context,第二個(gè)參數(shù)是所要申請(qǐng)權(quán)限的名稱,名稱當(dāng)然不能隨便寫阿貓阿狗,而是有特定名稱,建議直接調(diào)Android在Manifest.permission中已定義好的名稱,比如現(xiàn)在要申請(qǐng)的讀外部存儲(chǔ)權(quán)限是Manifest.permission.WRITE_EXTERNAL_STORAGE。該方法返回一個(gè)int類型的PERMISSION_GRANTED(同意)或者PERMISSION_DENIED`(拒絕)。一般來(lái)說(shuō),程序初次安裝后,所申請(qǐng)的權(quán)限的時(shí)候都是處于PERMISSION_DENIED狀態(tài),需要提出申請(qǐng),用戶同意之后不需要再次申請(qǐng),除非卸載應(yīng)用重新安裝或者到系統(tǒng)設(shè)置里把權(quán)限給關(guān)了;

      • 接下來(lái)是申請(qǐng)權(quán)限,申請(qǐng)使用的方法requestPermissions(),該方法傳入?yún)?shù)有三個(gè),第一個(gè)是Activity、 第二個(gè)是需要請(qǐng)求授權(quán)的權(quán)限字符串?dāng)?shù)組,可以把想申請(qǐng)的權(quán)限名稱都列入其中,第三個(gè)是識(shí)別權(quán)限請(qǐng)求的請(qǐng)求代碼,在權(quán)限申請(qǐng)的回調(diào)函數(shù)onRequestPermissionsResult()用得著,該值必須大于或等于0,其作用在回調(diào)函數(shù)里再詳細(xì)說(shuō)明,這里只要理解成是一個(gè)自定義的標(biāo)記。需要注意的是,申請(qǐng)權(quán)限是異步處理,也就是說(shuō),代碼不會(huì)阻塞在等用戶點(diǎn)擊,而是用戶點(diǎn)擊后再回調(diào)onRequestPermissionsResult()。以上兩個(gè)步驟的代碼如下:

    //檢查應(yīng)用是否已經(jīng)擁有權(quán)限if(ActivityCompat.checkSelfPermission(MainActivity.this,Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){// 說(shuō)明沒(méi)有該權(quán)限,就需要申請(qǐng)權(quán)限ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);}else {//已經(jīng)擁有權(quán)限,做進(jìn)一步操作}
    • 接下來(lái)是覆寫申請(qǐng)權(quán)限回調(diào)函數(shù)onRequestPermissionsResult(),對(duì)權(quán)限申請(qǐng)做后續(xù)處理,該回調(diào)函數(shù)有三個(gè)返回結(jié)果,第一個(gè)requestCode,這個(gè)參數(shù)就是在requestPermissions()提到的識(shí)別權(quán)限的請(qǐng)求代碼,作用就是一個(gè)回執(zhí)單號(hào),根據(jù)這個(gè)單號(hào)我們能確定是我們申請(qǐng)權(quán)限的處理結(jié)果,也就是說(shuō),在申請(qǐng)權(quán)限時(shí)傳入這個(gè)參數(shù),在處理結(jié)束后,回調(diào)函數(shù)原封不動(dòng)給回來(lái),這樣我們就知道是不是我們的處理結(jié)果;第二個(gè)參數(shù)是權(quán)限字符串?dāng)?shù)組,也就是我們?cè)趓equestPermissions()填的權(quán)限字符串?dāng)?shù)組;第三個(gè)參數(shù)用戶響應(yīng)的數(shù)組,用戶的對(duì)每個(gè)申請(qǐng)權(quán)限的批復(fù)情況就是在這個(gè)數(shù)組里,這個(gè)數(shù)組的個(gè)數(shù)是和申請(qǐng)權(quán)限數(shù)組是一一對(duì)應(yīng)的。代碼如下:
    @Overridepublic void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {//通過(guò)requestCode來(lái)識(shí)別是否同一個(gè)請(qǐng)求if (requestCode == 1){if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){//用戶同意執(zhí)行的操作}else{//用戶不同意不同意執(zhí)行的操作,例如提示用戶不同意不給用。。。}}}

    以上如果申請(qǐng)單個(gè)權(quán)限,如果申請(qǐng)多個(gè)權(quán)限又怎么操作呢?基本步驟和申請(qǐng)單個(gè)權(quán)限類似,但因?yàn)槭嵌鄠€(gè)權(quán)限,還需要做一下額外處理,例如怎么判斷是否每個(gè)權(quán)限都授權(quán)了。下面以多申請(qǐng)一個(gè)錄音權(quán)限來(lái)說(shuō)明

    • 同樣,首先在AndroidManifest.xml做聲明
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.RECORD_AUDIO" />
    • 準(zhǔn)備工作是創(chuàng)建一個(gè)權(quán)限字符串?dāng)?shù)組和聲明一個(gè)權(quán)限列表list,其中列表用于判斷每個(gè)權(quán)限的處理情況String[] permissions = new String[]{Manifest.permission.RECORD_AUDIO,Manifest.permission.READ_EXTERNAL_STORAGE}; List<String> mPermissionList = new ArrayList<>();
      • 判斷每個(gè)權(quán)限授權(quán)情況,未同意的列入申請(qǐng)名單,然后申請(qǐng)權(quán)限
    private void myRequestPermission() {mPermissionList.clear();//逐個(gè)判斷權(quán)限是否已經(jīng)通過(guò)for (int i = 0; i < permissions.length; i++) {if (ContextCompat.checkSelfPermission(this, permissions[i]) != PackageManager.PERMISSION_GRANTED) { //如果未授權(quán),則添加到列表中mPermissionList.add(permissions[i]);}}//申請(qǐng)權(quán)限,如果列表不為空,說(shuō)明有權(quán)限需要申請(qǐng)if (mPermissionList.size() > 0) {//有權(quán)限沒(méi)有通過(guò),需要申請(qǐng)ActivityCompat.requestPermissions(this, permissionsList.toArray(new String[permissionsList.size()]), 1);}else{//已有權(quán)限,做進(jìn)一步操作}}
    • 覆寫請(qǐng)求權(quán)限回調(diào)的方法,做后續(xù)處理
    @Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);switch (requestCode){case 1:int resultLength = grantResults.length;//說(shuō)明回調(diào)成功了,權(quán)限授權(quán)被允許if(resultLength > 0){for(int grantCode : grantResults){if(grantCode == PackageManager.PERMISSION_GRANTED){Toast.makeText(this, "授權(quán)成功", Toast.LENGTH_SHORT).show();}else{Toast.makeText(this, "授權(quán)失敗", Toast.LENGTH_SHORT).show();}}}break;default:break;}}

    4.總結(jié)

    經(jīng)過(guò)了解Android權(quán)限后,可以看出申請(qǐng)權(quán)限過(guò)程不是很復(fù)雜,普通權(quán)限比較簡(jiǎn)單,只需要在AndroidManifest.xml中聲明即可,危險(xiǎn)權(quán)限不僅需要在AndroidManifest.xml聲明,同時(shí)還需要在代碼中動(dòng)態(tài)申請(qǐng),首先是使用checkSelfPermission()檢查是否某個(gè)危險(xiǎn)權(quán)限是否已授權(quán),如果沒(méi)有授權(quán),則requestPermissions()申請(qǐng)授權(quán),記得這是異步處理,代碼不會(huì)阻塞在等待用戶授權(quán)位置,接下來(lái)就是處理授權(quán)情況,系統(tǒng)回調(diào)onRequestPermissionsResult通知我們處理結(jié)果,我們根據(jù)這個(gè)結(jié)果做進(jìn)一步處理。同時(shí)申請(qǐng)多個(gè)權(quán)限稍微復(fù)雜一點(diǎn),需要處理每個(gè)權(quán)限的處理情況。

    總結(jié)

    以上是生活随笔為你收集整理的Android权限申请的学习实践的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。