HarmonyOS获取设备地理位置实战_harmony获取定位(1),2024年最新HarmonyOS鸿蒙面试题及答案2024

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数HarmonyOS鸿蒙开发工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年HarmonyOS鸿蒙开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img

img
img
htt

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上HarmonyOS鸿蒙开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新

如果你觉得这些内容对你有帮助,可以添加VX:vip204888 (备注鸿蒙获取)
img

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

build(){
Column() {
Text(this.message)
.fontSize(20)
.height(40)
.fontColor(Color.White)
}
.width(‘100%’)
.backgroundColor(Color.Gray)
}

}


完成Demo的UI设计后,可以打开预览器查看界面效果



![图片](https://img-blog.csdnimg.cn/img_convert/b8eeb4f5af0c885f4a359860b1c815ba.png)



## 集成功能模块


**▍****向用户动态申请授权的基础功能模块**


获取设备地理位置信息的前提是用户同意提供相关敏感权限,这意味着我们需要向用户动态申请相关所需权限。而此次关于向用户动态申请授权的模块,笔者将把它们集成在Service目录下的两个TS文件里,分别是Applicant.ts与Detector.ts。


完成Demo的UI设计后,可以打开预览器查看界面效果


![图片](https://img-blog.csdnimg.cn/img_convert/b8eeb4f5af0c885f4a359860b1c815ba.png)



## 集成功能模块


**▍****向用户动态申请授权的基础功能模块**


获取设备地理位置信息的前提是用户同意提供相关敏感权限,这意味着我们需要向用户动态申请相关所需权限。而此次关于向用户动态申请授权的模块,笔者将把它们集成在Service目录下的两个TS文件里,分别是Applicant.ts与Detector.ts。



![图片](https://img-blog.csdnimg.cn/img_convert/bc3d8faad67be7d89dca73fac69f6dad.png)


之后,我们在Index.ets中对其进行调用



//导入common
import common from ‘@ohos.app.ability.common’
//导入向用户发起权限申请的模块
import Request_Permission_From_Users from ‘ets/Service/Applicant’

@Entry
@Component
struct Index {

//获取上下文对象, 储存在成员变量context中
private context = getContext(this) as common.UIAbilityContext

//编写异步方法,调用之前已写好的模块文件Applicant
async apply(){
let res = await Request_Permission_From_Users(this.context)
this.ifAccessible = res
if(res){
this.dialogController_Accessible.open()
}else{
this.dialogController_Inaccessible.open()
}
}

build() {
Column({space:10}) {

 ......

    Column(){
      Button('获取相关权限')
        .width('90%')
        .fontSize(18)
        .backgroundColor(Color.Pink)
        //调用异步方法apply
        .onClick(()=>{
          this.apply()
        })

     ......

    }
    .height('100%')
    .layoutWeight(4)
    .backgroundColor(Color.White)

  }
  .height('11%')
  .width('92%')

}

}


**获取设备地理信息的功能模块**


此功能模块的目的是输出设备所在地的经度,纬度,海拔高度和城市名,以及设备的速度(应该是瞬时的)。这需要先获取设备所在的地理位置坐标,再将地理位置坐标转化为具体的地理描述(即国家,城市等)。


在Service目录下新建一个TypeScript文件(右键Service目录,选择新建,再选择TypeScript),将其命名为Geo



![图片](https://img-blog.csdnimg.cn/img_convert/12398f681bc0399bb797742f592f6184.png)


在编辑器中打开目录Geo.ts,加入以下代码以集成获取设备地理信息的功能,各代码块的具体功能已写注解



//导入位置服务模块
import geoLocationManager from ‘@ohos.geoLocationManager’;

//导入自定义的权限检查模块
import Check_Access from ‘ets/Service/Detector’

//定义结点的标签
const TAG_NODE0 = '------[Geo-Node0] ’
const TAG_NODE1 = '------[Geo-Node1] ’
const TAG_NODE2 = '------[Geo-Node2] ’

/*
*结点函数1:获取用户设备当前所处位置的经度和纬度数据
*/
async function Node1_Get_Geographical_Position(){

//预定义返回值
let output = {
‘position_x’:null,
‘position_y’:null,
‘position_z’:null,
‘cityName’:’ 未知’,
‘speed’:null,
//结点函数的执行状态,默认为失败
‘isFinished’:false,
‘error’:‘无’
}

//检查定位功能是否可用
if(!geoLocationManager.isLocationEnabled()){
console.info(TAG_NODE1+‘Location module loads fail’)
output.error = ‘定位功能不可用, 请检查设备或服务器’
return
}

//定义需要输入的请求参数
let requestInfo = {‘priority’: 0x203, ‘scenario’: 0x300,‘maxAccuracy’: 0}

//等待模块完成获取地理位置的异步操作
await geoLocationManager.getCurrentLocation(requestInfo).then((result) => {
console.info(TAG_NODE1+‘Succeed! Current location => latitude: ’ + result.latitude+’; longitude: ‘+result.longitude+’;');

//记录获取的地理信息
output.position_x = result.latitude
output.position_y = result.longitude
output.position_z = result.altitude
output.speed = result.speed

//结点函数的执行状态修改为成功
output.isFinished = true

}).catch((error) => {
console.error(TAG_NODE1+'Get current location failed, error: ’ + JSON.stringify(error));
output.error = ‘地理位置获取失败’
});

return output

}

/*
*结点函数2:获取用户设备当前所处的城市名称(中文)
*/
async function Node2_Get_City_Name(input){

//预定义返回值
let output = {
‘cityName’: ’ 未知’,
‘position_x’:input.position_x,
‘position_y’:input.position_y,
‘position_z’:input.position_z,
‘speed’:input.speed,
//结点函数的执行状态,默认为失败
‘isFinished’: false,
‘error’:‘无’
}

//判断逆地理编码转换服务是否可用
if(!geoLocationManager.isGeocoderAvailable()){
console.error(TAG_NODE2+‘Geocoder module loads fail’)
output.error = ‘地理编码转化功能不可用, 请检查设备或服务器’
return output
}

//定义需要输入的请求参数,其中locale键对应的值’zh‘表示服务器将返回中文形式的信息
let reverseGeocodeRequest = {‘locale’:‘zh’,“latitude”: input.position_x, “longitude”: input.position_y, “maxItems”: 1};

//等待模块完成逆地理编码转换的异步操作
await geoLocationManager.getAddressesFromLocation(reverseGeocodeRequest).then((result) => {
console.info(TAG_NODE2+'City name : ’ + result[0].locality);

//记录获取的城市名
let cityName = result[0].locality
if(cityName.charAt(cityName.length-1) == '市') cityName.replace('市','')
output.cityName = cityName

//结点函数的执行状态修改为成功
output.isFinished = true

}).catch((error) => {
console.error(TAG_NODE2+'Get addresses from location: error: ’ + JSON.stringify(error));
output.error = ‘逆地理编码转换失败’
});

return output

}

//导出可供调用的接口
export async function Get_Geo_Data(){

//模块结点0
if(!Check_Access()){
console.error(TAG_NODE0+‘Insufficient required permissions’)
return {
‘position_x’:null,
‘position_y’:null,
‘position_z’:null,
‘cityName’:’ 未知’,
‘speed’:null,
‘isFinished’:false,
‘error’:‘设备未获取相关权限’
}
}

//模块结点1
let output = await Node1_Get_Geographical_Position()
if (!output.isFinished) return output

//模块结点2
return await Node2_Get_City_Name(output)

}


通常,集成这类模块需要优先考虑的问题是**回调地狱**。回调地狱是指,在使用回调函数处理异步操作时,由于多个异步操作的嵌套和依赖关系,导致代码结构变得混乱和难以维护的情况。在Java中,我们可以通过创建线程和设置各线程优先级的方式,将原本的异步过程调整为线性的同步过程。而在TypeScript中,除了传统的设置线程的方法之外,我们还可以通过Promise或async/await来避免回调地狱,使代码更加清晰和易于理解。


在上述代码中,笔者声明了两个异步函数,分别是Node1\_Get\_Geographical\_Position与Node2\_Get\_City\_Name,不妨称它们为结点函数。其中,第一个结点函数用于获取地理位置信息(包含坐标信息),第二个结点函数用于将所获取的地理坐标信息转换为地理描述,并且,它们在时间维度上有一个执行次序,即先执行第一个结点函数,当其执行完成并返回相关结果后,再执行第二个结点函数。显然,第二个结点函数的输入即为第一个结点函数的输出,而这也是先执行第一个结点函数的原因。


要让两个异步的结点函数按次序线性执行,我们可以定义一个新的异步函数Get\_Geo\_Data,在其函数体内添加合适的操作语句以调用这两个结点函数。在上述代码中,Get\_Geo\_Data首先需判定相关的位置权限是否已被提供,接着调用第一个结点函数Node1\_Get\_Geographical\_Position,并在调用时增加了关键字await。这意味着,在Node1\_Get\_Geographical\_Position返回结果之前,Get\_Geo\_Data函数体中剩下的未执行的操作语句是不会被执行的。当第一个结点函数执行结束后,Get\_Geo\_Data再调用第二个结点函数Node2\_Get\_City\_Name,同样地,要添加关键字await,否则在第二个结点函数成功响应前,Get\_Geo\_Data就已经跑完了,这样什么都不会被输出。


![](https://img-blog.csdnimg.cn/direct/ec861ba76ee04a66a766561392aee7f5.png)


接下来,笔者将讨论两个结点函数各自的代码逻辑。


对于第一个结点函数Node1\_Get\_Geographical\_Position,首先它预定义了需要输出的变量output(对应一个Object型数据),其包含7个不同的键值对。接着,检查定位功能是否可用,若可用,则通过导入的系统模块geoLocationManager的getCurrentLocation方法异步获取设备的地理位置信息,并在then()中提取地理位置信息中所携带的经度,纬度,海拔高度,和实时速度。最后,输出变量output。


至于第二个结点函数Node2\_Get\_City\_Name,首先它预定义了需要输出的变量output,并且将传入的参数input(即Node1\_Get\_Geographical\_Position的输出)的一些键对应的值拷贝到output中。之后,    判断逆地理编码转换功能是否可用,若可用,则通过geoLocationManager的getAddressesFromLocation方法异步获取设备所在位置的地理描述信息(即国家,城市等),并在then()中提取地理描述信息中的城市名。最后,输出变量output。


完成功能集成工作后,我们在Index.ets中调用此模块



//导入获取设备地理信息的模块
import { Get_Geo_Data } from ‘ets/Service/Geo’

@Entry
@Component
struct Index {

//编写异步方法,调用之前已写好的模块文件Geo
async update_geo_data(){

//判断是否获取所需权限
if(!this.ifAccessible){
  this.dialogController_Inaccessible.open()
  return
}

let info = await Get_Geo_Data()

this.Geo_Info = '       ---地理信息---\n' + '\n当前所在城市:' + info.cityName + '\n纬度: ' + info.position_x + '\n经度: ' + info.position_y + '\n海拔: ' + info.position_z + '\n速度: ' + info.speed + ' m/s\n'
if(!info.isFinished) this.Geo_Info += '\n错误信息: ' + info.error

}

build() {
Column({space:10}) {

    Column(){
    
     ......

      Button('获取地理位置')
        .width('90%')
        .fontSize(18)
        .backgroundColor(Color.Pink)
        .margin({
          top:14
        })
        //调用异步方法update_geo_data
        .onClick(()=>{
          this.update_geo_data()
        })

    }
    .height('100%')
    .layoutWeight(4)
    .backgroundColor(Color.White)

  }
  .height('11%')
  .width('92%')

}

}


## 真机&模拟机调试


Demo完成之后,我们需要用模拟机或真机来运行以查看效果。



![图片](https://img-blog.csdnimg.cn/img_convert/eaa0ad378460ceaadbaab749e34f4c38.gif)


可惜的是,模拟机里的逆地理编码转换服务是不可用的,所以其无法得到设备所在地的地理描述,因而无法输出城市名。


相关日志如下,可见,逆地理编码转换服务被检查为不可用。



![图片](https://img-blog.csdnimg.cn/img_convert/57b96e475eb6dbde5299882693186e87.png)


如果在真机上运行,逆地理编码转换服务是没什么问题的。下图是笔者借用了roommate的真机后得到的程序运行截图



![图片](https://img-blog.csdnimg.cn/img_convert/d6ce77909e6f6119eed764fc53eac287.jpeg)


![](https://img-blog.csdnimg.cn/direct/d6ab95dfa3f943bfb683e92378b0fcd4.png)


最后,有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的**鸿蒙(Harmony NEXT)资料**用来跟着学习是非常有必要的。 


**这份鸿蒙(Harmony NEXT)资料包含了鸿蒙开发必掌握的核心知识要点,内容包含了**(**ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony****多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(Harmony NEXT)**技术知识点。


希望这一份鸿蒙学习资料能够给大家带来帮助,有需要的小伙伴自行领取,**限时开源,先到先得~无套路领取!!**


**如果你是一名有经验的资深Android移动开发、Java开发、前端开发、对鸿蒙感兴趣以及转行人员,可以直接领取这份资料**


**获取这份完整版高清学习路线,请点击→**[纯血版全套鸿蒙HarmonyOS学习资料]( )****


### **鸿蒙(Harmony NEXT)最新学习路线**


**![](https://img-blog.csdnimg.cn/direct/309a2ac95b5d40aa8c0f79885edb295a.png)**


* **HarmonOS基础技能**
频、视频、WebGL、OpenHarmony****多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(Harmony NEXT)**技术知识点。


希望这一份鸿蒙学习资料能够给大家带来帮助,有需要的小伙伴自行领取,**限时开源,先到先得~无套路领取!!**


**如果你是一名有经验的资深Android移动开发、Java开发、前端开发、对鸿蒙感兴趣以及转行人员,可以直接领取这份资料**


**获取这份完整版高清学习路线,请点击→**[纯血版全套鸿蒙HarmonyOS学习资料]( )****


### **鸿蒙(Harmony NEXT)最新学习路线**


**![](https://img-blog.csdnimg.cn/direct/309a2ac95b5d40aa8c0f79885edb295a.png)**


* **HarmonOS基础技能**
  • 18
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值