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

歡迎訪問 生活随笔!

生活随笔

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

Android

Android 6.0 动态权限申请

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

1. 概述

Android 6.0 (API 23) 之前應(yīng)用的權(quán)限在安裝時(shí)全部授予,運(yùn)行時(shí)應(yīng)用不再需要詢問用戶。在 Android 6.0 或更高版本對(duì)權(quán)限進(jìn)行了分類,對(duì)某些涉及到用戶隱私的權(quán)限可在運(yùn)行時(shí)根據(jù)用戶的需要?jiǎng)討B(tài)授予。這樣就不需要在安裝時(shí)被強(qiáng)迫同意某些權(quán)限。

2. 正常權(quán)限 和 危險(xiǎn)權(quán)限

Android系統(tǒng)權(quán)限分為幾個(gè)保護(hù)級(jí)別。需要了解的兩個(gè)最重要保護(hù)級(jí)別是?正常權(quán)限?和?危險(xiǎn)權(quán)限:

(1)正常權(quán)限:

涵蓋應(yīng)用需要訪問其沙盒外部數(shù)據(jù)或資源,但對(duì)用戶隱私或其他應(yīng)用操作風(fēng)險(xiǎn)很小的區(qū)域。這些權(quán)限在應(yīng)用安裝時(shí)授予,運(yùn)行時(shí)不再詢問用戶。例如: 網(wǎng)絡(luò)訪問、WIFI狀態(tài)、音量設(shè)置等。完整的正常權(quán)限列表參考官網(wǎng)?正常權(quán)限。

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

涵蓋應(yīng)用需要涉及用戶隱私信息的數(shù)據(jù)或資源,或者可能對(duì)用戶存儲(chǔ)的數(shù)據(jù)或其他應(yīng)用的操作產(chǎn)生影響的區(qū)域。例如: 讀取通訊錄、讀寫存儲(chǔ)器數(shù)據(jù)、獲取用戶位置等。如果應(yīng)用聲明需要這些危險(xiǎn)權(quán)限,則必須在運(yùn)行時(shí)明確告訴用戶,讓用戶手動(dòng)授予。

3. 權(quán)限組

Android系統(tǒng)對(duì)所有的危險(xiǎn)權(quán)限進(jìn)行了分組,稱為?權(quán)限組?。屬于同一組的危險(xiǎn)權(quán)限將自動(dòng)合并授予,用戶授予應(yīng)用某個(gè)權(quán)限組的權(quán)限,則應(yīng)用將獲得該權(quán)限組下的所有權(quán)限(前提是相關(guān)權(quán)限在 AndroidManifest.xml 中有聲明)。

危險(xiǎn)權(quán)限?和?權(quán)限組?列表如下:

PS: 在 AndroidManifest.xml 聲明過的危險(xiǎn)權(quán)限對(duì)應(yīng)的權(quán)限組可以在系統(tǒng) “設(shè)置” -> “應(yīng)用” -> “應(yīng)用信息” -> “權(quán)限” 中查看,可以手動(dòng)授權(quán)和取消授權(quán)。

權(quán)限組和權(quán)限在Android代碼中以?字符串常量?來表示,分別定義在以下兩個(gè)?靜態(tài)內(nèi)部類?的字段中:

  • android.Manifest.permission_group(權(quán)限組):?
    • Manifest.permission_group.CALENDAR
    • Manifest.permission_group.STORAGE
    • ......
  • android.Manifest.permission(權(quán)限):?
    • Manifest.permission.READ_CALENDAR
    • Manifest.permission.READ_EXTERNAL_STORAGE
    • ......

4. 在運(yùn)行時(shí)請(qǐng)求權(quán)限

設(shè)備系統(tǒng)是 Android 6.0 (API 23) 或更高版本,并且應(yīng)用的 targetSdkVersion 是 23 或更高版本,則針對(duì)在 AndroidManifest.xml 中聲明的危險(xiǎn)權(quán)限,在運(yùn)行時(shí)還需要?jiǎng)討B(tài)請(qǐng)求用戶授權(quán)。

動(dòng)態(tài)權(quán)限請(qǐng)求相關(guān)操作的API封裝在在android.support.v4包中,發(fā)起請(qǐng)求權(quán)限的Activity需要直接或間接繼承android.support.v4.app.FragmentActivity。

PS: 也可以在直接或間接繼承?android.support.v4.app.Fragment?的?Fragment?中發(fā)起權(quán)限請(qǐng)求。

代碼步驟中主要包含以下幾個(gè)方法:

(1)檢查權(quán)限

// 檢查權(quán)限 ContextCompat.checkSelfPermission(Context context, String permission)

返回值(android.content.pm.PackageManager中的常量):

  • 有權(quán)限:?PackageManager.PERMISSION_GRANTED
  • 無權(quán)限:?PackageManager.PERMISSION_DENIED

當(dāng)應(yīng)用需要用到危險(xiǎn)權(quán)限時(shí),在執(zhí)行權(quán)限相關(guān)代碼前,使用該方法判斷是否擁有指定的權(quán)限。有權(quán)限,則繼續(xù)執(zhí)行設(shè)計(jì)需要權(quán)限的代碼;無權(quán)限,則向用戶請(qǐng)求授予權(quán)限。

(2)解釋權(quán)限

// 解釋權(quán)限 ActivityCompat.shouldShowRequestPermissionRationale(Activity activity, String permission)

判斷是否有必要向用戶解釋為什么要這項(xiàng)權(quán)限。如果應(yīng)用第一次請(qǐng)求過此權(quán)限,但是被用戶拒絕了,則之后調(diào)用該方法將返回 true,此時(shí)就有必要向用戶詳細(xì)說明需要此權(quán)限的原因(個(gè)人認(rèn)為此方法是可選的)。

PS: 如果應(yīng)用第一次請(qǐng)求此權(quán)限時(shí)被用戶拒絕,第二次再請(qǐng)求此權(quán)限時(shí),用戶勾選了權(quán)限請(qǐng)求對(duì)話框的“不再詢問”,則此方法返回 false。如果設(shè)備規(guī)范禁止應(yīng)用擁有該權(quán)限,此方法也返回 false。

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

// 請(qǐng)求權(quán)限 ActivityCompat.requestPermissions(Activity activity, String[] permissions, int requestCode)

PS:

  • 權(quán)限參數(shù)傳入的是數(shù)組,可以調(diào)用該方法一次請(qǐng)求多個(gè)權(quán)限;
  • 傳入的權(quán)限數(shù)組參數(shù)以單個(gè)具體權(quán)限為單位,但彈框詢問用戶授權(quán)時(shí),屬于同一權(quán)限組的權(quán)限將自動(dòng)合并詢問授權(quán)一次;
  • 請(qǐng)求的權(quán)限必須事先在 AndroidManifest.xml 中有聲明,否則調(diào)用此方法請(qǐng)求時(shí),將不彈框,而是直接返回“拒絕”的結(jié)果;
  • 第一次請(qǐng)求權(quán)限時(shí),用戶點(diǎn)擊了“拒絕”,第二次再請(qǐng)求該權(quán)限時(shí),對(duì)話框?qū)⒊霈F(xiàn)“不再詢問”復(fù)選框,如果用戶勾選了“不再詢問”并點(diǎn)擊了“拒絕”,則之后再請(qǐng)求此權(quán)限組時(shí)將不彈框,而是直接返回“拒絕”的結(jié)果。

(4)處理結(jié)果

請(qǐng)求權(quán)限的結(jié)果返回和接收一個(gè)Activity的返回類似,重寫?FragmentActivity?或?(v4) Fragment?中的?onRequestPermissionsResult(...)?方法。

/*** 處理權(quán)限請(qǐng)求結(jié)果** @param requestCode* 請(qǐng)求權(quán)限時(shí)傳入的請(qǐng)求碼,用于區(qū)別是哪一次請(qǐng)求的** @param permissions* 所請(qǐng)求的所有權(quán)限的數(shù)組** @param grantResults* 權(quán)限授予結(jié)果,和 permissions 數(shù)組參數(shù)中的權(quán)限一一對(duì)應(yīng),元素值為兩種情況,如下:* 授予: PackageManager.PERMISSION_GRANTED* 拒絕: PackageManager.PERMISSION_DENIED*/ @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {// ... }

5. 代碼演示

功能很簡(jiǎn)單,如下:

  • 點(diǎn)擊一個(gè)按鈕,如果有相應(yīng)權(quán)限就進(jìn)行備份通訊錄操作;
  • 如果沒有相應(yīng)的權(quán)限,則向用戶申請(qǐng)權(quán)限;
  • 如果用戶授權(quán)通過,則繼續(xù)進(jìn)行備份通訊錄操作;
  • 如果用戶拒絕授權(quán),則彈出對(duì)話框引導(dǎo)用戶跳轉(zhuǎn)到應(yīng)用權(quán)限管理界面手動(dòng)授權(quán)。
  • 效果大致如下:

    ?

    部分文件代碼:

    1、首先在 AndroidManifest.xml 中聲明權(quán)限

    <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.xiets.demoapp"><!-- 聲明所有需要的權(quán)限(包括普通權(quán)限和危險(xiǎn)權(quán)限) --><uses-permission android:name="android.permission.READ_CONTACTS"/><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><applicationandroid:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:theme="@style/AppTheme"><activity android:name=".MainActivity"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>

    2、布局文件 activity_main.xml

    <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:padding="10dp"><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="click"android:textSize="20sp"android:text="備份通訊錄" /></RelativeLayout>

    3、MainActivity

    package com.xiets.demoapp;import android.Manifest; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Bundle; import android.provider.Settings; import android.support.annotation.NonNull; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Toast;/*** 一鍵備份通訊錄** @author xietansheng*/ public class MainActivity extends AppCompatActivity {private static final int MY_PERMISSION_REQUEST_CODE = 10000;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}/*** 點(diǎn)擊按鈕,將通訊錄備份保存到外部存儲(chǔ)器備。** 需要3個(gè)權(quán)限(都是危險(xiǎn)權(quán)限):* 1. 讀取通訊錄權(quán)限;* 2. 讀取外部存儲(chǔ)器權(quán)限;* 3. 寫入外部存儲(chǔ)器權(quán)限.*/public void click(View view) {/*** 第 1 步: 檢查是否有相應(yīng)的權(quán)限*/boolean isAllGranted = checkPermissionAllGranted(new String[] {Manifest.permission.READ_CONTACTS,Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE});// 如果這3個(gè)權(quán)限全都擁有, 則直接執(zhí)行備份代碼if (isAllGranted) {doBackup();return;}/*** 第 2 步: 請(qǐng)求權(quán)限*/// 一次請(qǐng)求多個(gè)權(quán)限, 如果其他有權(quán)限是已經(jīng)授予的將會(huì)自動(dòng)忽略掉 ActivityCompat.requestPermissions(this,new String[] {Manifest.permission.READ_CONTACTS,Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE},MY_PERMISSION_REQUEST_CODE);}/*** 檢查是否擁有指定的所有權(quán)限*/private boolean checkPermissionAllGranted(String[] permissions) {for (String permission : permissions) {if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {// 只要有一個(gè)權(quán)限沒有被授予, 則直接返回 falsereturn false;}}return true;}/*** 第 3 步: 申請(qǐng)權(quán)限結(jié)果返回處理*/@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);if (requestCode == MY_PERMISSION_REQUEST_CODE) {boolean isAllGranted = true;// 判斷是否所有的權(quán)限都已經(jīng)授予了for (int grant : grantResults) {if (grant != PackageManager.PERMISSION_GRANTED) {isAllGranted = false;break;}}if (isAllGranted) {// 如果所有的權(quán)限都授予了, 則執(zhí)行備份代碼 doBackup();} else {// 彈出對(duì)話框告訴用戶需要權(quán)限的原因, 并引導(dǎo)用戶去應(yīng)用權(quán)限管理中手動(dòng)打開權(quán)限按鈕 openAppDetails();}}}/*** 第 4 步: 備份通訊錄操作*/private void doBackup() {// 本文主旨是講解如果動(dòng)態(tài)申請(qǐng)權(quán)限, 具體備份代碼不再展示, 就假裝備份一下Toast.makeText(this, "正在備份通訊錄...", Toast.LENGTH_SHORT).show();}/*** 打開 APP 的詳情設(shè)置*/private void openAppDetails() {AlertDialog.Builder builder = new AlertDialog.Builder(this);builder.setMessage("備份通訊錄需要訪問 “通訊錄” 和 “外部存儲(chǔ)器”,請(qǐng)到 “應(yīng)用信息 -> 權(quán)限” 中授予!");builder.setPositiveButton("去手動(dòng)授權(quán)", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {Intent intent = new Intent();intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);intent.addCategory(Intent.CATEGORY_DEFAULT);intent.setData(Uri.parse("package:" + getPackageName()));intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);startActivity(intent);}});builder.setNegativeButton("取消", null);builder.show();}}

    ?

    轉(zhuǎn)載于:https://www.cnblogs.com/zhujiabin/p/9305521.html

    總結(jié)

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

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