已开启应用的位置权限，但仍然提示未开启位置权限
=======================

#### 问题现象

已开启应用的位置权限，但实际无法获取当前位置且仍然提示未开启位置权限，跳转系统设置页后应用位置权限也都是开启的。

#### 背景知识

*   [Location Kit](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/location-kit-intro)：位置子系统使用多种定位技术提供服务，如GNSS定位、基站定位、WLAN/蓝牙定位（基站定位、WLAN/蓝牙定位后续统称“网络定位技术”）；通过这些定位技术，无论用户设备在室内或是户外，都可以准确地确定设备位置。
*   [向用户申请授权](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/request-user-authorization)：当应用需要访问用户的隐私信息或使用系统能力时，例如获取位置信息、访问日历、使用相机拍摄照片或录制视频等，应该向用户请求授权，这部分权限是user\_grant权限。
*   [geoLocationManager.isLocationEnabled](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-geolocationmanager#geolocationmanagerislocationenabled)：判断位置服务是否已经开启。可以通过此接口获取手机是否开启了位置服务。
*   [requestGlobalSwitch](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-abilityaccessctrl#requestglobalswitch12)：部分情况下，录音、拍照等功能禁用，应用可拉起此弹框请求用户同意开启对应功能。如果当前全局开关的状态为开启，则不拉起弹框。

#### 问题定位

1.  排查应用是否被授权了位置权限：在日志中全局搜索关键字“ohos.permission.LOCATION”、“ohos.permission.APPROXIMATELY\_LOCATION”，state为0，表示此应用已被授予ohos.permission.LOCATION、ohos.permission.APPROXIMATELY\_LOCATION这2个位置权限。
    
    07-22 12:00:48.108   3766-21737    C05A01/com.hm.example/ATM  com.hm.example  I     \[IsDynamicRequest:440\]Permission: ohos.permission.APPROXIMATELY\_LOCATION: state: 0, errorReason: 0
    07-22 12:00:48.108   3766-21737    C05A01/com.hm.example/ATM  com.hm.example  I     \[IsDynamicRequest:440\]Permission: ohos.permission.LOCATION: state: 0, errorReason: 0
    
2.  排查设备是否开启了位置服务：在日志中全局搜索关键字“location switch”，可以看到以下相关日志，表明设备的位置服务未开启。
    
    07-22 15:52:56.840   35263-35311   C02300/locationhub/Locator      locationhub           E     \[(ReportLocationStatus:1217)\]ReportLocationStatus line:1217 location switch is off
    07-22 15:52:56.861   35263-50703   C02300/locationhub/Locator      locationhub           E     \[(AddRequestToWorkRecord:508)\]AddRequestToWorkRecord line:508 the location switch is off
    

#### 分析结论

设备的位置服务未开启，导致应用虽然被授权了位置权限，但仍然获取不到位置信息。

#### 修改建议

1.  在获取到位置权限后，实际定位前，调用[geoLocationManager.isLocationEnabled](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-geolocationmanager#geolocationmanagerislocationenabled)查询系统位置服务开关状态。
2.  若系统位置服务开关未开启，调用[requestGlobalSwitch](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-abilityaccessctrl#requestglobalswitch12)接口向用户请求开启位置服务。

全量代码如下：

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/dd/v3/BYgu2r--SL2PuyYPi4jjvQ/notice_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260709T134319Z&HW-CC-Expire=86400&HW-CC-Sign=2DDBDF7074101F520B5D7BDE0D992AE43579BF3C17F5F32A3C845B5D552B0392)

参考[声明权限](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/declare-permissions)文档，需要先在module.json5文件中声明ohos.permission.APPROXIMATELY\_LOCATION和ohos.permission.LOCATION权限。

import { geoLocationManager } from '@kit.LocationKit';
import { abilityAccessCtrl, common, Permissions } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct Index {
  context = this.getUIContext().getHostContext() as common.UIAbilityContext;

  requestPermission() {
    try {
      _// 1、查询是否开启位置服务_
      let locationEnabled = geoLocationManager.isLocationEnabled();
      if (locationEnabled) {
       _ // 2.1、位置服务开启则申请位置相关授权_
        let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
        let permissions: Array<Permissions> = \['ohos.permission.LOCATION', 'ohos.permission.APPROXIMATELY\_LOCATION'\];
        _// requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗。_
        atManager.requestPermissionsFromUser(this.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}\`);
        });
      } else {
       _ // 2.2、位置服务未开启则弹窗请求用户开启位置服务_
        let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();

        atManager.requestGlobalSwitch(this.context, abilityAccessCtrl.SwitchType.LOCATION)
          .then((data: Boolean) => {
            console.info(\`requestGlobalSwitch data: ${data}\`);
            _// 返回false表示位置服务未开启，系统会自动弹窗请求用户开启位置服务_
          })
          .catch((err: BusinessError) => {
            console.error(\`requestGlobalSwitch err.code: ${err.code}, err.message: ${err.message}\`);
          });
      }
    } catch (err) {
      console.error(\`geoLocationManager.isLocationEnabled failed err.code: ${err.code}, err.message: ${err.message}\`);
    }
  }

  build() {
    Column() {
      Button('开启定位')
        .type(ButtonType.ROUNDED\_RECTANGLE)
        .backgroundColor('#0a59f7')
        .onClick(() => {
          this.requestPermission();
        });
    }
    .justifyContent(FlexAlign.Center)
    .height('100%')
    .width('100%');
  }
}