export interface BluetoothPermissionResult { ok: boolean message?: string } function normalizePermissionName (permission: string): string { return String(permission || '').split('.').pop() || String(permission || '') } function formatDeniedMessage (permissions: string[]): string { if (!permissions.length) return 'Bluetooth permission denied.' return 'Please allow Bluetooth permissions: ' + permissions.map(normalizePermissionName).join(', ') } function requestAndroidPermissions (permissions: string[]): Promise { return new Promise((resolve) => { // #ifdef APP-PLUS try { if (typeof plus === 'undefined' || !plus.android || !permissions.length) { resolve({ ok: true }) return } plus.android.requestPermissions( permissions, (resultObj: any) => { const deniedPresent = Array.isArray(resultObj?.deniedPresent) ? resultObj.deniedPresent : [] const deniedAlways = Array.isArray(resultObj?.deniedAlways) ? resultObj.deniedAlways : [] const denied = [...deniedPresent, ...deniedAlways] if (denied.length > 0) { resolve({ ok: false, message: formatDeniedMessage(denied), }) return } resolve({ ok: true }) }, () => { resolve({ ok: false, message: 'Failed to request Bluetooth permissions.', }) } ) return } catch (e: any) { resolve({ ok: false, message: e?.message || 'Failed to request Bluetooth permissions.', }) return } // #endif resolve({ ok: true }) }) } export async function ensureBluetoothPermissions (options?: { scan?: boolean connect?: boolean }): Promise { const { scan = false, connect = false } = options || {} // #ifdef APP-PLUS try { if (typeof plus === 'undefined' || !plus.android) { return { ok: true } } const Build = plus.android.importClass('android.os.Build') const sdkInt = Number(Build.VERSION.SDK_INT || 0) const permissions = new Set() if (sdkInt >= 31) { if (scan) permissions.add('android.permission.BLUETOOTH_SCAN') if (scan || connect) permissions.add('android.permission.BLUETOOTH_CONNECT') if (scan) permissions.add('android.permission.ACCESS_FINE_LOCATION') } else if (scan) { permissions.add('android.permission.ACCESS_FINE_LOCATION') permissions.add('android.permission.ACCESS_COARSE_LOCATION') } return await requestAndroidPermissions(Array.from(permissions)) } catch (e: any) { return { ok: false, message: e?.message || 'Bluetooth permission check failed.', } } // #endif return { ok: true } }