| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- /**
- * Android / iOS 权限与能力检测
- * Android 6+ 扫描 BLE 需要位置权限 + 位置服务开启
- * Android 12+ 需要 BLUETOOTH_SCAN / BLUETOOTH_CONNECT
- * iOS 需要 NSBluetoothAlwaysUsageDescription (在 manifest.json 中配置)
- *
- * 仅在 APP-PLUS 环境下调用 plus API, H5 / 小程序环境跳过
- */
- export function getPlatform() {
- try { return uni.getSystemInfoSync().platform } catch (_) { return '' }
- }
- /** 是否 App 环境 (plus 存在) */
- export function isAppPlus() {
- // #ifdef APP-PLUS
- return typeof plus !== 'undefined'
- // #endif
- // #ifndef APP-PLUS
- return false
- // #endif
- }
- /** 检查位置服务是否已开启 (Android) */
- export function isLocationEnabled() {
- return new Promise(resolve => {
- if (!isAppPlus() || getPlatform() !== 'android') return resolve(true)
- // #ifdef APP-PLUS
- try {
- const main = plus.android.runtimeMainActivity()
- const LocationManager = plus.android.importClass('android.location.LocationManager')
- const context = plus.android.importClass('android.content.Context')
- const lm = main.getSystemService(context.LOCATION_SERVICE)
- const gps = lm.isProviderEnabled(LocationManager.GPS_PROVIDER)
- const net = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
- resolve(gps || net)
- } catch (e) { resolve(true) }
- // #endif
- })
- }
- /** 跳转到系统位置服务设置 */
- export function openLocationSettings() {
- // #ifdef APP-PLUS
- if (!isAppPlus() || getPlatform() !== 'android') return
- try {
- const main = plus.android.runtimeMainActivity()
- const Intent = plus.android.importClass('android.content.Intent')
- const Settings = plus.android.importClass('android.provider.Settings')
- const intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
- main.startActivity(intent)
- } catch (e) { console.error(e) }
- // #endif
- }
- /** 请求 Android 运行时权限(定位/蓝牙扫描/连接). 返回 true/false */
- export function requestAndroidPermissions() {
- return new Promise(resolve => {
- if (!isAppPlus() || getPlatform() !== 'android') return resolve(true)
- // #ifdef APP-PLUS
- try {
- const main = plus.android.runtimeMainActivity()
- const Build = plus.android.importClass('android.os.Build')
- const sdkInt = Build.VERSION.SDK_INT
- const perms = ['android.permission.ACCESS_FINE_LOCATION']
- if (sdkInt >= 31) {
- perms.push('android.permission.BLUETOOTH_SCAN')
- perms.push('android.permission.BLUETOOTH_CONNECT')
- }
- const PackageManager = plus.android.importClass('android.content.pm.PackageManager')
- const need = perms.filter(p => main.checkSelfPermission(p) !== PackageManager.PERMISSION_GRANTED)
- if (!need.length) return resolve(true)
- const ActivityCompat = plus.android.importClass('androidx.core.app.ActivityCompat')
- // 注册结果回调
- const onReq = (activity, requestCode, permsArr, grantResults) => {
- plus.android.clearRequestPermissions && plus.android.clearRequestPermissions()
- const granted = grantResults && Array.from(grantResults).every(r => r === 0)
- resolve(!!granted)
- }
- if (plus.android.requestPermissions) {
- plus.android.requestPermissions(need, res => {
- resolve(res && res.granted && res.granted.length === need.length)
- }, () => resolve(false))
- } else {
- ActivityCompat.requestPermissions(main, need, 1001)
- // 无结果回调能力时, 乐观等待 2s 后查询
- setTimeout(() => {
- const still = need.filter(p => main.checkSelfPermission(p) !== PackageManager.PERMISSION_GRANTED)
- resolve(!still.length)
- }, 2000)
- }
- } catch (e) {
- console.error(e); resolve(false)
- }
- // #endif
- })
- }
- /** 检查系统蓝牙是否已开启 (Android 使用原生 API,iOS 依赖 uni API) */
- export function isBluetoothEnabled() {
- return new Promise(resolve => {
- const platform = getPlatform()
- if (!isAppPlus()) return resolve(true)
- // #ifdef APP-PLUS
- if (platform === 'android') {
- try {
- const BluetoothAdapter = plus.android.importClass('android.bluetooth.BluetoothAdapter')
- const adapter = BluetoothAdapter.getDefaultAdapter()
- resolve(adapter != null && adapter.isEnabled())
- } catch (e) {
- // 无法检测时放行,让后续流程处理
- resolve(true)
- }
- } else if (platform === 'ios') {
- // iOS 无法直接通过原生 API 检测,依赖 uni.openBluetoothAdapter 的结果
- resolve(true)
- } else {
- resolve(true)
- }
- // #endif
- // #ifndef APP-PLUS
- resolve(true)
- // #endif
- })
- }
- /** 跳转到系统蓝牙设置页面 */
- export function openBluetoothSettings() {
- // #ifdef APP-PLUS
- const platform = getPlatform()
- if (platform === 'android') {
- try {
- const main = plus.android.runtimeMainActivity()
- const Intent = plus.android.importClass('android.content.Intent')
- const Settings = plus.android.importClass('android.provider.Settings')
- const intent = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS)
- main.startActivity(intent)
- } catch (e) { console.error('跳转蓝牙设置失败', e) }
- } else if (platform === 'ios') {
- plus.runtime.openURL('App-Prefs:root=Bluetooth')
- }
- // #endif
- }
- /** 一键: 申请权限 + 校验定位服务 + 检测蓝牙开启. 失败抛异常 */
- export async function ensureBlePrerequisite() {
- const platform = getPlatform()
- if (platform === 'android') {
- const ok = await requestAndroidPermissions()
- if (!ok) throw new Error('BLE_PERMISSION_DENIED')
- const loc = await isLocationEnabled()
- if (!loc) throw new Error('BLE_LOCATION_OFF')
- }
- // 检测蓝牙是否开启(Android 原生检测,iOS 跳过此步)
- const bleOn = await isBluetoothEnabled()
- if (!bleOn) throw new Error('BLE_ADAPTER_OFF')
- return true
- }
|