前言
地图定位功能相信很多人都用过,在鸿蒙的应用程序开发中,使用高德地图的定位功能变得十分常见,那么在鸿蒙中一次完整的地位功能怎么实现?如果定位失败了,能否获取前几次的定位呢?本篇文章带你实现一个完整的定位功能流程,建议点赞收藏!
需求分析
要想实现一个完整的定位需求流程,就必须要做好准备工作,了解实现需求的具体步骤。
- 权限申请
- 检查 GPS 是否打开
- 单次定位还是多次定位
定位失败处理
技术实现
要想实现一次完整的定位流程,必须根据需要分析一步步去实现,由于高德地图的引入太过于简单,这里一笔带过。重点讲解完整实现的步骤。
添加基本定位权限,在 entry 模块下的 module.json5 中添加定位必要的两个权限。
{ // user_grant "name": "ohos.permission.APPROXIMATELY_LOCATION", "reason": "$string:location_permissions_reason", "usedScene": { "abilities": [ "EntryAbility" ], "when": "always" } }, { // user_grant "name": "ohos.permission.LOCATION", "reason": "$string:location_permissions_reason", "usedScene": { "abilities": [ "EntryAbility" ], "when": "always" } },
在页面中进行权限申请,一般是在 onPageShow 生命周期方法中申请,先检查系统 GPS 定位开关是否开启,如果没有开启则提示用户跳转到系统指定位置打开。
let location = geoLocationManager.isLocationEnabled() if (!location) { let dialog = new OpenSystemGPSEHelper() dialog.show(this.getUIContext(),getContext(this) as common.UIAbilityContext,()=>{ this.currentCity = "定位失败" }) } //GPS跳转页面 context.startAbility( { bundleName: "com.huawei.hmos.settings", abilityName: "com.huawei.hmos.settings.MainAbility", uri: "location_manager_settings" },
确认 GPS 打开之后,开始 申请 用户权限。
static applyPermission(context: common.UIAbilityContext, permissions: Array<Permissions>, grantedBlock: () => void, deniedBlock?: () => void) { let atManager = abilityAccessCtrl.createAtManager() let permissionGrantedNumber: number = 0 atManager.requestPermissionsFromUser(context, permissions).then((data) => { for (let index = 0; index < data.authResults.length; index++) { if (data.authResults[index] == 0) { permissionGrantedNumber++; } } if (permissionGrantedNumber == permissions.length) { grantedBlock() } else { if (deniedBlock) { deniedBlock() } else { PermissionUtil.openPermissionsInSystemSettings(context) } } }) }
如果用户打开权限,则直接开始定位服务,否则提示用户跳转到系统指定位置打开权限。
let wantInfo: Want = { bundleName: 'com.huawei.hmos.settings', abilityName: 'com.huawei.hmos.settings.MainAbility', uri: 'application_info_entry', parameters: { settingsParamBundleName: bundleInfo.name } } context.startAbility(wantInfo).then(() => { })
确认定位权限没问题后,开始定位,高德提供的定位有多次和单次,这里使用单次定位。
let listener: IAMapLocationListener = { onLocationChanged: (location) => { console.log("当前定位1:"+location.latitude+",---longitude:"+location.longitude) this.transformCity(location.latitude,location.longitude) }, onLocationError: (error) => { } }; LocationManager.getInstance().addListener(listener) LocationManager.getInstance().initLocation() // 定位参数配置 let options: AMapLocationOption = { //定位优先配置选项 priority: geoLocationManager.LocationRequestPriority.FIRST_FIX, //定位场景设置 scenario: geoLocationManager.LocationRequestScenario.UNSET, //定位精度 单位:米 maxAccuracy: 0, //指定单次定位超时时间 singleLocationTimeout: 3000, //定位是否返回逆地理信息 locatingWithReGeocode: true, //逆地址语言类型 reGeocodeLanguage: AMapLocationReGeocodeLanguage.Chinese, isOffset: false //是否加偏 } // 设置配置 this.locationManger?.setLocationOption(AMapLocationType.Single, options) if (this.listener != undefined) { // 监听 this.locationManger?.setLocationListener(AMapLocationType.Single, this.listener) } // 启动定位 this.locationManger?.requestSingleLocation()
- 定位成功拿到定位的信息,在实际开发中尽管设置中已经设置返回逆地理信息,但并没有返回具体信息,这点实在是无法理解,只能得到当前位置的经纬度。这个时候需要将经纬度转换为当前位置名称。
在开发中通过使用华为官方系统中的 api,对经纬度进行逆编码才能获取准备的位置名称。
let reverseGeocodeRequest:geoLocationManager.ReverseGeoCodeRequest = {"latitude":latitude, "longitude":longitude, "maxItems": 1}; try { geoLocationManager.getAddressesFromLocation(reverseGeocodeRequest, (err, data) => {})
如果地图定位失败,则可以根据高德地图提供的方法,尝试拿取历史定位信息。
LocationManager.getInstance().getLastLocation({ onLocationChanged: (location) => { console.info('地图定位缓存获取成功: ' + JSON.stringify(location)) if (success) { success() } }, onLocationError: (e) => { console.info('地图定位缓存获取失败: ' + JSON.stringify(e)) if (success) { success() } } })
- 如果历史定位信息也获取失败,这时就能使用默认定位位置了。
总结
定位功能实现起来比较简单,但是完整的定位流程及细节处理才是本篇文章的关键,相信看完本篇文章你已经学会在鸿蒙中怎么使用高德定位功能了,快去动手尝试一下吧!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。