写点什么

鸿蒙 NEXT 开发 - 位置服务

作者:东林知识库

1. 位置服务基本介绍

移动终端设备已经深入人们日常生活的方方面面,如查看所在城市的天气、新闻轶事、出行打车、旅行导航、运动记录。这些习以为常的活动,都离不开定位用户终端设备的位置。


鸿蒙的位置服务(Location Kit)提供了基础的定位服务,还提供了地理围栏、地理编码、逆地理编码、国家码等功能和接口。


使用位置时服务请打开设备“位置”开关。如果位置功能关闭并且代码未设置捕获异常,可能导致应用异常。模拟器不行,大家记得在真机上测试使用位置服务。

2. 申请位置权限

应用在使用 Location Kit 系统能力前,需要检查是否已经获取用户授权访问设备位置信息。如未获得授权,可以向用户申请需要的位置权限。


系统提供的定位权限有:


  • ohos.permission.LOCATION:用于获取精准位置,精准度在米级别。

  • ohos.permission.APPROXIMATELY_LOCATION:用于获取模糊位置,精确度为 5 公里。

  • ohos.permission.LOCATION_IN_BACKGROUND:用于应用切换到后台仍然需要获取定位信息的场景。


当应用需要访问用户的隐私信息或使用系统能力时,例如获取位置信息、访问日历、使用相机拍摄照片或录制视频等,应该向用户请求授权,这部分权限是 user_grant 权限。


当应用申请 user_grant 权限时,需要完成以下步骤:


  1. 在配置文件中,声明应用需要请求的权限。

  2. 将应用中需要申请权限的目标对象与对应目标权限进行关联,让用户明确地知道,哪些操作需要用户向应用授予指定的权限。

  3. 运行应用时,在用户触发访问操作目标对象时应该调用接口,精准触发动态授权弹框。该接口的内部会检查当前用户是否已经授权应用所需的权限,如果当前用户尚未授予应用所需的权限,该接口会拉起动态授权弹框,向用户请求授权。

  4. 检查用户的授权结果,确认用户已授权才可以进行下一步操作。


"requestPermissions":[  {    "name" : "ohos.permission.APPROXIMATELY_LOCATION",    "reason": "$string:permission_location",    "usedScene": {      "abilities": [        "EntryAbility"      ],      "when":"inuse"    }  }],
复制代码


官方文档:


文档中心

3. 获取设备的位置信息

3.1 基本介绍

开发者可以调用 HarmonyOS 位置相关接口,获取设备实时位置,或者最近的历史位置,以及监听设备的位置变化。


对于位置敏感的应用业务,建议获取设备实时位置信息。如果不需要设备实时位置信息,并且希望尽可能的节省耗电,开发者可以考虑获取最近的历史位置。

3.2 接口说明

获取设备的位置信息接口介绍


3.3 代码实现

3.3.1 配置文件加上位置权限信息

注意:记得在 module.json5 配置位置权限


"requestPermissions":[  {    "name" : "ohos.permission.APPROXIMATELY_LOCATION",    "reason": "$string:permission_location",    "usedScene": {      "abilities": [        "EntryAbility"      ],      "when":"inuse"    }  }],
复制代码

3.3.2 获取坐标代码


编辑



编辑



编辑


import { geoLocationManager } from '@kit.LocationKit';import { BusinessError } from '@kit.BasicServicesKit'import { abilityAccessCtrl, common, Permissions } from '@kit.AbilityKit';import { promptAction } from '@kit.ArkUI';
@Entry@Componentstruct Index { @State location: string = '' @State latitude: number = 0 @State longitude: number = 0
/** * 动态授权 */ aboutToAppear(): void { // 使用UIExtensionAbility:将common.UIAbilityContext 替换为common.UIExtensionContext const context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext; // 定义要申请的权限 const permissions: Array<Permissions> = ['ohos.permission.APPROXIMATELY_LOCATION']; let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager(); // requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗 atManager.requestPermissionsFromUser(context, permissions).then((data) => { let grantStatus: Array<number> = data.authResults; let length: number = grantStatus.length; for (let i = 0; i < length; i++) { if (grantStatus[i] === 0) { // 用户授权,可以继续访问目标操作 promptAction.showToast({ message: '用户授权当前定位功能成功' }) } else { // 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限 promptAction.showToast({ message: '用户必须授权才能访问当前定位功能' }) return; } } // 授权成功 }).catch((err: BusinessError) => { console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`); }) }
/** * 获取位置 */ getLocation() { let request: geoLocationManager.SingleLocationRequest = { 'locatingPriority': geoLocationManager.LocatingPriority.PRIORITY_LOCATING_SPEED, 'locatingTimeoutMs': 10000 } try { geoLocationManager.getCurrentLocation(request).then((result) => { // 调用getCurrentLocation获取当前设备位置,通过promise接收上报的位置 console.log('current location: ' + JSON.stringify(result)); this.latitude = result.latitude this.longitude = result.longitude }) .catch((error: BusinessError) => { // 接收上报的错误码 console.error('promise, getCurrentLocation: error=' + JSON.stringify(error)); }); } catch (err) { console.error("errCode:" + JSON.stringify(err)); } }
build() { Column() { Button('获取当前位置').onClick(() => { this.getLocation() }).margin(100)
Text('当前位置') Text('纬度:'+this.latitude) Text('经度:'+this.longitude)
}.width('100%') .height('100%')
}}
复制代码

3.3.3 将经纬度坐标转换成实际地理位置信息(地理编码转化)


编辑


import { geoLocationManager } from '@kit.LocationKit';import { BusinessError } from '@kit.BasicServicesKit'import { abilityAccessCtrl, common, Permissions } from '@kit.AbilityKit';import { promptAction } from '@kit.ArkUI';
@Entry @Component struct Index { @State location: string = '' @State latitude: number = 0 @State longitude: number = 0
/** * 动态授权 */ aboutToAppear(): void { // 使用UIExtensionAbility:将common.UIAbilityContext 替换为common.UIExtensionContext const context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext; // 定义要申请的权限 const permissions: Array<Permissions> = ['ohos.permission.APPROXIMATELY_LOCATION']; let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager(); // requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗 atManager.requestPermissionsFromUser(context, permissions).then((data) => { let grantStatus: Array<number> = data.authResults; let length: number = grantStatus.length; for (let i = 0; i < length; i++) { if (grantStatus[i] === 0) { // 用户授权,可以继续访问目标操作 promptAction.showToast({ message: '用户授权当前定位功能成功' }) } else { // 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限 promptAction.showToast({ message: '用户必须授权才能访问当前定位功能' }) return; } } // 授权成功 }).catch((err: BusinessError) => { console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`); }) }
/** * 获取位置 */ getLocation() { let request: geoLocationManager.SingleLocationRequest = { 'locatingPriority': geoLocationManager.LocatingPriority.PRIORITY_LOCATING_SPEED, 'locatingTimeoutMs': 10000 } try { geoLocationManager.getCurrentLocation(request).then((result) => { // 调用getCurrentLocation获取当前设备位置,通过promise接收上报的位置 console.log('current location: ' + JSON.stringify(result)); // 获取坐标 this.latitude = result.latitude this.longitude = result.longitude // 判断地理编码服务是否可用 try { let isAvailable = geoLocationManager.isGeocoderAvailable(); if (isAvailable) { let reverseGeocodeRequest: geoLocationManager.ReverseGeoCodeRequest = { "latitude": this.latitude, "longitude": this.longitude, "maxItems": 1 }; try { geoLocationManager.getAddressesFromLocation(reverseGeocodeRequest, (err, data) => { if (err) { console.log('getAddressesFromLocation err: ' + JSON.stringify(err)); } else { console.log('getAddressesFromLocation data: ' + JSON.stringify(data)); // 成功获取到位置信息 this.location = data[0].placeName+'' return } }); } catch (err) { console.error("errCode:" + JSON.stringify(err)); } }else{ promptAction.showToast({ message: '地理编码服务不可用' }) }
} catch (err) { console.error("errCode:" + JSON.stringify(err)); } }) .catch((error: BusinessError) => { // 接收上报的错误码 console.error('promise, getCurrentLocation: error=' + JSON.stringify(error)); }); } catch (err) { console.error("errCode:" + JSON.stringify(err)); } }
build() { Column() { Button('获取当前位置').onClick(() => { this.getLocation() }).margin(100)
Text('当前位置') Text('当前具体位置:' + this.location)
}.width('100%') .height('100%')
}}
复制代码


发布于: 2 小时前阅读数: 10
用户头像

享受当下,享受生活,享受成长乐趣! 2025-02-26 加入

鸿蒙、Java、大数据

评论

发布
暂无评论
鸿蒙NEXT开发-位置服务_东林知识库_InfoQ写作社区