- 示例工程
- 前端
- 移动开发
- 跨平台
【免费下载链接】uni-app
A cross-platform framework using Vue.js
本篇技术指南围绕 uni-app x(uni-app 跨端框架的下一代演进,基于 UTS 语言)提供的
uni.getSystemSetting()API 展开,讲解如何同步读取设备蓝牙、Wi-Fi、定位开关状态与设备方向等系统设置。文档主体与配套源码位于 docs/api/get-system-setting.md 及 src/uni_modules/uni-getSystemSetting 插件目录。读完本文,你将掌握该 API 的完整返回结构、各平台(Android/iOS/HarmonyOS/微信小程序)的兼容性差异与底层实现原理,并能基于仓库示例编写可运行的系统设置读取页面、正确处理权限缺失场景。
一、API 概览:什么是 uni.getSystemSetting()
uni.getSystemSetting()是一个同步API,用于获取当前设备的系统级设置状态,包括蓝牙是否开启、地理位置服务是否开启、Wi-Fi 是否开启,以及当前设备方向(横屏/竖屏)。它不需要任何参数,直接返回一个GetSystemSettingResult对象:
const res = uni.getSystemSetting();从 接口定义 可以看到其类型签名:
export type GetSystemSetting = () => GetSystemSettingResult也就是说,调用该 API 时无需传入任何配置,调用后立即拿到结果,非常适合在页面初始化、权限检查或功能入口前判断系统环境。
平台兼容性
| Web | 微信小程序 | Android | iOS | HarmonyOS | | :- | :- | :- | :- | :- | | 不支持(x) | 4.41 | 3.9 | 4.11 | 4.61 |
兼容性说明:
- Web 端完全不支持,调用无效,该 API 仅面向 App 与小程序场景;
- 微信小程序自基础库 4.41 起支持;
- App 端三个平台的支持版本分别标注在 interface.uts 的
@uniPlatform注释中:Android 需 uni-app x 3.9+,iOS 需 4.11+,HarmonyOS 需 uni-app x 4.61+(uniVer标注的 4.25/4.31 为 uni-app 编译器版本号,unixVer才是 uni-app x 版本号); - 除微信小程序外,支付宝、百度、抖音、飞书(Lark)、QQ、快手、京东等小程序平台在 uni-app x 中均未实现(标注为
x)。
二、返回值 GetSystemSettingResult 属性详解
调用uni.getSystemSetting()后返回的GetSystemSettingResult对象,共包含 6 个属性:
| 名称 | 类型 | 必备 | 描述 | | :- | :- | :- | :- | | bluetoothEnabled | boolean | 否 | 蓝牙是否开启 | | bluetoothError | string | 否 | 蓝牙的报错信息 | | locationEnabled | boolean | 是 | 位置服务是否开启 | | wifiEnabled | boolean | 否 | Wi-Fi 是否开启 | | wifiError | string | 否 | Wi-Fi 的报错信息 | | deviceOrientation | string | 是 | 设备方向 |
各属性的平台差异
对照 interface.uts 中每个字段的@uniPlatform注释,可以精确还原各平台支持情况:
- bluetoothEnabled / bluetoothError:微信小程序 4.41、Android 3.9、iOS 4.11、HarmonyOS 4.61 均支持;Web 不支持。
- locationEnabled:所有支持该 API 的平台均返回(必备字段),用于判断系统定位总开关。
- wifiEnabled / wifiError:注意差异——微信小程序与 Android、HarmonyOS 支持,iOS 不支持 Wi-Fi 状态读取(标注为
x),因此 iOS 上不会返回这两个字段。 - deviceOrientation:所有平台均返回(必备字段)。
deviceOrientation 合法值
| 合法值 | 描述 | | :- | :- | | portrait | 纵向(竖屏) | | landscape | 横向(横屏) |
在类型定义中,该字段被声明为字符串字面量联合类型:
deviceOrientation: /** * 纵向 */ 'portrait' | /** * 横向 */ 'landscape',这表示返回结果只会是'portrait'或'landscape'两者之一,便于开发者直接进行类型安全的判断。
关于返回字段为空的说明
bluetoothEnabled、wifiEnabled是可选属性,在平台不支持、或权限不足导致无法读取时可能为undefined;而locationEnabled与deviceOrientation是必备字段,任何支持平台上都会返回明确值。示例代码中正是通过res.bluetoothEnabled ?? false这样的空值合并写法来兜底,避免undefined影响布尔判断。
三、各平台底层实现原理(源码级解析)
作为 UTS 插件实现,uni-getSystemSetting 按平台拆分实现,位于utssdk目录下,各平台编译为目标平台原生语言:Android 编译为 Kotlin、iOS 编译为 Swift、HarmonyOS 编译为 ArkTS。下面逐一分析其底层读取逻辑。
3.1 Android:DeviceUtil 工具类
Android 入口 app-android/index.uts 首先构造基础结果,再分别读取蓝牙与 Wi-Fi 状态,并使用try/catch捕获权限异常:
export const getSystemSetting : GetSystemSetting = () : GetSystemSettingResult => { let context = UTSAndroid.getAppContext(); let result : GetSystemSettingResult = { deviceOrientation : DeviceUtil.deviceOrientation(context!), locationEnabled : DeviceUtil.locationEnable(context!), }; try { let blueToothEnable = DeviceUtil.blueToothEnable(context!); result.bluetoothEnabled = blueToothEnable; } catch (e : Exception) { result.bluetoothError = "Missing permissions required by BluetoothAdapter.isEnabled: android.permission.BLUETOOTH"; } try { result.wifiEnabled = DeviceUtil.wifiEnable(context!); } catch (e : Exception) { result.wifiError = "Missing permissions required by WifiManager.isWifiEnabled: android.permission.ACCESS_WIFI_STATE"; } return result; }具体读取逻辑封装在 app-android/device/DeviceUtil.uts 中:
- 蓝牙状态:Android 6.0(API 23)及以上会先通过
context.checkSelfPermission(Manifest.permission.BLUETOOTH)检查蓝牙权限,若被拒绝则直接抛出异常;随后通过BluetoothManager.getAdapter().isEnabled()判断蓝牙是否开启。 - 定位状态:Android 9(API 28)及以上使用
LocationManager.isLocationEnabled()读取系统定位总开关;低版本则回退读取Settings.Secure.LOCATION_MODE设置项,与LOCATION_MODE_OFF比较。 - Wi-Fi 状态:通过
WifiManager.getWifiState()与WifiManager.WIFI_STATE_ENABLED比较判断。 - 设备方向:读取
Resources.getConfiguration().orientation,与ORIENTATION_PORTRAIT/ORIENTATION_LANDSCAPE比对后映射为'portrait'/'landscape',其余情况返回空字符串。
从实现可见:蓝牙与 Wi-Fi 的读取依赖对应权限,未配置权限时 API 不会崩溃,而是把错误信息写入bluetoothError/wifiError字段。
3.2 iOS:原生桥接 UTSiOS.getSystemSetting()
iOS 实现 app-ios/index.uts 直接调用框架层提供的原生方法UTSiOS.getSystemSetting(),返回一个Map,随后逐字段取出并装配成GetSystemSettingResult:
export const getSystemSetting : GetSystemSetting = () : GetSystemSettingResult => { let setting : Map<string, any> = UTSiOS.getSystemSetting(); let result : GetSystemSettingResult = { deviceOrientation: "portrait", locationEnabled : false }; ... }值得注意的是,iOS 端deviceOrientation默认初始化为"portrait"、locationEnabled默认false,再根据原生返回的 Map 中实际存在的键覆盖更新。由于 iOS 不提供 Wi-Fi 状态读取(对应文档中wifiError在 iOS 标注为x),该字段在 iOS 上不会返回。
3.3 HarmonyOS:ArkTS 系统能力封装
鸿蒙实现 app-harmony/index.uts 使用了defineSyncApi定义同步 API,并调用鸿蒙系统 Kit 能力:
- 设备方向:通过
display.getDefaultDisplaySync().orientation判断,PORTRAIT或PORTRAIT_INVERTED归为'portrait',其余归为'landscape'; - 蓝牙:
access.getState() === access.BluetoothState.STATE_ON(来自@kit.ConnectivityKit); - 定位:
geoLocationManager.isLocationEnabled()(来自@kit.LocationKit); - Wi-Fi:
wifiManager.isWifiActive()(来自@kit.ConnectivityKit)。
与 Android 一致的容错策略是:蓝牙与 Wi-Fi 读取均包裹在try/catch中,异常时把BusinessError.message写入对应的bluetoothError/wifiError字段。
四、完整可运行示例(hello uni-app x 页面)
官方示例页面位于仓库 src/pages/API/get-system-setting/get-system-setting.uvue,与 docs/api/get-system-setting.md 中给出的示例一致。页面 UI 上展示蓝牙开关、定位开关、Wi-Fi 开关与设备方向四个只读输入框,点击按钮后调用 API 填充数据:
<template> <view class="uni-common-mt"> <view class="uni-list"> <view class="uni-list-cell"> <view class="uni-pd"> <view class="uni-label" style="width:180px;">蓝牙的系统开关</view> </view> <view class="uni-list-cell-db"> <input type="text" :disabled="true" placeholder="未获取" :value="data.bluetoothEnabled" /> </view> </view> <!-- 地理位置的系统开关 / Wi-Fi 的系统开关 / 设备方向 结构相同 --> </view> <view class="uni-padding-wrap"> <view class="uni-btn-v"> <button type="primary" @tap="getSystemSetting">获取系统设置</button> </view> </view> </view> </template> <script setup lang="uts"> type DataType = { bluetoothEnabled: string; locationEnabled: string; wifiEnabled: string; deviceOrientation: string; } const title = ref('getSystemSetting') const data = reactive({ bluetoothEnabled: "", locationEnabled: "", wifiEnabled: "", deviceOrientation: "" } as DataType) const getSystemSetting = () => { const res = uni.getSystemSetting(); data.bluetoothEnabled = (res.bluetoothEnabled ?? false) ? "开启" : "关闭"; data.locationEnabled = res.locationEnabled ? "开启" : "关闭"; data.wifiEnabled = (res.wifiEnabled ?? false) ? "开启" : "关闭"; data.deviceOrientation = res.deviceOrientation if (res.bluetoothError != null) { data.bluetoothEnabled = "无蓝牙权限" } if (res.wifiError != null) { data.wifiEnabled = "无WiFi权限" } } </script>示例要点解读:
??空值合并:由于bluetoothEnabled、wifiEnabled是可选字段(部分平台不返回),用?? false保证三元判断永远可用;- 错误提示透出:当
bluetoothError/wifiError非空时,直接把 UI 文案置为“无蓝牙权限”“无WiFi权限”,即错误字段既承担诊断信息、又可直接映射为用户提示; - 该 API 为同步调用,无需
async/await,页面中可直接在事件回调里读取结果。
注意:由于 Web 端不支持,请将示例运行到 App 平台(Android/iOS/HarmonyOS 真机或模拟器)体验。
五、注意事项与权限配置
官方文档中明确指出:
如果出现
bluetoothError、wifiError非空的情况,就说明权限配置错误,需要根据文档正确配置权限。
结合 Android 实现 的源码,可以精确确认各平台所需权限:
| 平台 | 能力 | 所需权限 | 缺失时表现 | | :- | :- | :- | :- | | Android | 蓝牙状态 |android.permission.BLUETOOTH|bluetoothError非空 | | Android | Wi-Fi 状态 |android.permission.ACCESS_WIFI_STATE|wifiError非空 | | HarmonyOS | 蓝牙/定位/Wi-Fi | 对应系统 Kit 能力 | 写入对应*Error字段 | | iOS | 蓝牙/定位 | 由框架层UTSiOS.getSystemSetting()处理 | 不返回或返回错误字段 |
在 App 端,Android 原生权限的声明需要配置在原生工程中,具体配置方法可参考仓库内 app-nativeresource-android.md 文档中关于权限(permissions)的说明章节。此外,仓库根目录 AndroidManifest.xml 是 App 端工程清单文件的参考实现,可对照检查权限声明。
排查建议
- 如果
bluetoothError出现Missing permissions required by BluetoothAdapter.isEnabled: android.permission.BLUETOOTH字样,说明 Android 工程未声明蓝牙权限; - 如果
wifiError出现Missing permissions required by WifiManager.isWifiEnabled: android.permission.ACCESS_WIFI_STATE字样,说明未声明 Wi-Fi 状态读取权限; - 定位开关(
locationEnabled)的读取在 Android 上不依赖运行时权限,但如果你后续要使用定位功能,仍需按定位 API 的要求申请ACCESS_FINE_LOCATION/ACCESS_COARSE_LOCATION; - 由于 Web 不支持、且各小程序平台支持度不一(详见 interface.uts 的
@uniPlatform注释),建议在调用前使用条件编译或平台判断,避免在 Web 端误用。
六、自动化测试:行为契约验证
仓库为getSystemSetting提供了自动化测试用例 src/pages/API/get-system-setting/get-system-setting.test.js,从中可以提炼出 API 的行为契约:
- Web 与 App WebView 环境直接跳过测试(呼应“不支持 Web”);
- 测试断言:若
bluetoothEnabled为undefined或false,则bluetoothError必须非空——即蓝牙未开启或权限缺失必然伴随错误信息; - 反之,若
bluetoothEnabled为true,则bluetoothError应为undefined——成功读取时不得有错误信息; - Wi-Fi 字段遵循同样的互斥逻辑;
deviceOrientation的取值必须落在['portrait', 'landscape']集合内,即返回值的合法范围是强约束。
这套测试也印证了文档中返回字段的设计意图:bluetoothEnabled/bluetoothError、wifiEnabled/wifiError是“成对出现”的状态与诊断信息,任何一次调用都能明确区分“已开启 / 已关闭 / 无法读取(权限问题)”三种情况。
七、典型应用场景
- 功能入口引导:进入蓝牙配对、扫码、地图等页面之前,先判断系统开关是否打开,未打开时弹出提示引导用户去系统设置开启;
- 横竖屏适配判断:根据
deviceOrientation动态调整 UI 布局或提示用户旋转设备; - 权限自助诊断:把
bluetoothError/wifiError直接展示给用户,说明是权限配置问题而非功能不可用; - 与 getSystemInfo 互补:
uni.getSystemSetting()关注“系统设置开关”,而 get-system-info 关注设备信息与硬件参数,两者可组合使用构建完整的设备环境画像。
八、延伸阅读
- API 官方说明:docs/api/get-system-setting.md(本文档原始出处)
- 插件实现源码:src/uni_modules/uni-getSystemSetting
- 类型定义与平台标注:src/uni_modules/uni-getSystemSetting/utssdk/interface.uts
- Android 实现:src/uni_modules/uni-getSystemSetting/utssdk/app-android/index.uts
- HarmonyOS 实现:src/uni_modules/uni-getSystemSetting/utssdk/app-harmony/index.uts
- iOS 实现:src/uni_modules/uni-getSystemSetting/utssdk/app-ios/index.uts
- 示例页面:src/pages/API/get-system-setting/get-system-setting.uvue
- 自动化测试:src/pages/API/get-system-setting/get-system-setting.test.js
- Android 原生权限配置:docs/collocation/app-nativeresource-android.md
此外,GeneralCallbackResult是 uni-app x 通用错误回调类型(含errMsg字段),详见 docs/api/get-system-setting.md 末尾的“通用类型”一节,可供理解其他 API 的错误信息结构时参考。
- 示例工程
- 前端
- 移动开发
- 跨平台
【免费下载链接】uni-app
A cross-platform framework using Vue.js
相关推荐
uni-app x 系统分享插件 uni-shareWithSystem:跨端调用系统分享的 UTS 实现与实战指南
uni app x 系统分享插件 uni shareWithSystem:跨端调用系统分享的 UTS 实现与实战指南 本篇技术指南聚焦 uni app x 生态
示例工程前端移动开发跨平台uni-app x 权限管理实战:uni.openAppAuthorizeSetting 跳转系统授权管理页完全指南
uni app x 权限管理实战:uni.openAppAuthorizeSetting 跳转系统授权管理页完全指南 导读 uni.openAppAuthori
示例工程前端移动开发跨平台uni-app x 网络类型获取指南:uni.getNetworkType 跨端实现与源码解析
uni app x 网络类型获取指南:uni.getNetworkType 跨端实现与源码解析 获取设备当前网络类型(Wi Fi、2G/3G/4G/5G、无网络
示例工程前端移动开发跨平台
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考