|
@@ -0,0 +1,188 @@
|
|
|
|
+// permissionHelper.js
|
|
|
|
+
|
|
|
|
+// 权限说明配置(可以根据需要扩展)
|
|
|
|
+const permissionList = [
|
|
|
|
+ {
|
|
|
|
+ name: 'android.permission.CAMERA',
|
|
|
|
+ title: '使用摄像头权限',
|
|
|
|
+ content: '用于更换、上传您的头像、图片功能,不授权该权限会影响app的正常使用'
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ name: 'android.permission.READ_EXTERNAL_STORAGE',
|
|
|
|
+ title: '读照片及文件权限',
|
|
|
|
+ content: '用于更换、上传您的头像、图片功能,不授权该权限会影响app的正常使用'
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ name: 'android.permission.ACCESS_FINE_LOCATION',
|
|
|
|
+ title: '访问精确位置权限',
|
|
|
|
+ content: '用于获取用户位置,以便为用户提供有地域特点的服务'
|
|
|
|
+ }
|
|
|
|
+ // ... 可以在此添加其他权限
|
|
|
|
+];
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * 检查特定权限状态
|
|
|
|
+ * @param {string} permission - 要检查的权限名称
|
|
|
|
+ * @returns {Promise<boolean>} - 返回权限是否已授予
|
|
|
|
+ */
|
|
|
|
+export function checkPermission(permission) {
|
|
|
|
+ return new Promise((resolve) => {
|
|
|
|
+ // iOS 处理
|
|
|
|
+ if (plus.os.name === 'iOS') {
|
|
|
|
+ // iOS 权限检查方式与 Android 不同,通常需要调用特定API或尝试使用功能
|
|
|
|
+ resolve(true); // 简化处理,实际项目需完善
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Android 处理
|
|
|
|
+ const main = plus.android.runtimeMainActivity();
|
|
|
|
+ const result = main.checkSelfPermission(permission);
|
|
|
|
+ resolve(result === 0); // 0 表示已授权
|
|
|
|
+ });
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * 申请单个权限
|
|
|
|
+ * @param {string} permission - 要申请的权限名称
|
|
|
|
+ * @returns {Promise<Object>} - 返回授权结果对象
|
|
|
|
+ */
|
|
|
|
+export function requestSinglePermission(permission) {
|
|
|
|
+ return new Promise((resolve) => {
|
|
|
|
+ plus.android.requestPermissions([permission], (e) => {
|
|
|
|
+ resolve(e);
|
|
|
|
+ });
|
|
|
|
+ });
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * 显示权限说明弹窗
|
|
|
|
+ * @param {Object} permissionInfo - 权限信息对象
|
|
|
|
+ * @returns {Promise<boolean>} - 用户是否同意申请
|
|
|
|
+ */
|
|
|
|
+export function showPermissionExplanation(permissionInfo) {
|
|
|
|
+ return new Promise((resolve) => {
|
|
|
|
+ uni.showModal({
|
|
|
|
+ title: permissionInfo.title,
|
|
|
|
+ content: permissionInfo.content,
|
|
|
|
+ confirmText: '去开启',
|
|
|
|
+ cancelText: '暂不',
|
|
|
|
+ success: (res) => {
|
|
|
|
+ resolve(res.confirm);
|
|
|
|
+ },
|
|
|
|
+ fail: (err) => {
|
|
|
|
+ console.error('显示权限说明弹窗失败:', err);
|
|
|
|
+ resolve(false);
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ });
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * 引导用户前往应用系统设置页面
|
|
|
|
+ */
|
|
|
|
+export function openAppSystemSettings() {
|
|
|
|
+ // iOS 处理
|
|
|
|
+ if (plus.os.name === 'iOS') {
|
|
|
|
+ const UIApplication = plus.ios.importClass('UIApplication');
|
|
|
|
+ const NSURL = plus.ios.importClass('NSURL');
|
|
|
|
+ const app = UIApplication.sharedApplication();
|
|
|
|
+ const settingUrl = NSURL.URLWithString('app-settings:');
|
|
|
|
+ plus.ios.invoke(app, 'openURL:', settingUrl);
|
|
|
|
+ plus.ios.deleteObject(settingUrl);
|
|
|
|
+ plus.ios.deleteObject(NSURL);
|
|
|
|
+ plus.ios.deleteObject(app);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Android 处理
|
|
|
|
+ const mainActivity = plus.android.runtimeMainActivity();
|
|
|
|
+ const Intent = plus.android.importClass('android.content.Intent');
|
|
|
|
+ const Settings = plus.android.importClass('android.provider.Settings');
|
|
|
|
+ const Uri = plus.android.importClass('android.net.Uri');
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ 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);
|
|
|
|
+ } catch (error) {
|
|
|
|
+ uni.showToast({
|
|
|
|
+ title: '无法打开设置页面',
|
|
|
|
+ icon: 'none'
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * 处理权限申请结果
|
|
|
|
+ * @param {string} permission - 权限名称
|
|
|
|
+ * @param {Object} result - 授权结果对象
|
|
|
|
+ * @param {Object} permissionInfo - 权限信息对象(用于提示)
|
|
|
|
+ */
|
|
|
|
+export async function handlePermissionResult(permission, result, permissionInfo) {
|
|
|
|
+ // 权限被永久拒绝(用户选择了"不再询问")
|
|
|
|
+ if (result.deniedAlways && result.deniedAlways.length > 0) {
|
|
|
|
+ uni.showModal({
|
|
|
|
+ title: '权限未开启',
|
|
|
|
+ content: `您已拒绝${permissionInfo.title},请到系统设置中手动开启`,
|
|
|
|
+ confirmText: '前往设置',
|
|
|
|
+ success: (res) => {
|
|
|
|
+ if (res.confirm) {
|
|
|
|
+ openAppSystemSettings();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ // 权限被临时拒绝(用户只是点了"拒绝")
|
|
|
|
+ else if (result.deniedPresent && result.deniedPresent.length > 0) {
|
|
|
|
+ uni.showToast({
|
|
|
|
+ title: `${permissionInfo.title}未被授权,部分功能可能无法使用`,
|
|
|
|
+ icon: 'none',
|
|
|
|
+ duration: 3000
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ // 如果 granted 长度 > 0,表示权限已获取
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * 主权限申请流程
|
|
|
|
+ * @param {string} permission - 需要申请的权限名称
|
|
|
|
+ * @returns {Promise<boolean>} - 最终是否获取了权限
|
|
|
|
+ */
|
|
|
|
+export async function requestEssentialPermission(permission) {
|
|
|
|
+ const permissionInfo = permissionList.find(item => item.name === permission);
|
|
|
|
+ if (!permissionInfo) {
|
|
|
|
+ console.error('未找到该权限的配置信息');
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ // 1. 首先检查是否已有权限
|
|
|
|
+ const hasPermission = await checkPermission(permission);
|
|
|
|
+ if (hasPermission) {
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 2. 没有权限,展示说明弹窗
|
|
|
|
+ const userAgreed = await showPermissionExplanation(permissionInfo);
|
|
|
|
+ if (!userAgreed) {
|
|
|
|
+ // 用户不同意申请,记录或处理
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 3. 用户同意,申请系统权限
|
|
|
|
+ const result = await requestSinglePermission(permission);
|
|
|
|
+
|
|
|
|
+ // 4. 处理申请结果
|
|
|
|
+ await handlePermissionResult(permission, result, permissionInfo);
|
|
|
|
+
|
|
|
|
+ // 5. 最终检查权限状态
|
|
|
|
+ const finalStatus = await checkPermission(permission);
|
|
|
|
+ return finalStatus;
|
|
|
|
+
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error('权限申请流程出错:', error);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+}
|