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

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

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

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

相关推荐
编程百晓君3 小时前
一文彻底拿捏DevEco Studio的使用小技巧
华为·harmonyos
轻口味4 小时前
【每日学点鸿蒙知识】私仓搭建、resources创建文件夹、hvigor如何动态设置版本、SM3摘要算法、SP存储报错等
华为·json·harmonyos
JasonYin~6 小时前
HarmonyOS NEXT 实战之元服务:静态案例效果---查看国际航班服务
华为·harmonyos
深海的鲸同学 luvi6 小时前
【HarmonyOS NEXT】hdc环境变量配置
linux·windows·harmonyos
Freerain9911 小时前
鸿蒙Next ArkTS语法适配背景概述
华为·harmonyos
他的猫哎11 小时前
鸿蒙 Navigation组件下的组件获取pageStack问题
harmonyos·鸿蒙
雨汨11 小时前
鸿蒙之路的坑
华为·harmonyos
轻口味13 小时前
【每日学点鸿蒙知识】沙箱目录、图片压缩、characteristicsArray、gm-crypto 国密加解密、通知权限
pytorch·华为·harmonyos
xo1988201116 小时前
鸿蒙人脸识别
redis·华为·harmonyos
塞尔维亚大汉17 小时前
【OpenHarmony】 鸿蒙 UI开发之CircleIndicator
harmonyos·arkui