目录

元服务逆地理编码获取地址信息

Q:元服务如何通过逆地理编码,根据当前位置的经纬度返回对应的地址信息?

A:1.获取当前位置经纬度:

通过Location Kit的geoLocationManager.getCurrentLocation获取当前位置的经纬度信息。开发准备:在使用Location Kit系统能力前,需要检查是否已经获取用户授权访问设备位置信息。如未获得授权,可以向用户申请需要的位置权限,操作步骤参考:申请位置权限开发指导。

2.通过逆地理编码返回详细地址:

通过Map Kit的reverseGeocode逆地理编码接口解析经纬度返回对应的地址信息,包括位置描述信息、结构化区划信息、周边POI地点等详细信息。开发准备:在使用Map Kit系统能力前,需要开通地图服务,操作步骤参考Map Kit开发准备。

请开发者在项目的module.json5配置文件的requestPermissions标签中声明ohos.permission.APPROXIMATELY_LOCATION和ohos.permission.LOCATION权限,完整示例代码如下:

import { abilityAccessCtrl, bundleManager, common, Permissions } from '@kit.AbilityKit';
import { geoLocationManager } from '@kit.LocationKit';
import { site } from '@kit.MapKit';

const APPROXIMATELY_LOCATION: Permissions = 'ohos.permission.APPROXIMATELY_LOCATION';
const LOCATION: Permissions = 'ohos.permission.LOCATION';
const PERMISSION_TIPS: string = '"获取当前位置"需开启位置访问权限才能正常使用。';
const PRECISE_LOCATION_TIPS: string = '"获取当前位置"需获取精确定位权限才能获取精确位置。';
const LOCATION_SERVICE_TIPS: string = '"获取当前位置"需开启设备位置服务才能正常使用。';

@Entry
@Component
struct Index {
  @State isShowLocationPermissionTips: boolean = false;
  @State locationPermissionTips: string = PERMISSION_TIPS;
  @State isShowLocationServiceTips: boolean = false;
  @State locationServiceTips: string = LOCATION_SERVICE_TIPS;
  @State currentLocation: string = '';
  private context: common.UIAbilityContext = this.getUIContext().getHostContext() as common.UIAbilityContext;

  build() {
    Navigation() {
      Column() {
        Column() {
          Text(this.currentLocation);
        }
        .alignItems(HorizontalAlign.Start)
        .width('100%');

        Column() {
          if (this.isShowLocationPermissionTips) {
            Text() {
              Span(this.locationPermissionTips)
                .fontColor($r('sys.color.mask_secondary'));
              Span('开启位置访问权限')
                .fontColor('#0A59F7')
                .onClick(() => {
                  this.checkPermissionGrant();
                });
            }
            .margin({
              bottom: 16
            });
          }
          if (this.isShowLocationServiceTips) {
            Text() {
              Span(this.locationServiceTips)
                .fontColor($r('sys.color.mask_secondary'));
              Span('开启设备位置服务')
                .fontColor('#0A59F7')
                .onClick(() => {
                  this.checkLocationService();
                });
            }
            .margin({
              bottom: 16
            });
          }
          Button('获取当前位置')
            .width('80%')
            .onClick(() => {
              this.currentLocation = '';
              this.checkPermissionGrant();
            });
        };
      }
      .width('100%')
      .height('100%')
      .padding(10)
      .justifyContent(FlexAlign.SpaceBetween);
    }
    .titleMode(NavigationTitleMode.Full)
    .title('当前位置:');

  }

  /**
   * 检查应用是否有位置访问权限
   */
  checkPermissionGrant(): void {
    let hasLocationPermission = false;
    let tokenId: number = 0;
    try {
      let bundleInfo: bundleManager.BundleInfo =
        bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
      tokenId = bundleInfo.appInfo.accessTokenId;
    } catch (error) {
      const err: BusinessError = error as BusinessError;
      console.error(`Failed to get bundle info for self. Code is ${err.code}, message is ${err.message}`);
    }

    try {
      let atManager = abilityAccessCtrl.createAtManager();
      let hasApproxLocation = atManager.checkAccessTokenSync(tokenId, APPROXIMATELY_LOCATION);
      let hasLocation = atManager.checkAccessTokenSync(tokenId, LOCATION);
      hasLocationPermission = hasApproxLocation === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED &&
        hasLocation === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED;
    } catch (error) {
      const err: BusinessError = error as BusinessError;
      console.error(`Failed to check access token. Code is ${err.code}, message is ${err.message}`);
    }
    if (hasLocationPermission) {
      this.checkLocationService();
    } else {
      this.requestPermission();
    }
  }

  /**
   * 向用户请求位置访问权限
   */
  requestPermission(): void {
    let atManager = abilityAccessCtrl.createAtManager();
    try {
      atManager.requestPermissionsFromUser(this.context, [APPROXIMATELY_LOCATION, LOCATION])
        .then((data) => {
          if (data.authResults[0] === -1 || data.authResults[1] === -1) {
            if (data.dialogShownResults && (data.dialogShownResults[0] || data.dialogShownResults[1])) {
              this.isShowLocationPermissionTips = true;
              if (data.authResults[0] === -1) {
                this.locationPermissionTips = PERMISSION_TIPS;
              } else {
                this.locationPermissionTips = PRECISE_LOCATION_TIPS;
              }
            } else {
              this.openPermissionSetting();
              return;
            }
          } else {
            this.isShowLocationPermissionTips = false;
          }
          if (data.authResults[0] !== 0) {
            return;
          }
          this.checkLocationService();
        }).catch((err: Error) => {
        console.error(`requestPermissionsFromUser err. message is ${err.message}`);
      });
    } catch (error) {
      const err: BusinessError = error as BusinessError;
      console.error(`Failed to requestPermissionsFromUser. Code is ${err.code}, message is ${err.message}`);
    }
  }

  /**
   * 拉起权限设置弹窗
   */
  openPermissionSetting(): void {
    let atManger = abilityAccessCtrl.createAtManager();
    atManger.requestPermissionOnSetting(this.context, [APPROXIMATELY_LOCATION, LOCATION])
      .then((data: Array<abilityAccessCtrl.GrantStatus>) => {
        if (data[0] === -1 && data[1] === -1) {
          this.isShowLocationPermissionTips = true;
          this.locationPermissionTips = PERMISSION_TIPS;
          return;
        } else if (data[0] === 0 && data[1] === -1) {
          this.isShowLocationPermissionTips = true;
          this.locationPermissionTips = PRECISE_LOCATION_TIPS;
        } else {
          this.isShowLocationPermissionTips = false;
        }
        this.checkLocationService();
      }).catch((err: BusinessError) => {
      console.error(`Failed to requestPermissionOnSetting. Code is ${err.code}, message is ${err.message}`);
    });
  }

  /**
   * 检查设备是否开启位置服务
   */
  checkLocationService(): void {
    let atManager = abilityAccessCtrl.createAtManager();
    let isLocationEnable = true;
    try {
      isLocationEnable = geoLocationManager.isLocationEnabled();
    } catch (error) {
      const err: BusinessError = error as BusinessError;
      console.error(`Failed to check isLocationEnabled. Code is ${err.code}, message is ${err.message}`);
    }
    if (!isLocationEnable) {
      atManager.requestGlobalSwitch(this.context, abilityAccessCtrl.SwitchType.LOCATION).then((data: boolean) => {
        if (data) {
          this.isShowLocationServiceTips = false;
          this.getLocation();
        } else {
          this.isShowLocationServiceTips = true;
          this.locationServiceTips = LOCATION_SERVICE_TIPS;
        }
      }).catch((err: BusinessError) => {
        console.error(`Failed to requestGlobalSwitch. Code is ${err.code}, message is ${err.message}`);
      });
    } else {
      this.isShowLocationServiceTips = false;
      this.getLocation();
    }
  }

  /**
   * 获取位置信息并通过逆地理编码获取城市信息
   */
  getLocation() {
    let request: geoLocationManager.SingleLocationRequest = {
      'locatingTimeoutMs': 10000,
      'locatingPriority': geoLocationManager.LocatingPriority.PRIORITY_LOCATING_SPEED
    };
    geoLocationManager.getCurrentLocation(request).then((location) => {
      let params: site.ReverseGeocodeParams = {
        location: {
          latitude: location.latitude,
          longitude: location.longitude
        },
        language: 'zh',
        radius: 100
      };
      site.reverseGeocode(params).then((data) => {
        if (data.addressDescription) {
          this.currentLocation = data.addressDescription;
        }
      }).catch((err: BusinessError) => {
        console.error(`Failed to reverseGeocode. Code is ${err.code}, message is ${err.message}`);
      });
    }).catch((err: BusinessError) => {
      console.error(`Failed to getCurrentLocation. Code is ${err.code}, message is ${err.message}`);
    });
  }
}

Q:调用reverseGeocode接口报错:App authentication failed. code: 1002600003。

A:参考1002600003完成应用身份校验。