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

举报
yd_215151764 发表于 2025/06/30 10:27:37 2025/06/30
【摘要】 ## 技术栈Appgallery connect## 开发准备上一节我们实现了地址管理页面的数据查询和展示,接下来我们要实现的功能是地址添加相关的,我们想实现的功能是地图选点,那么在地图选点之前我们要做的就是先获取用户当前的定位。获取定位后我们拿到经纬度和其他信息,然后在对应的地图上展示。## 功能分析要想实现定位功能,首先我们需要给应用申请定位权限,然后我们每次进入页面之前需要先进行定位功...


## 技术栈

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();
              })
这里我们同步创建一个弹窗,当然你可以有多种选择来实现权限的同步说明,在这里我们两种方式都实现了
创建弹窗
@CustomDialog
export  default  struct PermissionDialogWidget{
  @State titleText:string='';
  @State contentText:string='';
  controller: CustomDialogController
  build(){
    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=true
          this.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=false
          this.permissionController.close()
          return;
        }
      }
    }).catch((err:Error) => {
      console.error(`requestPermissionsFromUser failed, code is ${err.name}, message is ${err.message}`);
    })
  }
  
在这里我们既实现了自定义弹窗的同步说明,同时也在model.json5中配置了reason进行说明,可以按需进行实现。

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

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。