监听罗盘数据变化事件。频率:5 次/秒,接口调用后会自动开始监听
| Web | 微信小程序 | Android | iOS | iOS uni-app x UTS 插件 | HarmonyOS | HarmonyOS(Vapor) |
|---|---|---|---|---|---|---|
| 4.0 | 4.41 | 5.08 | 5.08 | x | 5.08 | 5.08 |
| 名称 | 类型 | 必填 | 默认值 | 兼容性 | 描述 |
|---|---|---|---|---|---|
| callback | (result: OnCompassChangeCallbackResult) => void | 是 | - | - | 罗盘数据变化事件的监听函数 |
| 名称 | 类型 | 必备 | 默认值 | 兼容性 | 描述 |
|---|---|---|---|---|---|
| direction | number | 是 | - | - | 面对的方向度数 |
| accuracy | number | string | 否 | - | - | 精度 |
| errMsg | string | 否 | - | - | 错误信息 |
取消监听罗盘数据
| Web | 微信小程序 | Android | iOS | iOS uni-app x UTS 插件 | HarmonyOS | HarmonyOS(Vapor) |
|---|---|---|---|---|---|---|
| 4.0 | 4.41 | 5.08 | 5.08 | x | 5.08 | 5.08 |
| 名称 | 类型 | 必填 | 默认值 | 兼容性 | 描述 |
|---|---|---|---|---|---|
| callback | (result: OnCompassChangeCallbackResult) => void | 否 | - | - | onCompassChange 传入的监听函数。不传此参数则移除所有监听函数。 |
| 名称 | 类型 | 必备 | 默认值 | 兼容性 | 描述 |
|---|---|---|---|---|---|
| direction | number | 是 | - | - | 面对的方向度数 |
| accuracy | number | string | 否 | - | - | 精度 |
| errMsg | string | 否 | - | - | 错误信息 |
开始监听罗盘数据
| Web | 微信小程序 | Android | iOS | HarmonyOS | HarmonyOS(Vapor) |
|---|---|---|---|---|---|
| 4.0 | 4.41 | 5.08 | 5.08 | 5.08 | 5.08 |
| 名称 | 类型 | 必填 | 默认值 | 兼容性 | 描述 | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| options | StartCompassOptions | 否 | - | - | 开始监听罗盘数据的参数 | ||||||||||||||||||||||||
| |||||||||||||||||||||||||||||
| 名称 | 类型 | 必备 | 默认值 | 兼容性 | 描述 |
|---|---|---|---|---|---|
| errMsg | string | 否 | - | - |
| 名称 | 类型 | 必备 | 默认值 | 兼容性 | 描述 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| errCode | number | 是 | - | - | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| errSubject | string | 是 | - | - | 统一错误主题(模块)名称 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| data | any | 否 | - | - | 错误信息中包含的数据 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cause | Error | 否 | - | - | 源错误信息,可以包含多个错误,详见SourceError | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| errMsg | string | 是 | - | - | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
停止监听罗盘数据
| Web | 微信小程序 | Android | iOS | HarmonyOS | HarmonyOS(Vapor) |
|---|---|---|---|---|---|
| 4.0 | 4.41 | 5.08 | 5.08 | 5.08 | 5.08 |
| 名称 | 类型 | 必填 | 默认值 | 兼容性 | 描述 | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| options | StopCompassOptions | 否 | - | - | 停止监听罗盘数据的参数 | ||||||||||||||||||||||||
| |||||||||||||||||||||||||||||
| 名称 | 类型 | 必备 | 默认值 | 兼容性 | 描述 |
|---|---|---|---|---|---|
| errMsg | string | 否 | - | - |
| 名称 | 类型 | 必备 | 默认值 | 兼容性 | 描述 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| errCode | number | 是 | - | - | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| errSubject | string | 是 | - | - | 统一错误主题(模块)名称 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| data | any | 否 | - | - | 错误信息中包含的数据 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cause | Error | 否 | - | - | 源错误信息,可以包含多个错误,详见SourceError | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| errMsg | string | 是 | - | - | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
示例为hello uni-app x alpha分支,与最新HBuilderX Alpha版同步。与最新正式版同步的master分支示例另见
示例
<template>
<!-- #ifdef APP -->
<scroll-view style="flex: 1;padding: 6px;">
<!-- #endif -->
<text class="uni-h2">罗盘 API</text>
<text class="notice">演示 `uni.startCompass`、`uni.stopCompass`、`uni.onCompassChange`、`uni.offCompassChange` 的完整流程。靠近强磁场或金属物体时数据可能抖动,可做“8”字校准。Web平台需使用https</text>
<text class="margin-v">先绑定监听,再启动采集,更容易观察回调是否生效。</text>
<text class="uni-h3">实时信息</text>
<view class="panel-list">
<text class="panel-item" v-for="item in infoItems" :key="item.label">{{ item.label }}:{{ item.value }}</text>
</view>
<text class="uni-h3">当前方位</text>
<view class="compass-card">
<view class="bg-compass-line"></view>
<image class="bg-compass" src="/static/compass.png" :style="compassStyle" />
<view class="direction-center">
<text class="direction-value">{{ directionText }}</text>
<text class="direction-degree">{{ degreeText }}</text>
</view>
</view>
<view class="uni-row">
<button id="btn-bind-primary-listener" class="margin-v" @tap="bindPrimaryListener">注册罗盘Change</button>
<button id="btn-remove-primary-listener" class="margin-v" style="margin-left: 3px;" @tap="removePrimaryListener">注销罗盘Change</button>
</view>
<view class="uni-row">
<button id="btn-start-compass" class="margin-v" type="primary" @tap="startCompassListen">uni.startCompass</button>
<button id="btn-stop-compass" class="margin-v" style="margin-left: 3px;" @tap="stopCompassListen">uni.stopCompass</button>
</view>
<text>重复绑定测试</text>
<view class="uni-row">
<button id="btn-bind-secondary-listener" class="margin-v" @tap="bindSecondaryListener">注册罗盘Change2</button>
<button id="btn-remove-secondary-listener" class="margin-v" style="margin-left: 3px;" @tap="removeSecondaryListener">注销罗盘Change2</button>
</view>
<text class="uni-h3">监听日志</text>
<view class="panel-list">
<text class="panel-item" v-for="item in logItems" :key="item.id">{{ item.text }}</text>
</view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script setup lang="uts">
type DisplayItem = {
label : string
value : string
}
type PageCompassAccuracy = number | string | null
type LogItem = {
id : number
text : string
}
const statusText = ref('未启动')
const direction = ref(0)
const directionText = ref('北')
const accuracyText = ref('null')
const primaryBound = ref(false)
const secondaryBound = ref(false)
const lastAction = ref('等待调用')
const lastStatus = ref('未执行')
const lastPayload = ref('请先绑定监听并开始采集')
const logItems = ref<Array<LogItem>>([])
const logId = ref(0)
const infoItems = computed(() : Array<DisplayItem> => {
return [
{ label: '监听状态', value: statusText.value },
{ label: '主监听', value: primaryBound.value ? '已绑定' : '未绑定' },
{ label: '额外监听', value: secondaryBound.value ? '已绑定' : '未绑定' },
{ label: 'accuracy', value: accuracyText.value },
{ label: '最近动作', value: lastAction.value },
{ label: '状态', value: lastStatus.value },
{ label: '说明', value: lastPayload.value }
]
})
function pushLog(line : string) : void {
logId.value = logId.value + 1
const item : LogItem = {
id: logId.value,
text: line
}
logItems.value.unshift(item)
if (logItems.value.length > 10) {
logItems.value.splice(10)
}
}
function updateResult(action : string, status : string, payload : string) : void {
lastAction.value = action
lastStatus.value = status
lastPayload.value = payload
pushLog(`${action} -> ${status}`)
}
function formatDirection(value : number) : string {
return value.toFixed(1)
}
function formatAccuracy(value : PageCompassAccuracy) : string {
if (value == null) {
return 'null'
}
if (typeof value == 'number') {
return value.toFixed(2)
}
return value
}
function resolveDirectionText(value : number) : string {
if (value >= 337.5 || value < 22.5) {
return '北'
}
if (value < 67.5) {
return '东北'
}
if (value < 112.5) {
return '东'
}
if (value < 157.5) {
return '东南'
}
if (value < 202.5) {
return '南'
}
if (value < 247.5) {
return '西南'
}
if (value < 292.5) {
return '西'
}
return '西北'
}
const compassStyle = computed(() : string => {
return `transform: rotate(${-direction.value}deg);`
})
const degreeText = computed(() : string => {
return `${formatDirection(direction.value)}°`
})
const primaryListener : OnCompassChangeCallback = (result : OnCompassChangeCallbackResult) => {
direction.value = result.direction
directionText.value = resolveDirectionText(result.direction)
accuracyText.value = formatAccuracy(result.accuracy != null ? result.accuracy : null)
statusText.value = '监听中'
}
const secondaryListener : OnCompassChangeCallback = (result : OnCompassChangeCallbackResult) => {
pushLog(`额外监听 -> ${formatDirection(result.direction)}° / accuracy ${formatAccuracy(result.accuracy != null ? result.accuracy : null)}`)
}
function ensurePrimaryBound() : void {
if (!primaryBound.value) {
uni.onCompassChange(primaryListener)
primaryBound.value = true
}
}
function bindPrimaryListener() : void {
ensurePrimaryBound()
updateResult('onCompassChange(primary)', '已绑定', '主监听已注册')
}
function bindSecondaryListener() : void {
if (!secondaryBound.value) {
uni.onCompassChange(secondaryListener)
secondaryBound.value = true
}
updateResult('onCompassChange(extra)', '已绑定', '额外监听已注册')
}
function removePrimaryListener() : void {
uni.offCompassChange(primaryListener)
primaryBound.value = false
updateResult('offCompassChange(primary)', '已解绑', '主监听已移除')
}
function removeSecondaryListener() : void {
uni.offCompassChange(secondaryListener)
secondaryBound.value = false
updateResult('offCompassChange(extra)', '已解绑', '额外监听已移除')
}
function startCompassListen() : void {
ensurePrimaryBound()
uni.startCompass({
success: (res) => {
statusText.value = '监听中'
const message = res.errMsg != null ? res.errMsg as string : 'startCompass:ok'
updateResult('startCompass', '成功', message)
},
fail: (error) => {
statusText.value = '启动失败'
const message = error.errMsg != null ? error.errMsg : 'startCompass:fail'
updateResult('startCompass', `失败 (${error.errCode})`, message)
}
})
}
function stopCompassListen() : void {
uni.stopCompass({
success: (res) => {
statusText.value = '已停止'
const message = res.errMsg != null ? res.errMsg as string : 'stopCompass:ok'
updateResult('stopCompass', '成功', message)
},
fail: (error) => {
const message = error.errMsg != null ? error.errMsg : 'stopCompass:fail'
updateResult('stopCompass', `失败 (${error.errCode})`, message)
}
})
}
onUnload(() => {
uni.offCompassChange(primaryListener)
uni.offCompassChange(secondaryListener)
uni.stopCompass()
});
defineExpose({
startCompassListen
})
</script>
<style>
.margin-v {
margin: 5px 0;
}
.notice {
color: #6b2d16;
font-size: 14px;
}
.panel-list {
margin: 5px 0;
padding: 10px;
border: 1px solid #ccc;
display: flex;
flex-direction: column;
}
.panel-item {
font-size: 14px;
margin: 4px 0;
}
.compass-card {
position: relative;
margin: 12px auto;
width: 270px;
height: 270px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.direction-center {
position: relative;
z-index: 1;
display: flex;
flex-direction: column;
align-items: center;
}
.direction-value {
font-size: 30px;
}
.direction-degree {
font-size: 16px;
margin-top: 6px;
}
.bg-compass {
position: absolute;
top: 0;
left: 0;
width: 270px;
height: 270px;
transition-duration: 0.1s;
}
.bg-compass-line {
position: absolute;
left: 134px;
top: -5px;
width: 3px;
height: 28px;
background-color: #1aad19;
border-radius: 100px;
z-index: 1;
}
</style>
| 名称 | 类型 | 必备 | 默认值 | 兼容性 | 描述 |
|---|---|---|---|---|---|
| errMsg | string | 是 | - | 错误信息 |