【鸿蒙 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、实现效果

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

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

**最后:**👏👏😊😊😊👍👍

相关推荐
Georgewu1 小时前
【HarmonyOS 5】鸿蒙中自定义弹框OpenCustomDialog、CustomDialog与DialogHub的区别详解
harmonyos
塞尔维亚大汉1 小时前
鸿蒙内核源码分析(消息封装篇) | 剖析LiteIpc 进程通讯内容
harmonyos·源码阅读
Georgewu1 小时前
【HarmonyOS NEXT】鸿蒙跳转华为应用市场目标APP下载页
harmonyos
ajassi20003 小时前
开源 Arkts 鸿蒙应用 开发(六)数据持久--文件和首选项存储
linux·开源·harmonyos
塞尔维亚大汉4 小时前
鸿蒙内核源码分析(共享内存) | 进程间最快通讯方式
harmonyos·源码阅读
生如夏花℡7 小时前
HarmonyOS学习记录4
学习·华为·harmonyos
xq95278 小时前
编程之路2025年中总结,勇往直前 再战江湖
harmonyos
枫叶丹49 小时前
【HarmonyOS Next之旅】DevEco Studio使用指南(四十二) -> 动态修改编译配置
华为·harmonyos·deveco studio·harmonyos next
前端世界20 小时前
鸿蒙UI开发全解:JS与Java双引擎实战指南
javascript·ui·harmonyos
阿巴~阿巴~1 天前
操作系统核心技术剖析:从Android驱动模型到鸿蒙微内核的国产化实践
android·华为·harmonyos