Android基础面试--如何在Android中申请权限?

1 阅读6分钟

一、如何在Android中申请权限?

回答要点
在Android中申请权限主要分成两部分:声明权限和实际申请权限。声明权限需要在AndroidManifest.xml文件中进行,而实际请求权限则在代码中进行。
  1. 在AndroidManifest.xml文件中声明权限。例如,如果你要使用相机,你需要添加以下代码:
<uses-permission android:name="android.permission.CAMERA"/>
  1. 在代码中请求权限。以Android 6.0(APILevel 23)为分界线,高于这个版本的Android系统需要在运行时请求权限。以下是具体步骤:
  • 检查当前是否已经拥有权限:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
                != PackageManager.PERMISSION_GRANTED) {
    // 权限未被授予,执行请求权限操作
}
  • 请求权限:
ActivityCompat.requestPermissions(this,
        new String[]{Manifest.permission.CAMERA},
        MY_PERMISSIONS_REQUEST_CAMERA);
  • 处理权限请求结果。重写方法:onRequestPermissionsResult:
@Override
public void onRequestPermissionsResult(int requestCode,
                                       String[] permissions,
                                       int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_CAMERA:
            if (grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // 权限请求被同意,可以执行操作
            } else {
                // 权限请求被拒绝,给用户一个提示
            }
            return;
    }
}
  • 多权限申请:有时候你会需要一次性申请多个权限,这可以通过将多个权限放到一个数组中,并一次性请求来完成。例如:
ActivityCompat.requestPermissions(this,
        new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE},
        MY_PERMISSIONS_REQUEST_MULTI);
  • 权限解释:根据用户体验设计的最佳实践,如果用户拒绝了某个权眼请求,下次请求之前最好进行一个解释,告诉用户为何需要这个权眼。使用shouldshowRequestPermissionRationale 方法可以判断是否应该给出该解释:
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
        Manifest.permission.CAMERA)) {
    // 向用户展示为什么需要这个权限
}
  • 敏感权限:一些权限被认为是“危险”的,例如访问联系人、相机、位置等,需要在运行时请求。而其他非危险权限,如INTERNET权限,只需要在AndrodManifest.xml中声明即可。
  • 权限组:从 Android 8.0开始,如果应用已经授予某个权限组中的一个权眼,为该组请求任何其他权限时,系统会自动授予这些权限而不再提示用户。例如,如果应用已经授予了READ_CONTACTS权限,再次请求WRITE_CONTACTS权限时,系统会自动授予。
  • 最佳实践:逐步请求权限而不是一次性请求所有可能需要的权限。这样可以避免用户被大量权限请求吓到,且可以更好地解释和展示权限的必要性。

二、注意事项

  1. 权限分类
  • 普通权限(Normal):自动授予(如网络权限),仅需声明。
  • 危险权限(Dangerous):需运行时申请(如相机、定位)。
  • 特殊权限:需跳转系统设置(如WRITE_SETTINGS)。
  1. 权限组
  • 同一组的权限只需申请一次(如STORAGE组包含读/写外部存储权限)。
  • 不要依赖分组逻辑:不同Android版本可能调整分组,应显式请求每个权限。
  1. 用户体验优化 Rationale 解释:在用户拒绝后再次请求前,通过 shouldShowRequestPermissionRationale()判断是否需要解释权限必要性。 永久拒绝处理:若用户勾选“不再询问”,需引导至系统设置页。
  2. 兼容性
  • API级别适配:低于API23的设备安装时自动授予所有声明的权限。
  • 分区存储(Scoped Storage):针对Android10+的文件访问权限需特别处理。
  1. 敏感权限限制
  • 后台定位:需单独申请ACCESS BACKGROUNDLOCATION(Android 10+)。
  • 摄像头/麦克风:Android13+需分别申请READ_MEDIA_IMAGES 和RECORD_AUDIO。

三、请开始你的表演

在Android中如何声明和申请权限?

在Android 中申请权限分为两个步骤:首先在 AndroidManifest.xml文件中使用:<uses-permisson> 标签声明所需权限,例如相机权限 <uses-permission android:name = "android pemisionCAMERA"/>;然后在代码中针对 Android 60 (APl 23) 及以上版本进行运行时权申请,通过 ContextCompat.checkSelfPermisson 检查权限状态,若未授予则调用ActivityCompat.requestPermissions 发起请求,并在 onRequestPermissionsResult中处理用户授权结果。

Android 中危险权限和普通权限的区别是什么?

危险权限(如相机、联系人、位置等)涉及用户隐私数据,需要在运行时动态申请并由用户明确授权;而普通权限(如INTERNET)只涉及应用基本功能,只需在AndroidManifest.xml中声明即可,系统会自动授予,无需运行时请求。

如何处理多个权限的申请?

可以将多个权限放入字符串数组中,使用 ActivityCompatRequestPermissions一次性请求。例如同时请求相机和存储权限:new Sting[]{Manifest.permision.CAMERA,Manifest.permision.READ.EXTERNAL.STORAGE}。需要注意的是,即使其中部分权限已被授予,系统仍会对未授权的权限发起请求,结果需在回调中逐一判断每个权限的授予状态。

什么是shouldShowRequestPermissionRationale,它的作用是什么?

shouldShowRequestPermissonRationale 用于判断是否应向用户显示权限请求的解释说明。当用户之前拒绝过该权限且勾选了不再提示时,此方法返回false;如果只是简单拒绝,返回tue。开发者可据此决定是否弹出对话框告知用户为何需要该权限,从而提高用户理解和接受度。

Android 权限组的作用是什么?

从Android 8.0开始,权限被划分为权限组。如果应用已获得同一权限组中的某个权限,再次请求该组内的其他权限时,系统将自动授予而不再提示用户。例如已授予READ_CONTACTS后,请求WRITE_CONTACTS将被静默通过,提升用户体验并减少重复请求。

申请权限时有哪些最佳实践?

推荐逐步申请权限,即在用户实际需要某项功能时再请求对应权限,而非启动应用时一次性请求所有权限。这样能结合具体场景向用户解释权限用途,提升接受率。同时应配合shouldShowRequestPermissionRationale 提供合理说明,并妥善处理权限被拒绝的情况,避免功能异常或崩溃。

如何检查和请求单个权限?

使用 ContextCompat.checkSelfPermissionContext, ManifestPermission.XXX)检查是否已有权限,若返回 PERMISSiON.DENIED,则通过ActivityCompat.requestPermissions(activity, new String[](Manifest. permission.XXX), REQUEST CODE) 发起请求, 最终在onRequestPermissionsResult 回调中根据grantResults判断结果并执行相应逻辑。

权限请求结果如何处理?

重写onRequestPermisionsResult 方法,在其中根据传入的 requestCode区分不同的权限请求,检查 gantResult数组内容:若长度大于0且值为 PackageManag.PERMSSION.GRANTED,表示用户同意;否则视为拒绝,需给出提示或引导用户手动开启权限。

为什么有些权限不需要运行时申请?

因为Android将权限分为普通权限和危险权限。普通权限不涉及敏感信息(如访问网络)仅需在清单文件中声明中可由系统自动授子;而危险权限涉及用户隐私,必须在运行时动态申请并获得用户确认,以增强安全性和透明度。

目标 SDK 版本对权限申请有何影响?

当应用的目标SDK版本(targetSdkVersion)大于等于23时,必须在运行时请求危险权限,即使已在清单中声明;若低于23,则系统会在安装时授予所有权限,无需运行时请求。因此建议适配新版本权限模型以符合Google Play 的审核要求和现代 Android安全规范。