前言
在移动应用开发中,位置服务是许多应用的核心功能之一。HarmonyOS提供了完善的位置服务能力,包括位置权限管理、实时定位、地理编码等功能。本文将详细介绍如何在HarmonyOS应用中实现位置服务的各种功能,包括权限申请、位置开关检测、实时定位获取等。
一、位置权限申请
在HarmonyOS中,位置权限分为两种:
ohos.permission.APPROXIMATELY_LOCATION
:模糊定位权限ohos.permission.LOCATION
:精确定位权限
1.1 权限检查与申请实现
首先,我们需要创建一个权限工具类来管理位置权限的检查和申请:
typescript
import { abilityAccessCtrl, bundleManager, Permissions, common, UIAbility } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { window } from '@kit.ArkUI';
const TAG = 'PermissionGrant ';
async function checkPermissionGrant(permission: Permissions): Promise<abilityAccessCtrl.GrantStatus> {
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
let grantStatus: abilityAccessCtrl.GrantStatus = abilityAccessCtrl.GrantStatus.PERMISSION_DENIED;
// 获取应用程序的accessTokenID
let tokenId: number = 0;
try {
let bundleInfo: bundleManager.BundleInfo = await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo;
tokenId = appInfo.accessTokenId;
} catch (error) {
const err: BusinessError = error as BusinessError;
console.error(`Failed to get bundle info for self. Code is ${err.code}, message is ${err.message}`);
}
// 校验应用是否被授予权限
try {
grantStatus = await atManager.checkAccessToken(tokenId, permission);
} catch (error) {
const err: BusinessError = error as BusinessError;
console.error(`Failed to check access token. Code is ${err.code}, message is ${err.message}`);
}
return grantStatus;
}
export async function checkPermissions(): Promise<string> {
let permissions: Array<Permissons> = ['ohos.permission.LOCATION', 'ohos.permission.APPROXIMATELY_LOCATION'];
let grantStatus1: boolean = await checkPermissionGrant('ohos.permission.LOCATION') === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED;
let grantStatus2: boolean = await checkPermissionGrant('ohos.permission.APPROXIMATELY_LOCATION') === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED;
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
if (grantStatus2 && !grantStatus1 || !grantStatus1 && !grantStatus2) {
console.log(TAG + '获取权限失败')
const result = await atManager.requestPermissionsFromUser(getContext(), permissions)
return '权限首次获取成功' + JSON.stringify(result)
} else {
console.log(TAG + '获取权限成功')
return '权限已经获取成功'
}
}
1.2 页面中调用权限申请
在页面中,我们可以通过按钮点击来触发权限申请:
typescript
import { checkPermissions } from '../utils/PermissionGrant';
@Entry
@Component
struct LocationKitTestPage {
@State message: string = 'hello'
build() {
Column({ space: 20 }) {
Button('用户申请位置授权')
.onClick(async () => {
const promiseString: Promise<string> = checkPermissions()
promiseString.then((stringValue: string) => {
this.message = stringValue
});
})
Text(this.message)
}
}
}
二、位置服务功能实现
2.1 检测位置开关状态
在使用位置服务前,最好先检查设备的位置服务是否已开启:
php
Button('判断位置开关是否打开')
.onClick(() => {
try {
let locationEnabled = geoLocationManager.isLocationEnabled();
if (locationEnabled == true) promptAction.showToast({ message: '开关已打开' })
else promptAction.showToast({ message: '开关未打开' })
} catch (err) {
promptAction.showToast({ message: "errCode:" + err.code + ", message:" + err.message })
}
})
2.2 获取实时位置信息
获取实时位置是位置服务的核心功能:
typescript
@State location: geoLocationManager.Location | null = null
Button('获取当前的实时位置')
.onClick(() => {
try {
geoLocationManager.on('locationChange', {}, (location) => {
this.location = location
});
} catch (err) {
promptAction.showToast({ message: "errCode:" + err.code + ", message:" + err.message })
}
})
Text(JSON.stringify(this.location, null, 2))
2.3 地理编码服务
HarmonyOS还提供了地理编码服务,可以将地址转换为坐标或反之:
javascript
Button('地理解析')
.onClick(async () => {
const location = await geoLocationManager.getAddressesFromLocationName({
description: '广州市'
})
promptAction.showToast({ message: JSON.stringify(location, null, 2) })
})
2.4 检查服务可用性
在使用地理编码服务前,可以先检查服务是否可用:
javascript
Button('判断服务是否可用')
.onClick(() => {
const isAvailable = geoLocationManager.isGeocoderAvailable()
promptAction.showToast({ message: '服务是否支持' + isAvailable })
})
三、完整页面实现
以下是完整的页面实现代码:
typescript
import { checkPermissions } from '../utils/PermissionGrant';
import { geoLocationManager } from '@kit.LocationKit';
import { AlertDialog, promptAction } from '@kit.ArkUI';
const TAG = 'LoacationKitTestPage ';
@Entry
@Component
struct LocationKitTestPage {
@State message: string = 'hello'
@State location: geoLocationManager.Location | null = null
build() {
Column({ space: 20 }) {
Button('用户申请位置授权')
.onClick(async () => {
const promiseString: Promise<string> = checkPermissions()
promiseString.then((stringValue: string) => {
this.message = stringValue
});
})
Button('判断位置开关是否打开')
.onClick(() => {
try {
let locationEnabled = geoLocationManager.isLocationEnabled();
if (locationEnabled == true) promptAction.showToast({ message: '开关已打开' })
else promptAction.showToast({ message: '开关未打开' })
} catch (err) {
promptAction.showToast({ message: "errCode:" + err.code + ", message:" + err.message })
}
})
Button('获取当前的实时位置')
.onClick(() => {
try {
geoLocationManager.on('locationChange', {}, (location) => {
this.location = location
});
} catch (err) {
promptAction.showToast({ message: "errCode:" + err.code + ", message:" + err.message })
}
})
Button('判断服务是否可用')
.onClick(() => {
const isAvailable = geoLocationManager.isGeocoderAvailable()
promptAction.showToast({ message: '服务是否支持' + isAvailable })
})
Button('地理解析')
.onClick(async () => {
const location = await geoLocationManager.getAddressesFromLocationName({
description: '广州市'
})
promptAction.showToast({ message: JSON.stringify(location, null, 2) })
})
Text(JSON.stringify(this.location, null, 2))
}
.height('100%')
.width('100%')
}
}
四、注意事项
-
权限声明 :在
module.json5
文件中需要声明所需的位置权限:json"requestPermissions": [ { "name": "ohos.permission.LOCATION" }, { "name": "ohos.permission.APPROXIMATELY_LOCATION" } ]
-
权限申请策略:精确定位权限只能与模糊定位权限一起申请,或者已经有模糊定位权限才能申请精确定位权限。
五、总结
本文详细介绍了HarmonyOS中位置服务的开发流程,包括:
- 位置权限的检查与申请
- 设备位置服务的开关检测
- 实时位置信息的获取
- 地理编码服务的实现
- 服务可用性检查
通过这些功能的组合,开发者可以轻松实现各种基于位置的服务和应用。在实际开发中,应根据应用需求合理使用这些功能,并注意权限管理和性能优化。
希望本文对您的HarmonyOS开发有所帮助!如果有任何问题,欢迎在评论区留言讨论。