UniApp获取安卓系统权限教程

本教程将详细介绍在UniApp中开发安卓APP时,如何正确配置和动态申请系统权限,涵盖权限声明、运行时申请、状态处理等完整流程。

一、权限配置基础

1.1 在manifest.json中声明权限

在项目根目录的manifest.json文件中配置所需权限。有两种配置方式:

​方式一:可视化配置(推荐)​

打开HBuilderX,在manifest.json编辑界面切换到"App权限配置" -> "Android权限配置",勾选需要的权限项。

​方式二:代码视图配置​

在manifest.json的代码视图中添加:

复制代码
{
  "app-plus": {
    "distribute": {
      "android": {
        "permissions": [
          "android.permission.CAMERA",
          "android.permission.ACCESS_FINE_LOCATION",
          "android.permission.WRITE_EXTERNAL_STORAGE"
        ]
      }
    }
  }
}

1.2 常用安卓权限列表

权限名称 说明 权限常量
相机权限 访问摄像头拍照 android.permission.CAMERA
存储权限 读写外部存储 android.permission.WRITE_EXTERNAL_STORAGE
定位权限 获取精确位置 android.permission.ACCESS_FINE_LOCATION
麦克风权限 录音 android.permission.RECORD_AUDIO
电话权限 拨打电话 android.permission.CALL_PHONE
联系人权限 读取联系人 android.permission.READ_CONTACTS

二、动态权限申请

Android 6.0+系统要求运行时动态申请敏感权限。UniApp通过plus.android.requestPermissionsAPI实现。

2.1 基本申请方法

复制代码
// 单个权限申请示例
plus.android.requestPermissions(
  ['android.permission.CAMERA'],
  function(resultObj) {
    // 权限申请结果回调
    console.log('权限申请结果:', resultObj);
    
    if (resultObj.granted.length > 0) {
      // 权限已授予
      console.log('相机权限已获取');
    } else if (resultObj.deniedPresent.length > 0) {
      // 本次拒绝
      console.log('用户本次拒绝授权');
    } else if (resultObj.deniedAlways.length > 0) {
      // 永久拒绝
      console.log('用户永久拒绝授权');
    }
  },
  function(error) {
    // 申请出错
    console.error('权限申请出错:', error);
  }
);

2.2 多个权限同时申请

复制代码
// 同时申请多个权限
const permissions = [
  'android.permission.CAMERA',
  'android.permission.WRITE_EXTERNAL_STORAGE'
];

plus.android.requestPermissions(
  permissions,
  function(resultObj) {
    // 处理多个权限结果
    console.log('已授权:', resultObj.granted);
    console.log('本次拒绝:', resultObj.deniedPresent);
    console.log('永久拒绝:', resultObj.deniedAlways);
  }
);

三、权限状态处理

3.1 检查权限状态

在申请权限前,可以先检查当前权限状态:

复制代码
// 检查权限是否已授予(仅适用于部分权限)
uni.getSetting({
  success(res) {
    if (res.authSetting['scope.camera']) {
      console.log('相机权限已开启');
    } else {
      // 需要申请权限
      requestCameraPermission();
    }
  }
});

3.2 处理用户拒绝场景

当用户拒绝权限时,需要提供友好的引导:

复制代码
function handlePermissionResult(resultObj) {
  if (resultObj.deniedAlways.length > 0) {
    // 用户勾选了"不再询问",需要引导到设置页
    uni.showModal({
      title: '权限提示',
      content: '您已永久拒绝该权限,请前往设置手动开启',
      success(res) {
        if (res.confirm) {
          // 跳转到应用设置页
          openAppSettings();
        }
      }
    });
  } else if (resultObj.deniedPresent.length > 0) {
    // 本次拒绝,可以稍后再次尝试
    uni.showToast({
      title: '权限未获取,部分功能无法使用',
      icon: 'none'
    });
  }
}

四、跳转到系统设置页

当用户永久拒绝权限时,需要引导用户到系统设置页手动开启:

复制代码
// 跳转到应用权限设置页
function openAppSettings() {
  if (plus.os.name === 'Android') {
    const Intent = plus.android.importClass('android.content.Intent');
    const Settings = plus.android.importClass('android.provider.Settings');
    const Uri = plus.android.importClass('android.net.Uri');
    
    const mainActivity = plus.android.runtimeMainActivity();
    const intent = new Intent();
    intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
    const uri = Uri.fromParts('package', mainActivity.getPackageName(), null);
    intent.setData(uri);
    mainActivity.startActivity(intent);
  }
}

五、完整示例代码

5.1 相机权限申请完整示例

复制代码
// 封装相机权限申请函数
export function requestCameraPermission() {
  return new Promise((resolve, reject) => {
    // 先检查是否已授权
    uni.getSetting({
      success(res) {
        if (res.authSetting['scope.camera']) {
          resolve(true);
          return;
        }
        
        // 向用户解释权限用途
        uni.showModal({
          title: '权限申请',
          content: '我们需要访问您的相机以使用拍照功能',
          success(modalRes) {
            if (modalRes.confirm) {
              // 发起权限申请
              plus.android.requestPermissions(
                ['android.permission.CAMERA'],
                function(resultObj) {
                  if (resultObj.granted.length > 0) {
                    resolve(true);
                  } else if (resultObj.deniedAlways.length > 0) {
                    // 永久拒绝,引导到设置页
                    uni.showModal({
                      title: '提示',
                      content: '请前往设置开启相机权限',
                      success(settingRes) {
                        if (settingRes.confirm) {
                          openAppSettings();
                        }
                        resolve(false);
                      }
                    });
                  } else {
                    resolve(false);
                  }
                },
                function(error) {
                  console.error('权限申请错误:', error);
                  reject(error);
                }
              );
            } else {
              resolve(false);
            }
          }
        });
      }
    });
  });
}

// 使用示例
async function takePhoto() {
  const hasPermission = await requestCameraPermission();
  if (hasPermission) {
    // 执行拍照操作
    uni.chooseImage({
      count: 1,
      success(res) {
        console.log('拍照成功:', res.tempFilePaths[0]);
      }
    });
  }
}

5.2 定位权限申请示例

复制代码
// 定位权限申请
function requestLocationPermission() {
  const permissions = [
    'android.permission.ACCESS_FINE_LOCATION',
    'android.permission.ACCESS_COARSE_LOCATION'
  ];
  
  plus.android.requestPermissions(
    permissions,
    function(resultObj) {
      if (resultObj.granted.length > 0) {
        // 获取定位
        uni.getLocation({
          type: 'wgs84',
          success(res) {
            console.log('定位成功:', res);
          }
        });
      } else {
        uni.showToast({
          title: '定位权限未获取',
          icon: 'none'
        });
      }
    }
  );
}

六、常见问题与解决方案

6.1 权限弹窗不显示

  • ​原因1​​:manifest.json中未正确配置权限

  • ​解决​​:检查manifest.json权限配置,确保权限名称正确

  • ​原因2​​:在非主线程调用权限申请

  • ​解决​​:确保在页面生命周期(如onLoad、onShow)或用户交互事件中调用

6.2 权限申请回调不执行

  • ​原因​:Android系统限制,用户点击"拒绝"后短时间内不会再次弹窗
  • ​解决​:添加合理的重试机制,或引导用户到设置页

6.3 应用市场审核被拒

  • ​原因​:权限使用说明不充分
  • ​解决​:在权限申请前向用户清晰说明权限用途,并在隐私政策中说明数据使用方式

七、最佳实践建议

  1. ​按需申请​:在真正需要使用功能时才申请权限,不要一次性申请所有权限
  2. ​用户引导​:申请权限前向用户解释为什么需要该权限,提升用户体验
  3. ​错误处理​:对权限拒绝、永久拒绝等不同状态做差异化处理
  4. ​测试覆盖​:在不同Android版本、不同厂商ROM上测试权限申请流程
  5. ​隐私合规​:确保符合应用市场审核要求,在隐私政策中说明权限使用目的

八、总结

UniApp开发安卓APP的权限管理涉及manifest配置、运行时申请、状态处理等多个环节。通过plus.android.requestPermissionsAPI可以方便地实现动态权限申请,但需要注意不同Android版本的兼容性、用户引导、错误处理等细节。建议将权限申请逻辑封装成工具函数,提高代码复用性和可维护性。

在实际开发中,建议参考官方文档和最新API,因为不同HBuilderX版本可能会有细微差异。同时,关注各大应用市场的审核要求,确保权限使用符合规范。


​注意​​:本教程基于UniApp官方文档和常见开发实践编写,具体实现时请根据实际项目需求和HBuilderX版本进行调整。建议在真机上进行充分测试,确保权限申请流程正常工作。

相关推荐
毕设源码-朱学姐3 小时前
【开题答辩全过程】以 基于安卓的教师上课辅助系统为例,包含答辩的问题和答案
android
诸神黄昏EX4 小时前
Android Safety 系列专题【篇二:AVB签名】
android
2601_949543014 小时前
Flutter for OpenHarmony垃圾分类指南App实战:意见反馈实现
android·flutter
urkay-5 小时前
Android 中实现 HMAC-SHA256
android·开发语言·python
YIN_尹5 小时前
【MySQL】增删查改的艺术——数据库CRUD完全指南(下)
android·数据库·mysql
m0_748233175 小时前
PHP8.0新特性全解析
android
一起养小猫5 小时前
Flutter for OpenHarmony 实战:从零开发一款五子棋游戏
android·前端·javascript·flutter·游戏·harmonyos
●VON6 小时前
从像素到语义:React Native Text 组件在 OpenHarmony 上的渲染哲学与工程实现
android·react native·react.js
henysugar6 小时前
Android studio编译aidl若干问题记录
android·ide·android studio·aidl