动态申请后台位置权限失败该如何处理
=================

#### 问题现象

按如下截图方式申请后台位置权限时，未弹出授权窗口，导致无法获取位置信息。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/d0/v3/qWqXon8kQH2Zys2VXT9qgg/zh-cn_image_0000002658913749.png?HW-CC-KV=V1&HW-CC-Date=20260709T134320Z&HW-CC-Expire=86400&HW-CC-Sign=456152DB5BAAF7BE4CE24815DE5389550542BA46AF0C2C122DE802038A692FE7 "点击放大")

#### 背景知识

系统提供的定位权限有：

*   ohos.permission.LOCATION：用于获取[精准位置](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/permissions-for-all-user#ohospermissionlocation)，精准度在米级别。
*   ohos.permission.APPROXIMATELY\_LOCATION：用于获取[模糊位置](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/permissions-for-all-user#ohospermissionapproximately_location)，精确度为5公里。
*   ohos.permission.LOCATION\_IN\_BACKGROUND：用于[后台获取位置](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/permissions-for-all-user#ohospermissionlocation_in_background)，应用切换到后台仍然需要获取定位信息的场景。

由于安全隐私要求，应用不能通过弹窗的形式被授予后台位置权限，应用如果需要使用后台位置权限，需要引导用户到设置界面手动授予。

#### 解决方案

1.  当APP运行在前台，且需要访问设备位置信息时，需要向用户获取位置授权。
    
    import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
    import common from '@ohos.app.ability.common';
    import { BusinessError } from '@ohos.base';
    
    @Entry
    @Component
    struct locationTest {
      private permissions: Array<Permissions\> = \[
        'ohos.permission.APPROXIMATELY\_LOCATION',
        'ohos.permission.LOCATION'
      \];
    
      reqPermissionsFromUser(permissions: Array<Permissions\>, context: common.UIAbilityContext): void {
        const atManager: abilityAccessCtrl.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) {
              _//_ _用户授权，可以继续访问目标操作_
            } else {
            _  // 用户拒绝授权，提示用户必须授权才能访问当前页面的功能，并引导用户到系统设置中打开相应的权限_
              return;
            }
          }
          _// 授权成功_
        }).catch((err: BusinessError) \=\> {
          console.error(\`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}\`);
        });
      }
    
      aboutToAppear() {
        const context: common.UIAbilityContext \= this.getUIContext().getHostContext() as common.UIAbilityContext;
        this.reqPermissionsFromUser(this.permissions, context);
      }
    
      build() {
        Text('申请位置权限')
      }
    }
    
    效果预览：
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/ac/v3/5UW4MABjShKywA8dluzgMQ/zh-cn_image_0000002658793803.png?HW-CC-KV=V1&HW-CC-Date=20260709T134320Z&HW-CC-Expire=86400&HW-CC-Sign=078D78CB1AF2FD87848470F5970E909DA038449C2AD561A67663A4DDA2C63807 "点击放大")
    
2.  当用户点击弹窗授予前台位置权限后，如果APP运行到后台时也需要获取用户的位置信息，应用可以通过弹窗、提示窗等形式告知用户前往设置界面授予后台位置权限，在设置界面中将位置信息访问权限设置为**始终允许**，点击**确认按钮**，调用openPermissionsInSystemSettings()方法跳转到应用设置界面。
    
    效果预览：
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/74/v3/RxyskwLRQEmWMbKr6xfwRg/zh-cn_image_0000002628394532.png?HW-CC-KV=V1&HW-CC-Date=20260709T134320Z&HW-CC-Expire=86400&HW-CC-Sign=DADF0245EB185C354FF53D668A2F56B31584F3521917B48E9400419F31182B9D "点击放大")
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/b5/v3/ci8syeIOT4meD3pJZQzRug/zh-cn_image_0000002628554426.png?HW-CC-KV=V1&HW-CC-Date=20260709T134320Z&HW-CC-Expire=86400&HW-CC-Sign=918C4B39720B05952C4205C49CDEDDA80FE34693A8BE6BADE0AC4AB9364A3DE4 "点击放大")
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/88/v3/JfoqW2ykSaq6M_qHxQYV6A/zh-cn_image_0000002658913751.png?HW-CC-KV=V1&HW-CC-Date=20260709T134320Z&HW-CC-Expire=86400&HW-CC-Sign=F18E9903D6D7FCF9482FC862296F65F14FC1F67469B7203E26DDA1E17634D934 "点击放大")
    
    import { AlertDialog } from '@kit.ArkUI';
    import common from '@ohos.app.ability.common';
    import { Want } from '@kit.AbilityKit';
    
    @Entry
    @Component
    struct locationTest2 {
      private dialogControllerConfirm: CustomDialogController \= new CustomDialogController({
        builder: AlertDialog({
          primaryTitle: '温馨提示',
          content: '为了保证正常导航，需要将位置信息访问权限设置为【始终允许】',
          primaryButton: {
            value: '取消',
            action: () \=\> {
           _   // 取消逻辑_
            },
          },
          secondaryButton: {
            value: '确认',
            role: ButtonRole.ERROR,
            action: () \=\> {
              this.openPermissionsInSystemSettings();
            }
          },
        }),
      });
    
      openPermissionsInSystemSettings(): void {
        let wantInfo: Want \= {
          bundleName: 'com.huawei.hmos.settings',
          abilityName: 'com.huawei.hmos.settings.MainAbility',
          uri: 'application\_info\_entry',
          parameters: {
            settingsParamBundleName: 'com.huawei.locationTest' _//_ _打开指定应用的详情页面_
          }
        };
        const context: common.UIAbilityContext \= this.getUIContext().getHostContext() as common.UIAbilityContext;
        context.startAbility(wantInfo).then(() \=\> {
          _//_ _打开成功_
        }).catch(() \=\> {
         _ // 异常处理_
        });
      }
    
      build() {
        Button('跳转位置设置页面')
          .onClick(() \=\> {
            this.dialogControllerConfirm.open();
          })
      }
    }
    
    注：在entry模块的module.json5，需要将后台位置权限配置进去，位置信息访问权限设置界面才会看到**始终允许**的选项。
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/df/v3/liCMXqvbRbG49FwgKYTUmw/zh-cn_image_0000002658793805.png?HW-CC-KV=V1&HW-CC-Date=20260709T134320Z&HW-CC-Expire=86400&HW-CC-Sign=6E5E1D4D92ABCCB2B182335158B90D18844404F210615E2A1846007C6F540F51 "点击放大")
    

#### 总结

申请后台位置权限，除了要配置ohos.permission.LOCATION\_IN\_BACKGROUND权限到entry模块的module.json5文件中，还需要引导用户去应用设置界面设置位置权限为**始终允许**才能生效。