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完成应用身份校验。