《仿盒马》app开发技术分享-- 原生地图展示(端云一体)

开发准备

上一节我们实现了获取当前用户的位置,并且成功的拿到了经纬度,这一节我们就要根据拿到的经纬度,结合我们其他的知识点来实现地图的展示。

功能分析

地图的展示,我们需要在管理中心先给我们对应的应用开启地图api功能,否则是不能展示的,其次是我们要配置自签,不配置的话也是无法使用地图功能,然后我们还需要注意应用是否开启了联网权限,如果这些都已经完成,那么我们在地图显示之前还需要进行权限时候获取的校验

代码实现

首先我们在进入页面之前判断是否已经开启了定位权限

bundleManager.getBundleInfoForSelf(bundleFlags).then((data) => {

复制代码
    }).catch((err: BusinessError) => {
      hilog.error(0x0000, 'testTag', 'getBundleInfoForSelf failed. Cause: %{public}s', err.message);
    });

要实现这个功能我们还需要获取app的acctokenid

bundleManager.getBundleInfoForSelf(bundleFlags).then((data) => {

let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();

atManager.checkAccessToken(data.appInfo.accessTokenId, 'ohos.permission.LOCATION').then((status: abilityAccessCtrl.GrantStatus) => {

if (status==0) {

this.addressSetting=true

this.locationKey=true

this.reqPermissionsFromUser(permissions);

}

}).catch((err: BusinessError) => {

console.error(checkAccessToken fail, err->${JSON.stringify(err)});

});

}).catch((err: BusinessError) => {

hilog.error(0x0000, 'testTag', 'getBundleInfoForSelf failed. Cause: %{public}s', err.message);

});

这时候我们就通过反悔的status进行判断,当status等于0,我们就执行reqPermissionsFromUser,获取当前的位置经纬度,然后在里边实现地图参数的初始化和回调

this.mapOptions = {

position: {

target: {

latitude: locationInfo.latitude,

longitude: locationInfo.longitude

},

zoom: 10

}

};

this.callback = async (err, mapController) => {

if (!err) {

this.mapController = mapController;

this.mapEventManager = this.mapController.getEventManager();

let callback = () => {

console.info("TAG", on-mapLoad);

}

this.mapEventManager.on("mapLoad", callback);

}

};

都实现之后我们再添加对应的生命周期方法

onPageShow(): void {

if (this.mapController) {

this.mapController.show();

}

}

onPageHide(): void {

if (this.mapController) {

this.mapController.hide();

}

}

到这里我们的地图展示就实现了,我们执行一下代码看看效果

可以看到我们的地图已经成功展示出来了,完整代码如下

复制代码
import { MapComponent, mapCommon, map } from '@kit.MapKit';
import { AsyncCallback, BusinessError } from '@kit.BasicServicesKit';
import PermissionDialogWidget from '../dialog/PermissionDialogWidget';
import { geoLocationManager } from '@kit.LocationKit';
import { abilityAccessCtrl, bundleManager, common, Permissions } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';

const permissions: Array<Permissions> = ['ohos.permission.APPROXIMATELY_LOCATION','ohos.permission.LOCATION'];
let bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION;
@Entry
@Component
struct PushAddressPage {

  private mapOptions?: mapCommon.MapOptions;
  private callback?: AsyncCallback<map.MapComponentController>;
  private mapController?: map.MapComponentController;
  private mapEventManager?: map.MapEventManager;


  @State flag:boolean=false

  @State ss:number=0
  @State  locationKey:boolean=false
  @State  addressSetting:boolean=false
  permissionController:CustomDialogController=new CustomDialogController({
    builder:PermissionDialogWidget({
      titleText:"权限说明",
      contentText: '仿盒马想要申请位置权限,用于地址选择等功能。同意该权限后,选择地址时会复用此权限,不会重新申请,不授权上述权限,不影响APP其他功能使用。',
    }),
    alignment: DialogAlignment.Top,
  })
  @State locationInfo:geoLocationManager.ReverseGeoCodeRequest|null=null
  aboutToAppear(): void {
    try {
      let locationEnabled = geoLocationManager.isLocationEnabled();

      if (locationEnabled) {
        this.addressSetting=true
        bundleManager.getBundleInfoForSelf(bundleFlags).then((data) => {
          let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
          atManager.checkAccessToken(data.appInfo.accessTokenId, 'ohos.permission.LOCATION').then((status: abilityAccessCtrl.GrantStatus) => {
            if (status==0) {
              this.addressSetting=true
              this.locationKey=true
              this.reqPermissionsFromUser(permissions);
            }
          }).catch((err: BusinessError) => {
            console.error(`checkAccessToken fail, err->${JSON.stringify(err)}`);
          });
        }).catch((err: BusinessError) => {
          hilog.error(0x0000, 'testTag', 'getBundleInfoForSelf failed. Cause: %{public}s', err.message);
        });

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





  build() {
    if (this.flag){
      Column() {
        Stack({alignContent:Alignment.Bottom}){
          Column(){
            MapComponent({ mapOptions: this.mapOptions, mapCallback: this.callback }).width('100%').height('100%');
          }
          .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(()=>{
                  this.reqPermissionsFromUser(permissions);
                  this.permissionController.open();
                })
            }
            .padding(10)
            .borderRadius(5)
            .margin({bottom:30})
            .backgroundColor('#33000000')
            .justifyContent(FlexAlign.SpaceAround)
            .width('90%')
          }

        }
        .backgroundColor(Color.White)
        .height('100%')
        .width('100%')

      }
    }


  }



  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;
              this.mapOptions = {
                position: {
                  target: {
                    latitude: locationInfo.latitude,
                    longitude: locationInfo.longitude
                  },
                  zoom: 10
                }
              };
              this.callback = async (err, mapController) => {
                if (!err) {
                  this.mapController = mapController;
                  this.mapEventManager = this.mapController.getEventManager();
                  let callback = () => {
                    console.info("TAG", `on-mapLoad`);
                  }
                  this.mapEventManager.on("mapLoad", callback);
                }
              };
              this.flag=true

            })
              .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}`);
    })
  }



  aboutToDisappear() {
    this.permissionController!=undefined// 将dialogController置空
  }

  onPageShow(): void {
    if (this.mapController) {
      this.mapController.show();
    }
  }


  onPageHide(): void {
    if (this.mapController) {
      this.mapController.hide();
    }
  }


}
相关推荐
Georgewu4 小时前
【HarmonyOS 5】鸿蒙分布式协同应用开发详解
harmonyos
君莫笑111118 小时前
从零到一教你在鸿蒙中上架应用--全流程保姆级
harmonyos
二流小码农9 小时前
鸿蒙开发:资讯项目实战之项目初始化搭建
android·ios·harmonyos
HarmonyOS_SDK9 小时前
如何在应用中实现地图关键字搜索和标记聚合功能?
harmonyos
别说我什么都不会11 小时前
【OpenHarmony】图形图像加载:LargeImage
harmonyos
Aisanyi13 小时前
【鸿蒙开发】PC实现开局沉浸式全屏
前端·华为·harmonyos
我睡醒再说16 小时前
以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
harmonyos
我睡醒再说16 小时前
ArkUI-X跨平台开发能力解析:优势与限制场景
harmonyos
我睡醒再说16 小时前
纯血Harmony NETX 5小游戏实践:趣味三消游戏(附源文件)
harmonyos
我睡醒再说16 小时前
HarmonyOS NETX 5ArkUI-X打造数字猜谜游戏:(附源文件)
harmonyos