写点什么

《仿盒马》app 开发技术分享 -- 定位获取(25)

作者:鸿蒙小林
  • 2025-06-30
    浙江
  • 本文字数:2452 字

    阅读完需:约 8 分钟

技术栈

Appgallery connect

开发准备

上一节我们实现了地址管理页面的数据查询和展示,接下来我们要实现的功能是地址添加相关的,我们想实现的功能是地图选点,那么在地图选点之前我们要做的就是先获取用户当前的定位。获取定位后我们拿到经纬度和其他信息,然后在对应的地图上展示。

功能分析

要想实现定位功能,首先我们需要给应用申请定位权限,然后我们每次进入页面之前需要先进行定位功能是否开启的判断,如果没有开启我们要提示用户去开启,之后我们才是对定位请求的开启判断,用户同意之后获取当前的定位,在返回值中拿到经纬度

代码实现

首先我们在 model.json5 中添加对应的权限{"name": "ohos.permission.LOCATION","reason": "$string:app_location","usedScene": {"abilities": ["EntryAbility"],"when":"inuse"}


  },  {    "name": "ohos.permission.APPROXIMATELY_LOCATION",    "reason": "$string:app_reason_location",    "usedScene": {      "abilities": [        "EntryAbility"      ],      "when":"inuse"    }  }  添加完成后我们新建一个提交定位管理的页面,在生命周期中先进行手机是否开启定位的判断,并且新增两个变量来控制我们的定位触发
复制代码


@State locationKey:boolean=false@State addressSetting:boolean=false


aboutToAppear(): void {try {let locationEnabled = geoLocationManager.isLocationEnabled();if (locationEnabled) {this.addressSetting=true


  }else {    this.addressSetting=false  }} catch (err) {  console.error("errCode:" + err.code + ", message:"  + err.message);}
复制代码


}


如果用户开启了定位,并且我们没有开启应用的定位权限,在当前页面的底部提醒用户,去开启定位


build() {Column() {Stack({alignContent:Alignment.Bottom}){Column(){


    }    .layoutWeight(1)
if (this.addressSetting&&!this.locationKey){ Row(){ Text() .width(40)
Text("定位未开启") .fontColor(Color.Black)
Text("开启定位") .fontColor(Color.White) .backgroundColor(Color.Pink) .borderRadius(10) .padding(10) .onClick(()=>{ }) } .padding(10) .borderRadius(5) .margin({bottom:30}) .backgroundColor('#33000000') .justifyContent(FlexAlign.SpaceAround) .width('90%') }
} .backgroundColor(Color.White) .height('100%') .width('100%')
}
复制代码


}因为在隐私合规的情况下,我们已经不能进入页面就执行权限的请求了,这一点很重要当我们点击开启定位.onClick(()=>{this.reqPermissionsFromUser(permissions);this.permissionController.open();})这里我们同步创建一个弹窗,当然你可以有多种选择来实现权限的同步说明,在这里我们两种方式都实现了创建弹窗 @CustomDialogexport default struct PermissionDialogWidget{@State titleText:string='';@State contentText:string='';controller: CustomDialogControllerbuild(){Column(){Text(this.titleText).margin({top:10})Text(this.contentText).margin({top:20,bottom:10})}.justifyContent(FlexAlign.Start).padding({left:20,right:20})}}


引用弹窗 permissionController:CustomDialogController=new CustomDialogController({builder:PermissionDialogWidget({titleText:"权限说明",contentText: 'xxx 想要申请位置权限,用于地址选择等功能。同意该权限后,选择地址时会复用此权限,不会重新申请,不授权上述权限,不影响 APP 其他功能使用。',}),alignment: DialogAlignment.Top,})执行权限请求 reqPermissionsFromUser(permissions: Array<Permissions>): void {let context = getContext(this) as common.UIAbilityContext;let atManager = abilityAccessCtrl.createAtManager();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) {this.locationKey=truethis.permissionController.close()let request: geoLocationManager.SingleLocationRequest = {'locatingPriority': geoLocationManager.LocatingPriority.PRIORITY_LOCATING_SPEED,'locatingTimeoutMs': 10000}try {geoLocationManager.getCurrentLocation(request).then((result) => {console.log('current location: ' + JSON.stringify(result));let locationInfo:geoLocationManager.ReverseGeoCodeRequest=result;let reverseGeocodeRequest:geoLocationManager.ReverseGeoCodeRequest = {"latitude": locationInfo.latitude, "longitude": locationInfo.longitude, "maxItems": 1};try {geoLocationManager.getAddressesFromLocation(reverseGeocodeRequest, (err, data) => {if (err) {console.error('getAddressesFromLocation: err=' + JSON.stringify(err));}if (data) {console.info('地址打印' + JSON.stringify(data));}});} catch (err) {console.error("errCode:" + err.code + ", message:" + err.message);}}).catch((error:BusinessError) => {console.error('promise, getCurrentLocation: error=' + JSON.stringify(error));});} catch (err) {console.error("errCode:" + JSON.stringify(err));}} else {this.locationKey=falsethis.permissionController.close()return;}}}).catch((err:Error) => {console.error(requestPermissionsFromUser failed, code is ${err.name}, message is ${err.message});})}


在这里我们既实现了自定义弹窗的同步说明,同时也在 model.json5 中配置了 reason 进行说明,可以按需进行实现。


在请求定位的返回信息中我们拿到了经纬度的信息,到这里我们实现了定位获取功能

用户头像

鸿蒙小林

关注

还未添加个人签名 2025-06-20 加入

还未添加个人简介

评论

发布
暂无评论
《仿盒马》app开发技术分享-- 定位获取(25)_鸿蒙小林_InfoQ写作社区