阅读量:0
简介
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; // 获取应用程序的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.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; } }