HarmonyOS成功失掉设施天文位置

本期笔者将以一个Demo为例,协助有须要的HarmonyOS开发者成功失掉设施天文位置的配置。

关上DevEco Studio(开发工具的版本必定允许API9),创立一个新的project,相关勾选如下:

导入图片资源

在工程文件目录中关上目录:src/main/resources/rawfile, 参与两张恣意的图片(可以在IDE中将待参与的图片资源间接粘贴至rawfile目录下,也可以在文件资源治理器中经过文件门路关上rawfile目录并参与图片资源),区分命名为image1和image2。当然,图片的格局没有要求,只需在之后的步骤中能被正确援用即可。

参与UI形容

关上Index.ets,删除build()边疆有的一切代码块,参与新的UI申明和自定义弹窗,并定义一些成员变量,相关代码如下:

@Entry@Componentstruct Index {title:string = '天文信息面板'@State Geo_Info:string = ''//用于存储用户能否授权的形态信息@State ifAccessible:boolean = false//new两个弹窗控制器private dialogController_Accessible : CustomDialogController = new CustomDialogController({builder:dialog({message:'已失掉权限'})})private dialogController_Inaccessible : CustomDialogController = new CustomDialogController({builder:dialog({message:'失掉权限失败 | 缺少相关权限'})})build() {Column({space:10}) {//新的Text组件Text(this.title).fontSize(26).fontWeight(800).margin({top:20,bottom:20}).fontColor('#e699cc')Row(){//条件渲染image组件if(this.ifAccessible == true){Image($rawfile('image2.png')).objectFit(ImageFit.Contain).layoutWeight(1)}else{Image($rawfile('image1.png')).objectFit(ImageFit.Contain).layoutWeight(1)}Column(){//两个新的Button组件Button('失掉相关权限').width('90%').fontSize(18).backgroundColor(Color.Pink)Button('失掉天文位置').width('90%').fontSize(18).backgroundColor(Color.Pink).margin({top:14})}.height('100%').layoutWeight(4).backgroundColor(Color.White)}.height('11%').width('92%')//新的TextArea组件TextArea({text:this.Geo_Info}).width('94%').height('50%').fontSize(18).backgroundColor('#F0F0F0').margin({top:20})}.width('100%')}}//自定义弹窗@CustomDialogstruct dialog{controller:CustomDialogController@State message:string = ''build(){Column() {Text(this.message).fontSize(20).height(40).fontColor(Color.White)}.width('100%').backgroundColor(Color.Gray)}}

成功Demo的UI设计后,可以关上预览器检查界面成果:

集成配置模块

向用户灵活放开授权的基础配置模块

失掉设施天文位置信息的前提是用户赞同提供相关敏感权限,这象征着咱们须要向用户灵活放开相关所需权限。而此次关于向用户灵活放开授权的模块,笔者将把它们集成在Service目录下的两个TS文件里,区分是Applicant.ts与Detector.ts。

关于如何集成向用户灵活放开授权的模块,以及须要在module.json5中参与哪些权限,笔者在上期博客中已详细论述。

之后,咱们在Index.ets中对其启动调用。

//导入commonimport common from '@ohos.app.ability.common'//导入向用户动员权限放开的模块import Request_Permission_From_Users from 'ets/Service/Applicant'@Entry@Componentstruct Index {......//失掉高低文对象, 贮存在成员变量context中private context = getContext(this) as common.UIAbilityContext//编写异步方法,调用之前已写好的模块文件Applicantasync apply(){let res = await Request_Permission_From_Users(this.context)this.ifAccessible = resif(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。

在编辑器中关上目录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.latitudeoutput.position_y = result.longitudeoutput.position_z = result.altitudeoutput.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].localityif(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(){//模块结点0if(!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':'设施未失掉相关权限'}}//模块结点1let output = await Node1_Get_Geographical_Position()if (!output.isFinished) return output//模块结点2return 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就曾经跑完了,这样什么都不会被输入。

接上去,笔者将探讨两个结点函数各自的代码逻辑。

关于第一个结点函数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@Componentstruct Index {......//编写异步方法,调用之前已写好的模块文件Geoasync 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成功之后,咱们须要用模拟机或真机来运转以检查成果。

惋惜的是,模拟机里的逆天文编码转换服务是无法用的,所以其无法失掉设施所在地的天文形容,因此无法输入市区名。

相关日志如下,可见,逆天文编码转换服务被审核为无法用。

假设在真机上运转,逆天文编码转换服务是没什么疑问的。下图是笔者借用了roommate的真机后失掉的程序运转截图。

您可能还会对下面的文章感兴趣: