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

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

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

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

相关推荐
周胡杰22 分钟前
鸿蒙加载预置数据库-关系型数据库-如何读取本地/预制数据库
数据库·华为·harmonyos·鸿蒙
迷曳10 小时前
27、鸿蒙Harmony Next开发:ArkTS并发(Promise和async/await和多线程并发TaskPool和Worker的使用)
前端·华为·多线程·harmonyos
迷曳15 小时前
24、鸿蒙Harmony Next开发:不依赖UI组件的全局自定义弹出框 (openCustomDialog)
dialog·前端·ui·harmonyos·鸿蒙
NoirSeeker15 小时前
在windows平台上基于OpenHarmony sdk编译三方库并暴露给ArkTS使用(详细)
c++·windows·arkts·鸿蒙·交叉编译
平谷一勺1 天前
鸿蒙状态栏操作
华为·harmonyos·沉浸式状态栏
Georgewu2 天前
【HarmonyOS组件/模板集成创新活动-如何高效开发鸿蒙应用 (鸿社圈子)】
harmonyos
前端世界2 天前
跨平台 App 如何无痛迁移到鸿蒙系统?全流程实战+Demo 教程
华为·harmonyos
龙儿筝2 天前
鸿蒙和Android知识点
android·harmonyos
迷曳2 天前
17、鸿蒙Harmony Next开发:状态管理(组件拥有的状态和应用拥有的状态)
前端·harmonyos·鸿蒙
zhanshuo2 天前
不同品牌的设备也能“心有灵犀”?带你玩转鸿蒙分布式跨端协同
harmonyos