赞
踩
移动终端设备已经深入人们日常生活的方方面面,如查看所在城市的天气、新闻轶事、出行打车、旅行导航、运动记录。这些习以为常的活动,都离不开定位用户终端设备的位置。
当用户处于这些丰富的使用场景中时,系统的位置能力可以提供实时准确的位置数据。对于开发者,设计基于位置体验的服务,也可以使应用的使用体验更贴近每个用户。
当应用在实现基于设备位置的功能时,如:驾车导航,记录运动轨迹等,可以调用该模块的API接口,完成位置信息的获取。
位置子系统使用多种定位技术提供服务,如GNSS定位、基站定位、WLAN/蓝牙定位(基站定位、WLAN/蓝牙定位后续统称“网络定位技术”);通过这些定位技术,无论用户设备在室内或是户外,都可以准确地确定设备位置。
位置服务除了提供基础的定位服务之外,还提供了地理围栏、地理编码、逆地理编码、国家码等功能和接口。
位置能力作为系统为应用提供的一种基础服务,需要应用在所使用的业务场景,向系统主动发起请求,并在业务场景结束时,主动结束此请求,在此过程中系统会将实时的定位结果上报给应用。
使用设备的位置能力,需要用户进行确认并主动开启位置开关。如果位置开关没有开启,系统不会向任何应用提供位置服务。
设备位置信息属于用户敏感数据,所以即使用户已经开启位置开关,应用在获取设备位置前仍需向用户申请位置访问权限。在用户确认允许后,系统才会向应用提供位置服务。
系统提供的定位权限有:
访问设备的位置信息,必须申请权限,并且获得用户授权。
target API level | 申请位置权限 | 申请结果 | 位置的精确度 |
小于9 | ohos.permission.LOCATION | 成功 | 获取到精准位置,精准度在米级别。 |
大于等于9 | ohos.permission.LOCATION | 失败 | 无法获取位置。 |
大于等于9 | ohos.permission.APPROXIMATELY_LOCATION | 成功 | 获取到模糊位置,精确度为5公里。 |
大于等于9 | 同时申请ohos.permission.APPROXIMATELY_LOCATION和ohos.permission.LOCATION | 成功 | 获取到精准位置,精准度在米级别。 |
在工程目录下的module.json5中
添加:
根据需要添加权限,这里我只用简单的模糊定位权限(ohos.permission.APPROXIMATELY_LOCATION)来演示
- "requestPermissions": [
- {
- "name": 'ohos.permission.APPROXIMATELY_LOCATION'
- }
- ],
注意:使用位置服务功能,在module.json5添加权限的同时,还需用户动态申请权限。不能够只在module.json5添加权限,还需要用户动态申请权限。而且还需要虚拟机中运行代码。
当应用需要访问用户的隐私信息或使用系统能力时,例如获取位置信息、访问日历、使用相机拍摄照片或录制视频等,应该向用户请求授权。这需要使用 user_grant 类型权限。在此之前,应用需要进行权限校验,以判断当前调用者是否具备所需的权限。如果权限校验结果表明当前应用尚未被授权该权限,则应使用动态弹框授权方式,为用户提供手动授权的入口。
在进行权限申请之前,需要先检查当前应用程序是否已经被授予了权限。可以通过
@ohos.abilityAccessCtrl (程序访问控制管理)中的checkAccessToken()方法来校验当前是否已经授权。如果已经授权,则可以直接访问目标操作,否则需要进行下一步操作,即向用户申请授权。
使用@ohos.abilityAccessCtrl (程序访问控制管理)步骤:
导入模块:
import abilityAccessCtrl from '@ohos.abilityAccessCtrl'
abilityAccessCtrl.createAtManager获取访问控制模块对象:
let atManager = abilityAccessCtrl.createAtManager();
然后利用atManager来执行检查是否拥有权限:
checkAccessToken:
checkAccessToken(tokenID: number, permissionName: Permissions): Promise<GrantStatus>
校验应用是否授予权限。使用Promise异步回调。
参数说明:
参数名 | 类型 | 必填 | 说明 |
tokenID | number | 是 | 要校验的目标应用的身份标识。可通过应用的ApplicationInfo获得。 |
permissionName | Permissions | 是 | 需要校验的权限名称,合法的权限名取值可在系统权限定义列表中查询。 |
完整代码如下
- async function checkAccessToken(permission: Permissions): Promise<abilityAccessCtrl.GrantStatus> {
- let atManager = abilityAccessCtrl.createAtManager();
- let grantStatus: abilityAccessCtrl.GrantStatus;
-
- // 获取应用程序的accessTokenID
- let tokenId: number;
- try {
- let bundleInfo: bundleManager.BundleInfo = await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
- let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo;
- tokenId = appInfo.accessTokenId;
- } catch (err) {
- console.error(`getBundleInfoForSelf failed, code is ${err.code}, message is ${err.message}`);
- }
-
- // 校验应用是否被授予权限
- try {
- grantStatus = await atManager.checkAccessToken(tokenId, permission);
- } catch (err) {
- console.error(`checkAccessToken failed, code is ${err.code}, message is ${err.message}`);
- }
-
- return grantStatus;
- }
-
- async function checkPermissions(): Promise<void> {
- const permissions: Array<Permissions> = ['ohos.permission.READ_CALENDAR'];
- let grantStatus: abilityAccessCtrl.GrantStatus = await checkAccessToken(permissions[0]);
-
- if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
- // 已经授权,可以继续访问目标操作
- AlertDialog.show(
- {
- title: '消息',
- message: '权限已经授权',
- autoCancel: true,
- alignment: DialogAlignment.Bottom,
- }
- )
- } else {
- // 没有被授权
- AlertDialog.show(
- {
- title: '消息',
- message: '权限没有被授予',
- autoCancel: true,
- alignment: DialogAlignment.Bottom,
- }
- )
- }
- }

该代码块中,拥有两个函数checkAccessToken、checkPermissions,其中checkAccessToken用来获取abilityAccessCtrl.GrantStatus类型对象。checkPermissions函数调用checkAccessToken获取abilityAccessCtrl.GrantStatus类型对象后,通过该类型对象进行判定设备是否拥有权限。
我将上述的代码绑定到检查权限按钮之后,点击按钮后将会出现以下效果:
这是因为我只是检查是否拥有权限,还没去申请权限。
动态向用户申请权限是指在应用程序运行时向用户请求授权的过程。可以通过调用requestPermissionsFromUser()方法来实现。该方法接收一个权限列表参数,例如位置、日历、相机、麦克风等。用户可以选择授予权限或者拒绝授权。
接口说明:
requestPermissionsFromUser
requestPermissionsFromUser(context: Context, permissionList: Array<Permissions>, requestCallback: AsyncCallback<PermissionRequestResult>) : void;
用于UIAbility拉起弹框请求用户授权。使用callback异步回调。
模型约束:此接口仅可在Stage模型下使用。
参数说明:
参数名 | 类型 | 必填 | 说明 |
context | Context | 是 | 请求权限的UIAbility的UIAbilityContext。 |
permissionList | Array<Permissions> | 是 | 权限名列表,合法的权限名取值可在系统权限定义列表中查询。 |
callback | AsyncCallback<PermissionRequestResult> | 是 | 回调函数,返回接口调用是否成功的结果。 |
使用步骤:
与前面检查是否拥有权限类似:
首先导入模块和创建atManager:
- import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
- let atManager = abilityAccessCtrl.createAtManager();
利用atManager执行requestPermissionsFromUser方法:
完整代码如下
- function reqPermissionsFromUser(permissions: Array<Permissions>): void {
- let context = getContext(this) as common.UIAbilityContext;
- let atManager = abilityAccessCtrl.createAtManager();
- // requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
- 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) {
- // 用户授权,可以继续访问目标操作
- AlertDialog.show(
- {
- title: '消息',
- message: '用户手动授权成功',
- autoCancel: true,
- alignment: DialogAlignment.Bottom,
- }
- )
- } else {
- // 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限
- AlertDialog.show(
- {
- title: '消息',
- message: '用户拒绝授权',
- autoCancel: true,
- alignment: DialogAlignment.Bottom,
- }
- )
- return;
- }
- }
- // 授权成功
- }).catch((err) => {
- console.error(`requestPermissionsFromUser failed, code is ${err.code}, message is ${err.message}`);
- })
- }

将上述代码绑定到获取权限按钮后,点击将会出现一下效果,如图所示:
当我们将上述申请权限的方法理解之后,我们接下来将通过geoLocationManager模块进行对位置的获取。
import geoLocationManager from '@ohos.geoLocationManager';
这里我们使用geoLocationManager.getCurrentLocation来获取定位信息
geoLocationManager.getCurrentLocation
getCurrentLocation(request: CurrentLocationRequest, callback: AsyncCallback<Location>): void
获取当前位置,使用callback回调异步返回结果。
需要权限:ohos.permission.APPROXIMATELY_LOCATION
参数说明:
参数名 | 类型 | 必填 | 说明 |
request | 是 | 设置位置请求参数。 | |
callback | AsyncCallback<Location> | 是 | 用来接收位置信息的回调。 |
- let requestInfo = {'priority': 0x203, 'scenario': 0x300,'maxAccuracy': 0};
- let locationChange = (err, location) => {
- if (err) {
- console.log('locationChanger: err=' + JSON.stringify(err));
- }
- if (location) {
- console.log('locationChanger: location=' + JSON.stringify(location));
- AlertDialog.show(
- {
- title: '消息',
- message: '获取定位成功:' + JSON.stringify(location),
- autoCancel: true,
- alignment: DialogAlignment.Bottom,
- }
- )
- }

效果如图所示:
Location信息:
名称 | 类型 | 可读 | 可写 | 说明 |
latitude | number | 是 | 否 | 表示纬度信息,正值表示北纬,负值表示南纬。取值范围为-90到90。 |
longitude | number | 是 | 否 | 表示经度信息,正值表示东经,负值表是西经。取值范围为-180到180。 |
altitude | number | 是 | 否 | 表示高度信息,单位米。 |
accuracy | number | 是 | 否 | 表示精度信息,单位米。 |
speed | number | 是 | 否 | 表示速度信息,单位米每秒。 |
timeStamp | number | 是 | 否 | 表示位置时间戳,UTC格式。 |
direction | number | 是 | 否 | 表示航向信息。单位是“度”,取值范围为0到360。 |
timeSinceBoot | number | 是 | 否 | 表示位置时间戳,开机时间格式。 |
additions | Array<string> | 是 | 否 | 附加信息。 |
additionSize | number | 是 | 否 | 附加信息数量。取值范围为大于等于0。 |
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。