当前位置: 首页 > news >正文

【HarmonyOS学习】定位相关知识(Locationkit)

简介

LocationKit提供了定位服务、地理围栏、地理编码、逆地理编码和国家码等功能。

可以实现点击获取用户位置信息、持续获取位置信息和区域进出监控等多项功能。

需要注意,需要确定用户已经开启定位信息,一下的代码没有做这一步的操作,默认开启了。

权限

申请位置权限的方式位置的精确度
只申请ohos.permission.APPROXIMATELY_LOCATION获取到模糊位置,精确度为5公里。
同时申请ohos.permission.APPROXIMATELY_LOCATION 和ohos.permission.LOCATION获取到精准位置,精准度在米级别。

如果应用需要在后台运行时访问设备位置,还需要申请ohos.permission.LOCATION_IN_BACKGROUND权限。

这里强烈推荐大家去使用 旺旺崔冰冰 大佬的工具库(ef-tool)以下的权限获取代码来自大佬的工具库权限相关的代码。

import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
import { bundleManager, common } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';export class AuthUtil {/*** 判断是否授权* @param permissions  待判断的权限* @returns 已授权true,未授权false*/static async checkPermissions(permissions: Permissions): Promise<boolean> {//判断是否授权let grantStatus: abilityAccessCtrl.GrantStatus = await AuthUtil.checkAccessToken(permissions);if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {//已经授权return true;} else {//未授权return false;}}/*** 发起授权* @param permissions  需要授权的权限* @param callBack  授权成功后的回调,1为用户同意授权,-1为用户拒绝授权* @returns*/static async reqPermissionsFromUser(permissions: Permissions, callBack: (index: number) => void): Promise<void> {let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();// requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗let request = await atManager.requestPermissionsFromUser(getContext() as common.UIAbilityContext, [permissions]);let grantStatus: Array<number> = request.authResults;let length: number = grantStatus.length;for (let i = 0; i < length; i++) {if (grantStatus[i] === 0) {// 用户授权,可以继续访问目标操作callBack(1);} else {callBack(-1);// 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限return;}}}/*** 发起授权 以Promise方式返回* @param permissions 需要授权的权限* @returns 1表示授权成功继续业务操作,-1表示用户拒绝授权*/static async reqPermissions(permissions: Permissions): Promise<number> {let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();// requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗let request = await atManager.requestPermissionsFromUser(getContext() as common.UIAbilityContext, [permissions]);let grantStatus: Array<number> = request.authResults;let length: number = grantStatus.length;for (let i = 0; i < length; i++) {if (grantStatus[i] === 0) {// 用户授权,可以继续访问目标操作return 1;} else {// 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限return -1;}}return -1;}/*** 检查是否授权* @param permission 待检查权限* @returns 授权状态*/private static async checkAccessToken(permission: Permissions): Promise<abilityAccessCtrl.GrantStatus> {let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();let grantStatus: abilityAccessCtrl.GrantStatus = abilityAccessCtrl.GrantStatus.PERMISSION_DENIED;// 获取应用程序的accessTokenIDlet 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.log('获取应用绑定包信息失败:原因为:' + err.message)}// 校验应用是否被授予权限try {grantStatus = await atManager.checkAccessToken(tokenId, permission);} catch (error) {const err: BusinessError = error as BusinessError;console.log('校验授权信息失败:原因为:' + err.message)}return grantStatus;}
}

定位信息Location参数

在这里插入图片描述

单次获取设备定位信息

有两种方式,分别是获取系统缓存的最新位置和获取当前位置。

获取缓存的位置,可以减少系统功耗。如果对时间精度要求较高,直接获取当前位置较好。

以下是完整的代码

import { geoLocationManager } from '@kit.LocationKit';
import { BusinessError } from '@kit.BasicServicesKit'
import json from '@ohos.util.json';
import { AuthUtil } from '../Util/AuthUtil';
import { Permissions } from '@kit.AbilityKit';@Entry
@Component
struct Index {locationPermissions: Permissions = 'ohos.permission.LOCATION'locationMatelyPermissions: Permissions = 'ohos.permission.APPROXIMATELY_LOCATION'async aboutToAppear(): Promise<void> {let permissionResult = await this.CheckPermission();if (!permissionResult) {//这里需要指引用户二次开启return;}}/*** 查看缓存中的位置*/GetLastLocation() {//查看系统缓存的最新位置let location = geoLocationManager.getLastLocation();console.log(json.stringify(location))}/*** 查看当前最新位置**locatingPriority 有两个相关标签*  1.geoLocationManager.LocatingPriority.PRIORITY_LOCATING_SPEED ->如果对定位速度要求较高建议使用这个*  2.geoLocationManager.LocatingPriority.PRIORITY_ACCURACY ->如果对位置的返回精度要求较高使用这个* locatingTimeoutMs 单次定位时间,建议10S*/GetSingleLocation() {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));}).catch((error: BusinessError) => { // 接收上报的错误码console.error('promise, getCurrentLocation: error=' + JSON.stringify(error));});} catch (err) {console.error("errCode:" + JSON.stringify(err));}}build() {Column() {Button("查看系统中缓存的最新位置").width(220).height(50).margin({ bottom: 40 }).onClick(() => this.GetLastLocation())Button("查看最新位置").width(220).height(50).margin({ bottom: 40 }).onClick(() => {this.GetSingleLocation()})}.height('100%').width('100%').justifyContent(FlexAlign.Center)}/*** 检查定位权限是否添加* @returns true为已经添加,false为未添加*/private async CheckPermission(): Promise<boolean> {let result: boolean = true;let locationPermissionCheck = await AuthUtil.checkPermissions(this.locationPermissions)if (!locationPermissionCheck) {AuthUtil.reqPermissionsFromUser(this.locationPermissions, (index: number) => {if (index === -1) {result = false;}})}if (!result) {return result;}let locationMatelyPermissionCheck = await AuthUtil.checkPermissions(this.locationMatelyPermissions)if (!locationMatelyPermissionCheck) {AuthUtil.reqPermissionsFromUser(this.locationMatelyPermissions, (index: number) => {if (index === -1) {result = false;}})}return result;}
}

持续获取设备定位信息

import { geoLocationManager } from '@kit.LocationKit';
import { BusinessError } from '@kit.BasicServicesKit'
import json from '@ohos.util.json';
import { AuthUtil } from '../Util/AuthUtil';
import { Permissions } from '@kit.AbilityKit';@Entry
@Component
struct Index {locationPermissions: Permissions = 'ohos.permission.LOCATION'locationMatelyPermissions: Permissions = 'ohos.permission.APPROXIMATELY_LOCATION'async aboutToAppear(): Promise<void> {let permissionResult = await this.CheckPermission();if (!permissionResult) {//这里需要指引用户二次开启return;}}/*** 持续定位(ContinuousLocationRequest对象)** interval-> 上报位置信息的时间间隔,单位是秒** locationScenario ->用户活动场景枚举* 1. NAVIGATION:导航场景。需要高定位精度和实时性能。* 2. SPORT:运动场景。要求高定位精度。* 3. TRANSPORT:运输场景。需要高定位精度和实时性能。* 4. TRANSPORT:运输场景。需要高定位精度和实时性能。* 5. DAILY_LIFE_SERVICE:日常生活场景。定位精度要求低。*/OpenContinuosLocation() {let request: geoLocationManager.ContinuousLocationRequest = {'interval': 1,'locationScenario': geoLocationManager.UserActivityScenario.NAVIGATION}let locationCallback = (location: geoLocationManager.Location): void => {console.log('定位信息: ' + JSON.stringify(location));};try {geoLocationManager.on('locationChange', request, locationCallback);} catch (err) {console.error("errCode:" + JSON.stringify(err));}}/*** 关闭持续定位*/ClosedContinuosLocation() {geoLocationManager.off('locationChange', (loca: geoLocationManager.Location) => {console.log("持续定位关闭");console.log("最后一次定位" + json.stringify(loca));})}build() {Column() {Button("开启持续定位").width(220).height(50).margin({ bottom: 40 }).onClick(() => {this.OpenContinuosLocation()})Button("关闭持续定位").width(220).height(50).margin({ bottom: 40 }).onClick(() => {this.ClosedContinuosLocation()})}.height('100%').width('100%').justifyContent(FlexAlign.Center)}/*** 检查定位权限是否添加* @returns true为已经添加,false为未添加*/private async CheckPermission(): Promise<boolean> {let result: boolean = true;let locationPermissionCheck = await AuthUtil.checkPermissions(this.locationPermissions)if (!locationPermissionCheck) {AuthUtil.reqPermissionsFromUser(this.locationPermissions, (index: number) => {if (index === -1) {result = false;}})}if (!result) {return result;}let locationMatelyPermissionCheck = await AuthUtil.checkPermissions(this.locationMatelyPermissions)if (!locationMatelyPermissionCheck) {AuthUtil.reqPermissionsFromUser(this.locationMatelyPermissions, (index: number) => {if (index === -1) {result = false;}})}return result;}
}

地理编码地址获取

两种方式:通过经纬度坐标获取和通过详细地址描述获取。

import { geoLocationManager } from '@kit.LocationKit';
import { Permissions } from '@kit.AbilityKit';
import { AuthUtil } from '../Util/AuthUtil';@Entry
@Component
struct Loaction_Page2 {locationPermissions: Permissions = 'ohos.permission.LOCATION'locationMatelyPermissions: Permissions = 'ohos.permission.APPROXIMATELY_LOCATION'async aboutToAppear(): Promise<void> {let permissionResult = await this.CheckPermission();if (!permissionResult) {//这里需要指引用户二次开启return;}this.CheckGeoService()}LocationToAddress() {this.CheckGeoService()let reverseGeocodeRequest: geoLocationManager.ReverseGeoCodeRequest ={"locale": "zh","country": "CN","latitude": 40.02099028,"longitude": 115.96965089,"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));}});} catch (err) {console.error("errCode:" + JSON.stringify(err));}}LocationNameToAddress() {let geocodeRequest: geoLocationManager.GeoCodeRequest = {"description": "广东省广州市海珠区阅江西路222号(广州塔站B出口170米左右)","maxItems": 1};try {geoLocationManager.getAddressesFromLocationName(geocodeRequest, (err, data) => {if (err) {console.log('getAddressesFromLocationName err: ' + JSON.stringify(err));} else {console.log('getAddressesFromLocationName data: ' + JSON.stringify(data));}});} catch (err) {console.error("errCode:" + JSON.stringify(err));}}build() {Column() {Button("具体地址得到地理编码").width(220).height(50).margin({ bottom: 40 }).onClick(() => {this.LocationNameToAddress();})Button("具体坐标得到地理编码").width(220).height(50).margin({ bottom: 40 }).onClick(() => {this.LocationToAddress();})}.height('100%').width('100%').justifyContent(FlexAlign.Center)}/*** 查询地理编码和逆地理编码是否可用*/private CheckGeoService(): boolean {try {let isAvailable = geoLocationManager.isGeocoderAvailable();if (isAvailable) {console.log("地理编码和逆地理编码可用")return true;} else {console.log("地理编码和逆地理编码不可用")return false;}} catch (err) {console.error("errCode:" + JSON.stringify(err));return false;}}/*** 检查定位权限是否添加* @returns true为已经添加,false为未添加*/private async CheckPermission(): Promise<boolean> {let result: boolean = true;let locationPermissionCheck = await AuthUtil.checkPermissions(this.locationPermissions)if (!locationPermissionCheck) {AuthUtil.reqPermissionsFromUser(this.locationPermissions, (index: number) => {if (index === -1) {result = false;}})}if (!result) {return result;}let locationMatelyPermissionCheck = await AuthUtil.checkPermissions(this.locationMatelyPermissions)if (!locationMatelyPermissionCheck) {AuthUtil.reqPermissionsFromUser(this.locationMatelyPermissions, (index: number) => {if (index === -1) {result = false;}})}return result;}
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 不坑盒子有什么用?
  • 互动广告新体验:Flat Ads 助力全球开发者高效变现
  • Go网络编程-HTTP程序设计_2
  • 新时代多目标优化【数学建模】领域的极致探索——数学规划模型
  • ​数据结构之初始二叉树(3)
  • C语言 ——— 打印水仙花数
  • ubuntu22.04安装SecureCRT8.7.3,完成顺利使用
  • 【面试题】数据结构:堆排序的排序思想?
  • 辅助类BigDecima/BigInteger
  • 【Windows】操作系统之任务管理器(第一篇)
  • 车载音视频App框架设计
  • 前端pc和小程序接入快递100(跳转方式和api方式)====实时查询接口
  • Self-supervised Learning for Pre-Training 3D Point Clouds: A Survey
  • 如何免费用java c#实现手机在网状态查询
  • 【Apache POI】Java解析Excel文件并处理合并单元格-粘贴即用
  • Android Volley源码解析
  • C++类的相互关联
  • ES6--对象的扩展
  • Essential Studio for ASP.NET Web Forms 2017 v2,新增自定义树形网格工具栏
  • github从入门到放弃(1)
  • JS笔记四:作用域、变量(函数)提升
  • Koa2 之文件上传下载
  • LintCode 31. partitionArray 数组划分
  • session共享问题解决方案
  • Twitter赢在开放,三年创造奇迹
  • vue的全局变量和全局拦截请求器
  • win10下安装mysql5.7
  • Yii源码解读-服务定位器(Service Locator)
  • 分享一个自己写的基于canvas的原生js图片爆炸插件
  • 如何使用 JavaScript 解析 URL
  • Nginx实现动静分离
  • 新海诚画集[秒速5センチメートル:樱花抄·春]
  • # 20155222 2016-2017-2 《Java程序设计》第5周学习总结
  • # 学号 2017-2018-20172309 《程序设计与数据结构》实验三报告
  • #android不同版本废弃api,新api。
  • (02)Unity使用在线AI大模型(调用Python)
  • (C++)八皇后问题
  • (Java企业 / 公司项目)点赞业务系统设计-批量查询点赞状态(二)
  • (LeetCode) T14. Longest Common Prefix
  • (PADS学习)第二章:原理图绘制 第一部分
  • (zhuan) 一些RL的文献(及笔记)
  • (补充):java各种进制、原码、反码、补码和文本、图像、音频在计算机中的存储方式
  • (创新)基于VMD-CNN-BiLSTM的电力负荷预测—代码+数据
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • (一)Spring Cloud 直击微服务作用、架构应用、hystrix降级
  • (原创)可支持最大高度的NestedScrollView
  • (原創) X61用戶,小心你的上蓋!! (NB) (ThinkPad) (X61)
  • (转)ORM
  • .net framwork4.6操作MySQL报错Character set ‘utf8mb3‘ is not supported 解决方法
  • .net 调用海康SDK以及常见的坑解释
  • .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)...
  • .Net接口调试与案例
  • /etc/X11/xorg.conf 文件被误改后进不了图形化界面
  • @SpringBootConfiguration重复加载报错
  • [ Linux 长征路第五篇 ] make/Makefile Linux项目自动化创建工具