【鸿蒙 HarmonyOS】获取设备的地理位置

一、背景

获取移动设备的地理位置,包含:经度、维度、具体地理位置等,地理位置信息能在许多业务场景中被应用,如导航、地图服务、位置服务、社交媒体等。

下面以一个Demo例子,来实现获取设备地理位置的功能

官方文档指引👉:文档中心

二、实现方法

2.1、申请位置权限

在model.json5文件中的module模块下添加如下请求权限:

javascript 复制代码
{
    "module" : {
        "requestPermissions":[
           {
            "name": "ohos.permission.LOCATION",
           },
           {
            "name": "ohos.permission.APPROXIMATELY_LOCATION"
           }
        ]
    }
}

2.2、具体实现

2.2.1、授权询问

先检测权限是否已经授权,如果未授权就弹出授权弹窗

javascript 复制代码
// 检测权限是否已经授权,如果未授权就弹出授权弹窗
  reqPermissionsFromUser(permissions: Array<Permissions>){
    let context = getContext(this) as common.UIAbilityContext;
    let atManager = abilityAccessCtrl.createAtManager();
    // requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
    return 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) {
          // 用户授权,可以继续操作
          return true
        } else {
          // 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限
          return false
        }
      }
      // 授权成功
    }).catch((err) => {
      console.error(`requestPermissionsFromUser failed, code is ${err.code}, message is ${err.message}`);
    })
  }

2.2.2、获取当前位置

点击定位按钮,获取当前位置,包含:经度、维度、国家、省份及详细地址

javascript 复制代码
@Entry
@Component
struct Index {
  @State mLatitude: string = '' // 经度
  @State mLongitude: string = '' // 纬度
  @State mAddresses: string = '' // 地址
  @State mCountryName: string = '' // 国家名称
  @State mAdministrativeArea: string = '' // 省份
  @State mLocality: string = '' // 地市
  @State mSubLocality: string = '' // 县区

  build() {
    Column({space:10}) {
      Button('定位')
        .width('100%')
        .margin({ top: 10, bottom: 10 })
        .onClick(()=>{
          this.getLocation()
        })
      Text('【当前位置信息】').fontSize(20)
      Text(`经度:${this.mLatitude}`).width(260)
      Text(`纬度:${this.mLongitude}`).width(260)
      Text(`地址:${this.mAddresses}`).width(260)
      Text(`县区:${this.mSubLocality}`).width(260)
      Text(`地市:${this.mLocality}`).width(260)
      Text(`省份:${this.mAdministrativeArea}`).width(260)
      Text(`国家:${this.mCountryName}`).width(260)
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#EAEAEA')
    .padding(10)

  }
  //获取当前位置
  async getLocation(){
    let status = await this.reqPermissionsFromUser(['ohos.permission.LOCATION','ohos.permission.APPROXIMATELY_LOCATION'])
    if(status){
      let location = geoLocationManager.getLastLocation()
      console.log('lucy',JSON.stringify(location))

      location['locale'] = 'zh'
      //逆地理编码服务
      geoLocationManager.getAddressesFromLocation(location,(err,data: any)=>{
        if(!err){
          console.log('lucy--',JSON.stringify(data))
          this.mLatitude = data[0].latitude
          this.mLongitude = data[0].longitude;
          this.mAddresses = data[0].placeName
          this.mCountryName = data[0].countryName
          this.mAdministrativeArea = data[0].administrativeArea
          this.mLocality = data[0].locality
          this.mSubLocality = data[0].subLocality
        }
      })
    }
  }
}

备注:

真机调试时,使用逆地理编码getAddressesFromLocation获取结果都是英文,在使用getAddressesFromLocation()方法之前,添加location'locale' = 'zh'参数即可

2.2.3、进入页面与离开页面操作

进入页面授权访问,绑定监听事件;离开页面,取消监听事件

javascript 复制代码
  //进入页面授权访问,绑定监听事件
  async aboutToAppear(){
    let result = await this.reqPermissionsFromUser(['ohos.permission.LOCATION','ohos.permission.APPROXIMATELY_LOCATION'])
    if(result){
      geoLocationManager.on('locationChange',{
        priority:geoLocationManager.LocationRequestPriority.ACCURACY,
        timeInterval:0
      },value=>{
        console.log('lucy',JSON.stringify(value))})
    }
  }

  //离开页面,取消监听事件
  aboutToDisappear(){
    geoLocationManager.off('locationChange')
  }

2.2.4、完整代码

javascript 复制代码
import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
import common from '@ohos.app.ability.common';
import geoLocationManager from '@ohos.geoLocationManager';
@Entry
@Component
struct Index {
  @State mLatitude: string = '' // 经度
  @State mLongitude: string = '' // 纬度
  @State mAddresses: string = '' // 地址
  @State mCountryName: string = '' // 国家名称
  @State mAdministrativeArea: string = '' // 省份
  @State mLocality: string = '' // 地市
  @State mSubLocality: string = '' // 县区

  //进入页面授权访问,绑定监听事件
  async aboutToAppear(){
    let result = await this.reqPermissionsFromUser(['ohos.permission.LOCATION','ohos.permission.APPROXIMATELY_LOCATION'])
    if(result){
      geoLocationManager.on('locationChange',{
        priority:geoLocationManager.LocationRequestPriority.ACCURACY,
        timeInterval:0
      },value=>{
        console.log('lucy',JSON.stringify(value))})
    }
  }

  //离开页面,取消监听事件
  aboutToDisappear(){
    geoLocationManager.off('locationChange')
  }

  // 检测权限是否已经授权,如果未授权就弹出授权弹窗
  reqPermissionsFromUser(permissions: Array<Permissions>){
    let context = getContext(this) as common.UIAbilityContext;
    let atManager = abilityAccessCtrl.createAtManager();
    // requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
    return 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) {
          // 用户授权,可以继续操作
          return true
        } else {
          // 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限
          return false
        }
      }
      // 授权成功
    }).catch((err) => {
      console.error(`requestPermissionsFromUser failed, code is ${err.code}, message is ${err.message}`);
    })
  }

  build() {
    Column({space:10}) {
      Button('定位')
        .width('100%')
        .margin({ top: 10, bottom: 10 })
        .onClick(()=>{
          this.getLocation()
        })
      Text('【当前位置信息】').fontSize(20)
      Text(`经度:${this.mLatitude}`).width(260)
      Text(`纬度:${this.mLongitude}`).width(260)
      Text(`地址:${this.mAddresses}`).width(260)
      Text(`县区:${this.mSubLocality}`).width(260)
      Text(`地市:${this.mLocality}`).width(260)
      Text(`省份:${this.mAdministrativeArea}`).width(260)
      Text(`国家:${this.mCountryName}`).width(260)
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#EAEAEA')
    .padding(10)

  }
  //获取当前位置
  async getLocation(){
    let status = await this.reqPermissionsFromUser(['ohos.permission.LOCATION','ohos.permission.APPROXIMATELY_LOCATION'])
    if(status){
      let location = geoLocationManager.getLastLocation()
      console.log('lucy',JSON.stringify(location))

      location['locale'] = 'zh'
      //逆地理编码服务
      geoLocationManager.getAddressesFromLocation(location,(err,data: any)=>{
        if(!err){
          console.log('lucy--',JSON.stringify(data))
          this.mLatitude = data[0].latitude
          this.mLongitude = data[0].longitude;
          this.mAddresses = data[0].placeName
          this.mCountryName = data[0].countryName
          this.mAdministrativeArea = data[0].administrativeArea
          this.mLocality = data[0].locality
          this.mSubLocality = data[0].subLocality
        }
      })
    }
  }
}

2.3、实现效果

进入页面先授权访问位置信息,然后点击定位按钮,获取当前位置信息

**备注:**实现效果需进行真机调试,预览器和本地模拟器实现不了此效果

最后:👏👏😊😊😊👍👍

相关推荐
梦想不只是梦与想13 分钟前
鸿蒙 应用类型:企业应用
华为·harmonyos·企业应用
大雷神41 分钟前
HarmonyOS ArkGraphics 2D 文本绘制实操:用 TextBlob 做动态文字排版
华为·harmonyos
搬砖的kk1 小时前
从 0 到 1:用 KMP + Compose Multiplatform + Ktor 实现鸿蒙「历史上的今天」应用
开源·harmonyos
星辰徐哥1 小时前
鸿蒙PC平台 Gnote 笔记应用适配实战:从 Linux 到 鸿蒙PC 的 Electron 迁移
linux·笔记·electron·harmonyos·gnote
Swift社区1 小时前
鸿蒙 App 如何设计 Memory Center?一文讲透 Agent 的长期记忆架构
华为·架构·harmonyos
binbin_521 小时前
HarmonyOS 应用功耗优化实战:定位耗电、收口任务与验证回归
android·回归·harmonyos
lqj_本人2 小时前
Flutter 三方库 Pedometer 的鸿蒙化适配指南
flutter·华为·harmonyos
贾伟康21 小时前
【时光清单|19】HarmonyOS ArkTS 回归测试实战:覆盖启动、空数据、异常输入和重复点击
软件测试·harmonyos·arkts·回归测试·hypium
坚果的博客1 天前
Flutter OHOS 环境搭建实战:oh-3.44.9-dev 从 0 到 1 完整记录
flutter·华为·harmonyos
坚果的博客1 天前
认识 CPF-RN:React Native 鸿蒙官方社区与四大核心仓库
react native·react.js·harmonyos