鸿蒙定位功能开发指南【2】

2025-06-27 15:24:59
109次阅读
0个评论

第二篇:位置权限申请指南

权限类型说明

1. 模糊位置权限

  • 权限名称ohos.permission.APPROXIMATELY_LOCATION
  • 权限等级:normal级别
  • 权限描述:允许应用获取设备模糊位置信息
  • 精度范围:精确到公里级别

2. 精确位置权限

  • 权限名称ohos.permission.LOCATION
  • 权限等级:dangerous级别
  • 权限描述:允许应用获取设备精确位置信息
  • 精度范围:精确到米级别

权限申请策略

申请原则

  1. 最小权限原则:根据业务需求申请相应权限
  2. 渐进式申请:先申请模糊位置,需要时再申请精确位置
  3. 用户友好:在申请权限前向用户说明用途

权限申请时机

// 在需要使用位置功能时申请权限
async function checkAndRequestPermission() {
  let atManager = abilityAccessCtrl.createAtManager();
  
  // 检查是否已有权限
  try {
    let grantStatus = await atManager.checkAccessToken(
      tokenId, 'ohos.permission.APPROXIMATELY_LOCATION'
    );
    
    if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
      console.info('已有模糊位置权限');
      return true;
    } else {
      // 申请权限
      await requestLocationPermission();
    }
  } catch (err) {
    console.error('权限检查失败: ' + JSON.stringify(err));
  }
}

module.json5配置

基础配置

{
  "requestPermissions": [
    {
      "name": "ohos.permission.APPROXIMATELY_LOCATION",
      "reason": "$string:location_reason",
      "usedScene": {
        "abilities": ["EntryAbility"],
        "when": "inuse"
      }
    }
  ]
}

高精度定位配置

{
  "requestPermissions": [
    {
      "name": "ohos.permission.APPROXIMATELY_LOCATION",
      "reason": "$string:location_reason",
      "usedScene": {
        "abilities": ["EntryAbility"],
        "when": "inuse"
      }
    },
    {
      "name": "ohos.permission.LOCATION",
      "reason": "$string:precise_location_reason",
      "usedScene": {
        "abilities": ["EntryAbility"],
        "when": "inuse"
      }
    }
  ]
}

权限申请最佳实践

1. 权限说明文案

entry/src/main/resources/base/element/string.json中添加:

{
  "string": [
    {
      "name": "location_reason",
      "value": "用于获取您的位置信息,为您提供基于位置的服务"
    },
    {
      "name": "precise_location_reason", 
      "value": "用于获取您的精确位置信息,提供更准确的导航和定位服务"
    }
  ]
}

2. 动态权限申请

import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
import { BusinessError } from '@ohos.base';

@Entry
@Component
struct LocationPermissionPage {
  @State hasLocationPermission: boolean = false;

  async aboutToAppear() {
    await this.checkLocationPermission();
  }

  async checkLocationPermission() {
    let atManager = abilityAccessCtrl.createAtManager();
    let bundleInfo = await globalThis.context.getBundleInfo();
    
    try {
      let grantStatus = await atManager.checkAccessToken(
        bundleInfo.appId, 'ohos.permission.APPROXIMATELY_LOCATION'
      );
      
      this.hasLocationPermission = 
        grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED;
        
    } catch (err) {
      console.error('权限检查失败: ' + JSON.stringify(err));
    }
  }

  async requestLocationPermission() {
    let atManager = abilityAccessCtrl.createAtManager();
    let permissions: Array<Permissions> = [
      'ohos.permission.APPROXIMATELY_LOCATION'
    ];

    try {
      let data = await atManager.requestPermissionsFromUser(
        globalThis.context, permissions
      );
      
      if (data.authResults[0] === 0) {
        this.hasLocationPermission = true;
        console.info('位置权限申请成功');
      } else {
        console.info('位置权限申请被拒绝');
      }
    } catch (err) {
      console.error('权限申请异常: ' + JSON.stringify(err));
    }
  }

  build() {
    Column() {
      if (this.hasLocationPermission) {
        Text('已获得位置权限')
          .fontSize(16)
          .fontColor(Color.Green)
      } else {
        Column() {
          Text('需要获取位置权限才能使用此功能')
            .fontSize(14)
            .margin({ bottom: 16 })
          
          Button('申请位置权限')
            .onClick(() => {
              this.requestLocationPermission();
            })
        }
      }
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
    .padding(16)
  }
}

权限被拒绝的处理

引导用户手动开启

async function handlePermissionDenied() {
  // 显示对话框引导用户到设置页面开启权限
  AlertDialog.show({
    title: '权限提示',
    message: '位置权限被拒绝,请前往设置页面手动开启位置权限',
    primaryButton: {
      value: '去设置',
      action: () => {
        // 跳转到应用设置页面
        let context = globalThis.context;
        let bundleInfo = context.getBundleInfo();
        let want = {
          bundleName: 'com.huawei.hmos.settings',
          abilityName: 'com.huawei.hmos.settings.MainAbility',
          parameters: {
            pushParams: bundleInfo.name
          }
        };
        context.startAbility(want);
      }
    },
    secondaryButton: {
      value: '取消',
      action: () => {
        console.info('用户取消权限设置');
      }
    }
  });
}

注意事项

  1. 权限申请时机:在实际需要使用位置功能时申请,不要在应用启动时就申请
  2. 用户体验:申请权限前要向用户说明权限用途
  3. 权限降级:如果精确位置权限被拒绝,可以使用模糊位置权限
  4. 错误处理:要妥善处理权限被拒绝的情况
  5. 隐私保护:位置信息属于敏感数据,要做好数据保护

完整示例

查看完整的位置功能实现示例,请参考项目中的相关组件和页面实现。

收藏00

登录 后评论。没有帐号? 注册 一个。