鸿蒙定位开发服务

引言

        鸿蒙操作系统(HarmonyOS)作为面向万物互联时代的分布式操作系统,其定位服务(Location Kit)为开发者提供了多场景、高精度的位置能力支持。本文将从技术原理、开发流程到实战案例,全面解析鸿蒙定位服务的开发要点,助力开发者快速上手。

关于定位方式;

关于位置定位,位置服务官方提供了两种

利用系统的位置定位能力,可以在多种开发场景中获得实时准确的位置信息。本文将介绍如下四种常见的定位场景,并给出其具体实现方案,帮助开发者更好地掌握位置定位的基本原理和开发流程。

  • 当前位置定位:获取设备的当前位置信息。开发者可以根据实际需求将其应用于多种业务场景,如外卖定位、打车定位等。
  • 实时位置定位:持续获取设备的实时位置信息。开发者可以将此能力应用于需要实时定位的场景,如步行导航,驾车出行等。
  • 应用后台定位:将应用切换到后台仍然可以持续获取位置信息。该能力可以用于实现后台应用实时记录运动轨迹等业务场景。
  • 历史定位获取:获取系统缓存的最新位置,即最近一次的历史定位信息。该能力可以用于在设备网络信号较弱或对系统功耗比较敏感的场景下获取位置信息。

开发前的配置:

1.申请证书服务

在AGC平台申请到真机签名证书,先创建项目

在证书,APP ID和Profile中下载到后缀名.csr的证书

在Profile中拿到后缀名.p7b的证书

在项目的API管理中要开启三个服务

在Deveco Stuido里申请私钥和证书请求

拿到四个证书,配置到项目中

当前位置定位:

  1. 使用getCurrentLocation()获得当前位置信息

           a.需要设置关键参数(定位请求信息:定位方式优先级,单次定位超时时间)

步骤;

  1. 申请权限
  2. 实例化位置信息请求对象,确认当前定位策略
  3. 调用getCurrentLocation()接口获取当前位置信息。
  4. 调用getAddressesFromLocation()接口进行逆地理编码转化,将位置坐标信息转换为对应的地理位置
1.基础信息配置,申请权限
"requestPermissions": [//允许应用获取设备位置信息{"name": "ohos.permission.LOCATION","reason": "$string:location_permission","usedScene": {"abilities": ["EntryAbility"],"when": "inuse"}}]

创建一个常量工具类

export class CommonConstants {/*** 定位超时时间(毫秒)*/static LOCATING_TIMEOUT_MS: number = 10000;/*** 定位优先级*/static PRIORITY_LOCATING_SPEED: number = 0x502;/*** 定位场景*/static NAVIGATION: number = 0x401;/*** 定位开关关闭*/static LOCATION_SWITCH_OFF: number = 3301100;/*** 定位失败*/static LOCATION_FAILED: number = 3301200;/*** 反向地理编码失败*/static REVERSE_GEOCODING_FAILED: number = 3301300;/*** Wi-Fi 和蓝牙关闭*/static WIFI_BLUETOOTH_OFF: number = 3301800;/*** 信息窗口标题*/static MARKER_TITLE: string = getContext(this).resourceManager.getStringSync($r('app.string.geocoded_location'));
}

配置地图数据类型

// 地图数据类型
export interface LocationInter {latitude: number,  // 纬度,表示地理位置的南北方向longitude: number  // 经度,表示地理位置的东西方向
}
2.实例化位置信息
getLocationPosition(): void {// 定义单次定位请求的配置let request: geoLocationManager.SingleLocationRequest = {// 定位优先级locatingPriority: CommonConstants.PRIORITY_LOCATING_SPEED,// 单次定位超时时间locatingTimeoutMs: CommonConstants.LOCATING_TIMEOUT_MS};}
3.调用getCurrentLocation()接口获取当前位置信息。
getLocationPosition(): void {// 定义单次定位请求的配置let request: geoLocationManager.SingleLocationRequest = {// 定位优先级locatingPriority: CommonConstants.PRIORITY_LOCATING_SPEED,// 单次定位超时时间locatingTimeoutMs: CommonConstants.LOCATING_TIMEOUT_MS};// 调用地理位置管理器的getCurrentLocation方法获取当前位置信息geoLocationManager.getCurrentLocation(request).then((location: geoLocationManager.Location) => {// 若获取成功,调用getAddress方法进行地址解析this.getAddress({latitude: location.latitude,longitude: location.longitude})}).catch((err: BusinessError) => {// 若获取失败,记录错误日志并显示定位失败提示hilog.error(0x0000, TAG, `getCurrentLocationPosition failed, code: ${err.code}, message: ${err.message}`);this.locationFailedAlert(err.code);});}
4.调用getAddressesFromLocation()接口进行逆地理编码转化
geoLocationManager.getAddressesFromLocation(reverseGeocodeRequest, async (err, data) => {if (data) {// 若获取地址信息成功,更新地址信息和标记的信息窗口this.address = data[0]?.placeName || '';this.marker?.setInfoWindowVisible(true);this.marker?.setSnippet(this.address);// 记录地址信息日志hilog.info(0x0000, TAG, `The address is: ${this.address}`);if (this.isBackgroundRunning || this.isOnLocationChange) {// 若后台定位任务正在运行或正在监听位置变化,标记不使用缓存位置信息this.isCacheLocation = false;}} else {// 若获取地址信息失败,记录错误日志并根据情况显示定位失败提示hilog.error(0x0000, TAG, `getAddressesFromLocation failed, code: ${err.code}, message: ${err.message}`);if (!this.isOnLocationChange && !this.isBackgroundRunning) {this.locationFailedAlert(err.code);}}});

效果:

实时位置定位:

实时获取位置服务,需要使用到geoLocationManager.on('locationChange');来监听位置变化情况,实现持续获取位置的需求。on('locationChange')有三个参数需要满足

步骤:

  1. 申请定位权限
  2. 实例化位置信息请求对象
  3. 根据定位策略,调用on('locationChange');开启位置变化监听
  4. 在on('locationChange');的回调中调用逆地理编码转化,将坐标信息转换为对应地理位置
1.申请权限(同上)
2.实例化位置信息请求对象
onLocationChange(): void {// 定义持续定位请求的配置let request: geoLocationManager.ContinuousLocationRequest = {interval: 1,locationScenario: CommonConstants.NAVIGATION};}
3.根据定位策略,调用on('locationChange');开启位置变化监听
onLocationChange(): void {// 定义持续定位请求的配置let request: geoLocationManager.ContinuousLocationRequest = {interval: 1,locationScenario: CommonConstants.NAVIGATION};try {// 调用地理位置管理器的on方法开始监听位置变化geoLocationManager.on('locationChange', request, this.locationChange);// 检查是否有网络连接if (!this.judgeHasNet()) {// 若没有网络连接,显示提示信息promptAction.showToast({message: $r('app.string.internet_switch'),duration: 2000});// 隐藏标记的信息窗口this.marker?.setInfoWindowVisible(false);// 清空地址信息this.address = '';}} catch (err) {// 若出现错误,记录错误日志并显示定位失败提示hilog.error(0x0000, TAG, `onLocationChange failed, code: ${err.code}, message: ${err.message}`);this.locationFailedAlert(err.code);}}
4.on('locationChange')第三个参数设置
locationChange = (location: geoLocationManager.Location): void => {// 调用getAddress方法进行地址解析this.getAddress({latitude: location.latitude,longitude: location.longitude});}
5.在不需要获取位置信息时,及时关闭位置变化订阅,并删除对应的定位请求,减少设备功耗。
offLocationChange(): void {try {// 调用地理位置管理器的off方法停止监听位置变化geoLocationManager.off('locationChange', this.locationChange);} catch (err) {// 若出现错误,记录错误日志hilog.error(0x0000, TAG, `offLocationChange failed, code: ${err.code}, message: ${err.message}`);}}

应用后台定位:

应用后台定位是需要申请后台权限和长时任务权限,开启了任务模式为定位导航在on('locationChange')监听位置变化,便可在后台获取当前位置信息

步骤:

  1. 申请权限
  2. 设置长时任务模式为定位导航类型
  3. 在on('locationChange')监听位置变化
  4. 调用逆地理编码转化
1.申请权限
{"name": "ohos.permission.LOCATION_IN_BACKGROUND","reason": "$string:location_background","usedScene": {"abilities": ["EntryAbility"],"when": "always"}},
2.设置长时任务模式为定位导航类型

3.在在on('locationChange')监听位置变化,完成逆地理解析
startContinuousTask(): void {// 获取当前组件的上下文let context = getContext(this) as common.UIAbilityContext;if (!context) {return;}// 定义能力代理信息let wantAgentInfo: wantAgent.WantAgentInfo = {wants: [{bundleName: context.abilityInfo.bundleName,abilityName: context.abilityInfo.name}],operationType: wantAgent.OperationType.START_ABILITY,requestCode: 1,wantAgentFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG]};// 获取能力代理对象wantAgent.getWantAgent(wantAgentInfo).then((wantAgentObj) => {// 调用后台任务管理器的startBackgroundRunning方法启动后台定位任务backgroundTaskManager.startBackgroundRunning(context,backgroundTaskManager.BackgroundMode.LOCATION, wantAgentObj).then(() => {// 启动位置变化监听this.onLocationChange();// 记录后台定位任务启动成功日志hilog.info(0x0000, TAG, 'startBackgroundRunning succeeded');}).catch((err: BusinessError) => {// 若启动失败,记录错误日志hilog.error(0x0000, TAG, `startBackgroundRunning failed, cause:  ${JSON.stringify(err)}`);});});}
4.在不需要获取位置信息时,及时关闭位置变化订阅,并删除对应的定位请求,减少设备功耗。
stopContinuousTask(): void {// 获取当前组件的上下文let context = getContext(this) as common.UIAbilityContext;if (!context) {return;}// 调用后台任务管理器的stopBackgroundRunning方法停止后台定位任务backgroundTaskManager.stopBackgroundRunning(context).then(() => {if (!this.isOnLocationChange) {// 若未在监听位置变化,停止位置变化监听this.offLocationChange();}// 记录后台定位任务停止成功日志hilog.info(0x0000, TAG, 'stopBackgroundRunning succeeded');}).catch((err: BusinessError) => {// 若停止失败,记录错误日志hilog.error(0x0000, TAG, `stopBackgroundRunning failed, cause:  ${JSON.stringify(err)}`);});}

效果:

历史定位获取:

通过getLastLocation()接口来获取系统缓存的最新位置信息。

步骤:

  1. 申请权限
  2. 通过getLastLocation()接口来获取系统缓存的最新位置信息。
  3. 调用getAddressesFromLocation()接口进行逆地理编码转化
1.申请权限(完整权限)
"requestPermissions": [//允许应用获取设备位置信息{"name": "ohos.permission.LOCATION","reason": "$string:location_permission","usedScene": {"abilities": ["EntryAbility"],"when": "inuse"}},//允许应用获取设备模糊位置信息{"name": "ohos.permission.APPROXIMATELY_LOCATION","reason": "$string:fuzzy_location_permission","usedScene": {"abilities": ["EntryAbility"],"when": "inuse"}},//允许应用在后台获取设备位置信息。{"name": "ohos.permission.LOCATION_IN_BACKGROUND","reason": "$string:location_background","usedScene": {"abilities": ["EntryAbility"],"when": "always"}},//允许应用开启长时任务{"name": "ohos.permission.KEEP_BACKGROUND_RUNNING","reason": "$string:running_background","usedScene": {"abilities": ["EntryAbility"],"when": "always"}},//允许应用获取设备网络连接信息{"name": "ohos.permission.GET_NETWORK_INFO","reason": "$string:get_network_info","usedScene": {"abilities": ["EntryAbility"],"when": "always"}}]

2.通过getLastLocation()接口来获取系统缓存的最新位置信息

judgeHasNet(): boolean {try {// 获取默认网络句柄let netHandle = connection.getDefaultNetSync();if (!netHandle || netHandle.netId === 0) {return false;}// 获取网络能力信息let netCapability = connection.getNetCapabilitiesSync(netHandle);let cap = netCapability.networkCap || [];if (cap.includes(connection.NetCap.NET_CAPABILITY_VALIDATED)) {// 若网络能力包含有效验证,说明有网络连接return true;} else {return false;}} catch (err) {// 若出现错误,记录错误日志hilog.error(0x0000, TAG, `JudgeHasNet failed, code: ${err.code}, message: ${err.message}`);}return false;}

3.调用getAddressesFromLocation()接口进行逆地理编码(同上)

效果:

适用HarmonyOS NEXT / API12或以上版本 -----------------

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/76510.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

rknn_convert的使用方法

rknn_convert是RKNN-Toolkit2提供的一套常用模型转换工具,通过封装上述API接口,用户只需编辑模型对应的yml配置文件,就可以通过指令转换模型。以下是如何使用rknn_convert工具的示例命令以及支持的指令参数: python -m rknn.api.…

解决 axios get请求瞎转义问题

在Vue.js项目中,axios 是一个常用的HTTP客户端库,用于发送HTTP请求。qs 是一个用于处理查询字符串的库,通常与 axios 结合使用,特别是在处理POST请求时,将对象序列化为URL编码的字符串。 1. 安装 axios 和 qs 首先&a…

【XTerminal】【树莓派】Linux系统下的函数调用编程

目录 一、XTerminal下的Linux系统调用编程 1.1理解进程和线程的概念并在Linux系统下完成相应操作 (1) 进程 (2)线程 (3) 进程 vs 线程 (4)Linux 下的实践操作 1.2Linux的“虚拟内存管理”和stm32正式物理内存(内存映射)的区别 (1)Linux虚拟内存管…

torch 拆分子张量 分割张量

目录 unbind拆分子张量 1. 沿着第n个维度拆分(即按“批次”拆分) split分割张量 常用用法: 总结: unbind拆分子张量 import torchquaternions torch.tensor([[1, 2, 3, 4], [5, 6, 7, 8]]) result torch.unbind(quaternio…

【Linux】内核驱动学习笔记(二)

7、framebuffer驱动详解 7.1、什么是framebuffer (1)裸机中如何操作LCD (2)OS下操作LCD的难点 (3)framebuffer帧缓冲(简称fb)是linux内核中虚拟出的一个设备 (4)framebuffer向应用层提供一个统一标准接口的显示设备 (5)从驱动来看,fb是一个…

用 Docker Compose 与 Nginx 反向代理部署 Vikunja 待办事项管理系统

在高效管理日常任务和项目的过程中,开源待办事项工具 Vikunja 以其简洁、直观的设计和多视图支持受到越来越多用户的青睐。本文将详细介绍如何使用 Docker Compose 快速部署 Vikunja,并通过 Nginx 反向代理实现 HTTPS 访问,从而确保服务安全稳…

使用Python快速接入DeepSeek API的步骤指南

使用Python快速接入DeepSeek API的步骤指南 1. 前期准备 注册DeepSeek账号 访问DeepSeek官网注册账号 完成邮箱验证等认证流程 获取API密钥 登录后进入控制台 → API管理 创建新的API Key并妥善保存 安装必要库 pip install requests # 可选:处理复杂场景 pip…

Redis 主要能够用来做什么

Redis(Remote Dictionary Server)是一种基于内存的键值存储数据库,它的性能极高,广泛应用于各种高并发场景。以下是 Redis 常见的用途: 1. 缓存(Cache) 作用:存储热点数据&#xf…

印度股票实时数据API接口选型指南:iTick.org如何成为开发者优选

在全球金融数字化浪潮中,印度股票市场因其高速增长潜力备受关注。对于量化交易开发者、金融科技公司而言,稳定可靠的股票报价API接口是获取市场数据的核心基础设施。本文将深度对比主流印度股票API,并揭示iTick在数据服务领域的独特优势。 一…

24.多路转接-poll

poll也是一种linux中的多路转接的方案 解决select的fd有上限的问题解决select每次调用都要重新设置关心的fd poll函数接口 poll, ppoll - wait for some event on a file descriptor#include <poll.h>int poll(struct pollfd *fds, nfds_t nfds, int timeout);DESCRIP…

Linux 基础入门操作 前言 linux操作指令介绍

1 linux 目录介绍 Linux 文件系统采用层次化的目录结构&#xff0c;所有目录都从根目录 / 开始 1.1 核心目录 / (根目录) 整个文件系统的起点、包含所有其他目录和文件 /bin (基本命令二进制文件) 存放系统最基本的shell命令&#xff1a;如 ls, cp, mv, rm, cat 等&#…

Chrome开发者工具实战:调试三剑客

在前端开发的世界里&#xff0c;Chrome开发者工具就是我们的瑞士军刀&#xff0c;它集成了各种强大的功能&#xff0c;帮助我们快速定位和解决代码中的问题。今天&#xff0c;就让我们一起来看看如何使用Chrome开发者工具中的“调试三剑客”&#xff1a;断点调试、调用栈跟踪和…

函数柯里化(Currying)介绍(一种将接受多个参数的函数转换为一系列接受单一参数的函数的技术)

文章目录 柯里化的特点示例普通函数柯里化实现使用Lodash进行柯里化 应用场景总结 函数柯里化&#xff08;Currying&#xff09;是一种将接受多个参数的函数转换为一系列接受单一参数的函数的技术。换句话说&#xff0c;柯里化将一个多参数函数转化为一系列嵌套的单参数函数。 …

torch.nn中的非线性激活介绍合集——Pytorch中的非线性激活

1、nn.ELU 基本语法&#xff1a; class torch.nn.ELU(alpha1.0, inplaceFalse)按元素应用 Exponential Linear Unit &#xff08;ELU&#xff09; 函数。 论文中描述的方法&#xff1a;通过指数线性单元 &#xff08;ELU&#xff09; 进行快速准确的深度网络学习。 ELU 定义为…

Databend Cloud Dashboard 全新升级:直击痛点,释放数据价值

自 Databend Cloud 上线以来&#xff0c;我们一直致力于为用户提供高效的数据处理与可视化体验。早期&#xff0c;我们在工作区的“图表”区域推出了轻量级可视化功能&#xff0c;支持积分卡、饼图、柱状图和折线图四种展示方式。这些功能简单易用&#xff0c;基本满足了用户对…

Android Fresco 框架扩展模块源码深度剖析(四)

Android Fresco 框架扩展模块源码深度剖析 一、引言 在 Android 开发领域&#xff0c;图片处理一直是一个重要且具有挑战性的任务。Fresco 作为 Facebook 开源的强大图片加载框架&#xff0c;在图片的加载、缓存和显示等方面已经提供了非常完善的功能。然而&#xff0c;为了满…

蓝桥杯最后十天冲刺 day 2 双指针的思想

双指针思想介绍 双指针&#xff08;Two Pointers&#xff09;是一种在数组或链表等线性结构中常用的算法技巧&#xff0c;通过使用两个指针&#xff08;索引或引用&#xff09;以不同的速度或方向遍历数据结构&#xff0c;从而高效解决问题。双指针通常用于优化暴力解法&#…

Axure 使用笔记

1.Axure如何制作页面弹窗 https://blog.csdn.net/SDTechnology/article/details/143948691 2.axure 怎么点击按钮打开新页面 &#xff08;1&#xff09;新建交互 &#xff08;2&#xff09;单击是触发 &#xff08;3&#xff09;选择打开链接 &#xff08;4&#xff09;选择…

STM32实现一个简单电灯

新建工程的步骤 建立工程文件夹&#xff0c;Keil中新建工程&#xff0c;选择型号工程文件夹里建立Start、Library、User等文件夹&#xff0c;复制固件库里面的文件到工程文件夹工程里对应建立Start、Library、User等同名称的分组&#xff0c;然后将文件夹内的文件添加到工程分组…

html5炫酷图片悬停效果实现详解

html5炫酷图片悬停效果实现详解 这里写目录标题 html5炫酷图片悬停效果实现详解项目介绍技术栈核心功能实现1. 页面布局2. 图片容器样式3. 炫酷悬停效果缩放效果倾斜效果模糊效果旋转效果 4. 悬停文字效果5. 性能优化6. 响应式设计 项目亮点总结 项目介绍 本文将详细介绍如何使…