uniapp Android&iOS 定位权限检查

定位权限检查

javascript 复制代码
// 检查定位权限状态
export const checkPermission = () => {
	const platform = uni.getSystemInfoSync().platform;
	console.log('platform', platform)
	// #ifdef APP-PLUS
	if (platform === 'android') {
		// Android
		return checkAndroidPermission();
	} else if (platform === 'ios') {
		// iOS
		return checkIOSPermission();
	}
	// #endif
};

/**
 * 获取Android定位权限状态
 * @returns {Promise<string>} 返回权限状态:
 *   'granted_always' - 始终允许
 *   'granted_when_in_use' - 仅在使用时允许 (Android 10+)
 *   'denied' - 已拒绝
 *   'denied_forever' - 拒绝且不再询问
 */
// Android 检测权限
export const checkAndroidPermission = () => {
	return new Promise((resolve) => {
	// #ifdef APP-PLUS
		// 0-引导 1-允许 2-设置
		const main = plus.android.runtimeMainActivity();
		const ActivityCompat = plus.android.importClass('androidx.core.app.ActivityCompat');
		const PackageManager = plus.android.importClass('android.content.pm.PackageManager');
		const Manifest = plus.android.importClass('android.Manifest');
		const ContextCompat = plus.android.importClass('androidx.core.content.ContextCompat');

		// 检查是否已授权
		const hasFineLocation = ContextCompat.checkSelfPermission(
			main,
			Manifest.permission.ACCESS_FINE_LOCATION
		) === PackageManager.PERMISSION_GRANTED;

		const hasCoarseLocation = ContextCompat.checkSelfPermission(
			main,
			Manifest.permission.ACCESS_COARSE_LOCATION
		) === PackageManager.PERMISSION_GRANTED;

		if (!hasFineLocation && !hasCoarseLocation) {
			// 如果完全没有权限,检查是否被永久拒绝
			console.log("Android 权限被拒绝")
			resolve(2);
			return;
		}

		// 如果有权限,检查是否是"始终允许" (Android 10+)
		if (plus.os.version >= 10) {
			const AppOpsManager = plus.android.importClass('android.app.AppOpsManager');
			const appOps = main.getSystemService('appops');
			const mode = plus.android.invoke(
				appOps,
				'checkOpNoThrow',
				AppOpsManager.OPSTR_FINE_LOCATION,
				main.getApplicationInfo().uid,
				main.getPackageName()
			);
			// 处理可能的null返回值
			if (mode === null) {
				console.warn('checkOpNoThrow返回null,降级检查运行时权限');
				const hasPermission = ContextCompat.checkSelfPermission(
					main,
					Manifest.permission.ACCESS_FINE_LOCATION
				) === PackageManager.PERMISSION_GRANTED;

				console.log("降级检查运行hasPermission", hasPermission)
				resolve(hasPermission ? 1 : 2);
				return;
			}
			console.log("Android===mode", mode)
			switch (mode) {
				case 0: // MODE_ALLOWED
					console.log('始终允许定位');
					resolve(1);
					break;
				case 4: // MODE_FOREGROUND
					console.log('仅允许前台定位');
					resolve(1);
					break;
				case 1: // MODE_IGNORED
					console.log('已拒绝但可再次请求');
					resolve(1);
					break;
				case 2: // MODE_ERRORED
					console.log('已永久拒绝需手动设置');
					resolve(2);
					break;
				default:
					console.log('其他状态', mode);
			}
		} else {
			// Android 9及以下无法区分"始终允许"和"仅在使用时允许"
			console.log("Android 权限始终允许")
			resolve(1);
		}
	});
	// #endif
}

// iOS 检测权限
export const checkIOSPermission = () => {
	console.log('iOS 检测权限');
	return new Promise((resolve, reject) => {
		// #ifdef APP-PLUS
		const cllocationManger = plus.ios.import('CLLocationManager');
		const status = cllocationManger.authorizationStatus();
		const enable = cllocationManger.locationServicesEnabled();
		// 0-引导 1-允许 2-设置
		// status 含义:
		// 0: 未决定(kCLAuthorizationStatusNotDetermined)
		// 2: 已拒绝(kCLAuthorizationStatusDenied)
		// 3: 始终允许(kCLAuthorizationStatusAuthorizedAlways)
		// 4: 仅使用时允许(kCLAuthorizationStatusAuthorizedWhenInUse)
		console.log('status', status);
		if (!enable) {
			resolve(2);
		} else if (status === 2) {
			// 拒绝
			resolve(2);
		} else if (status === 4) {
			// 仅使用时允许
			resolve(0);
		} else if (status === 3) {
			// 未决定
			resolve(1);
		} else {
			resolve(0);
		}
		plus.ios.deleteObject(cllocationManger);
		// #endif
	});
};

// 权限请求
export const getAndroidLocation = () => {
	return new Promise((resolve, reject) => {
		plus.android.requestPermissions(
			['android.permission.ACCESS_FINE_LOCATION'],
			(result) => {
				console.log('android,', result);
				// 0-引导 1-允许 2-设置
				if (result.granted.length) {
					console.log('Android 已授予定位权限');
					resolve(1);
				} else if (result.deniedAlways.length) {
					// 拒绝,跳转系统设置
					console.log('Android 已拒绝定位权限');
					resolve(2);
				} else {
					resolve(0);
				}
			},
			(error) => {
				console.log("Android 检测权限---err", error)
				reject(error);
			}
		);
	})
}

使用

javascript 复制代码
		if (check) {
			// #ifdef APP-PLUS
			checkPermission().then(async code => {
				uni.setStorageSync("locationPermissions", true);
				console.log("code", code)
				// 0-引导 1-允许 2-设置
				if (code === 0) {
					console.log("权限引导")
					
				} else if (code === 1) {
					console.log("允许");
					
				} else if (code === 2) {
					console.log("跳转权限设置")
				}
			}).catch((err) => {
				console.log("报错", err)
				uni.showModal({
					content: '检测权限失败,请确认是否打开GPS,再重启APP',
					showCancel: false,
					confirmText: "去开启",
					success(res) {
						uni.openAppAuthorizeSetting()
					}
				})
			})
		}
相关推荐
ningmengjing_13 分钟前
在 PyCharm 中安装并配置 Node.js 的指南
开发语言·javascript·ecmascript
晓131328 分钟前
JavaScript基础篇——第五章 对象(最终篇)
开发语言·前端·javascript
wzj_what_why_how37 分钟前
Android网络层架构:统一错误处理的问题分析到解决方案与设计实现
android·架构
千里马学框架1 小时前
User手机上如何抓取界面的布局uiautomatorviewer
android·智能手机·aosp·uiautomator·布局抓取·user版本
灋✘逞_兇1 小时前
Node.Js是什么?
服务器·javascript·node.js
当牛作馬1 小时前
React——ant-design组件库使用问题记录
前端·react.js·前端框架
阿巴~阿巴~1 小时前
操作系统核心技术剖析:从Android驱动模型到鸿蒙微内核的国产化实践
android·华为·harmonyos
雪碧聊技术2 小时前
uniapp简介
uni-app·hbuilder
一只一只妖2 小时前
uniapp小程序无感刷新token
前端·小程序·uni-app
小飞悟2 小时前
那些年我们忽略的高频事件,正在拖垮你的页面
javascript·设计模式·面试