文档开发者中心
我的
|

HarmonyOS 5

配置了定位权限, 但是没有生效,但是在本地测试是可以定位的, 上线的版本不行,

已解决
配置了定位权限,  但是没有生效,但是在本地测试是可以定位的,   上线的版本不行,cke_929.png
点赞
收藏
回复
5
分享
举报
浏览233 发布于2025-08-20 02:55湖北
全部评论
最多点赞
最新发布
最早发布
|
采纳答复

楼主没有申请ohos.permission.LOCATION和ohos.permission.APPROXIMATELY_LOCATION权限,或者缺少了后台定位权限ohos.permission.LOCATION_IN_BACKGROUND,同时上线版本在运行时要动态请求权限

module.json5权限声明

收起
自动换行
深色代码主题
复制
{

  "module": {

    "requestPermissions": [

      {

        "name": "ohos.permission.LOCATION",

        "reason": "需要获取精确位置以提供服务"

      },

      {

        "name": "ohos.permission.APPROXIMATELY_LOCATION",

        "reason": "需要获取模糊位置以提供服务"

      },

      // 后台定位需添加

      {

        "name": "ohos.permission.LOCATION_IN_BACKGROUND",

        "reason": "后台持续获取位置"

      }

    ]

  }

}

动态权限申请

收起
自动换行
深色代码主题
复制
import abilityAccessCtrl, { Permissions } from '@kit.AbilityKit';

async function requestLocationPermissions() {

  const permissions: Permissions = [

    'ohos.permission.LOCATION', 

    'ohos.permission.APPROXIMATELY_LOCATION'

  ];

  

  const atManager = abilityAccessCtrl.createAtManager();

  const result = await atManager.requestPermissionsFromUser(

    getContext() as common.UIAbilityContext, 

    permissions

  );

  if (result.authResults.some(status => status !== 0)) {

    // 引导用户前往设置页开启权限

    promptAction.showToast({ message: '请前往设置开启定位权限' });

  }

}
展开全部
3楼回复于2025-08-21 02:12 来自河北
根据描述应用启动后未出现权限申请弹窗的提示,app未获得位置权限,可能是权限申请的代码逻辑存在问题。已发示例,可以参考。权限验证和申请可以放在EntryAbility.ets,在应用启动时申请权限​​​​​​​
收起
自动换行
深色代码主题
复制
import { abilityAccessCtrl, common, Permissions } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { promptAction } from '@kit.ArkUI';

//应用启动时验证权限及首次申请权限
function requestPermission(context: common.UIAbilityContext,
  permissionResult: (allow: boolean) => void): void {
  let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
  // requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
  let permissions: Array<Permissions> = ['ohos.permission.APPROXIMATELY_LOCATION','ohos.permission.LOCATION'];
  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) {
        // 用户授权,可以继续访问目标操作
        permissionResult(true);
      } else {
        // 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限
        promptAction.showDialog({
          title: '温馨提示',
          message: '用户必须授权才能访问当前页面的功能',
          alignment: DialogAlignment.Center,
          buttons: [
            { text: '取消', color: '#666666' },
            { text: '确认', color: '#666666' }
          ]
        }).then((res) => {
          if (res.index === 1) {
            //点击确认调用二次申请方法
            requestNextPermission(context, () => {
            })
          }
        })
        permissionResult(false);
        return;
      }
    }
    // 授权成功
  }).catch((err: BusinessError) => {
    permissionResult(false);
    console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
  })
}

//二次申请权限
function requestNextPermission(context: common.UIAbilityContext,
  permissionResult: (allow: boolean) => void): void {
  let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
  // requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
  let permissions: Array<Permissions> = ['ohos.permission.APPROXIMATELY_LOCATION','ohos.permission.LOCATION'];
  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({message:'您已授权'})
      } else {
        // 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限
        permissionResult(false);
        atManager.requestPermissionOnSetting(context, ['ohos.permission.APPROXIMATELY_LOCATION','ohos.permission.LOCATION'])
          .then((data: Array<abilityAccessCtrl.GrantStatus>) => {
            console.info('data:' + data.toString());
          })
          .catch((err: BusinessError) => {
            console.error('data:' + err.message);
          });
        return;
      }
    }
    // 授权成功
  }).catch((err: BusinessError) => {
    permissionResult(false);
    console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
  })
}


@Entry
@Component
struct Index {
  @State message: string = 'Hello World'

aboutToAppear(): void {
  requestPermission(getContext(this) as common.UIAbilityContext, () => {
  });
}

  build() {
    Row() {
      Column() {
        Button('二次授权').onClick(() => {
          console.info('二次授权')
          requestNextPermission(getContext(this) as common.UIAbilityContext, () => {
          });
        })
      }
      .height('100%')
      .width('100%')
      .justifyContent(FlexAlign.Center)
    }
  }
}
展开全部
1
1楼回复于2025-08-20 02:56 来自湖北
  • 重启试试君
    感谢楼主的分享,内容很有价值!希望以后还能看到更多这样的好帖!
    2025-08-21 00:57 来自广东

【背景知识】

应用权限申请:在HarmonyOS开发中,应用访问如相机、麦克风、位置、图库等系统资源或系统能力时,需通过系统Picker、安全控件、授权使用等方式来访问,以确保用户隐私安全。

【参考方案】

可参考考勤打卡位置获取示例,通过动态申请权限实现利用位置服务进行考勤打卡的效果。

  1. 校验应用是否被授权。
    收起
    自动换行
    深色代码主题
    复制
      async checkPermissions(permissions: Array<Permissions>) {
    
        for (let permission of permissions) {
    
          let grantStatus: abilityAccessCtrl.GrantStatus = await this.checkAccessToken(permission);
    
          if (grantStatus !== abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
    
            return false;
    
          }
    
        }
    
        return true;
    
      }
    
    
    
      async checkAccessToken(permission: Permissions): Promise<abilityAccessCtrl.GrantStatus> {
    
        let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
    
        let grantStatus: abilityAccessCtrl.GrantStatus = abilityAccessCtrl.GrantStatus.PERMISSION_DENIED;
    
    
    
        // 获取应用程序的accessTokenID
    
        let tokenId: number = 0;
    
        try {
    
          let bundleInfo: bundleManager.BundleInfo =
    
            await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
    
          let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo;
    
          tokenId = appInfo.accessTokenId;
    
          grantStatus = await atManager.checkAccessToken(tokenId, permission);
    
        } catch (error) {
    
          let err: BusinessError = error as BusinessError;
    
          hilog.error(0x000, 'testTag', `Failed to check access token  ${err.code}, message is ${err.message}`);
    
        }
    
        return grantStatus;
    
      }

  2. 第一次弹窗申请用户授权。
    收起
    自动换行
    深色代码主题
    复制
      async requestPermissions(context: UIContext, permissions: Array<Permissions>): Promise<boolean | undefined> {
    
        let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
    
        try {
    
          let data =
    
            await atManager.requestPermissionsFromUser(context.getHostContext() as common.UIAbilityContext, permissions)
    
          hilog.info(0x000, 'testTag', 'requestPermissions1 success', JSON.stringify(data))
    
          return data.dialogShownResults ? data.dialogShownResults[0] : undefined; // 返回请求是否有弹窗
    
        } catch (e) {
    
          hilog.error(0x000, 'testTag', `requestPermissions1 err Code is ${e.code}, message is ${e.message}`);
    
          return undefined;
    
        }
    
      }

  3. 第二次半模态设置页面申请用户授权。
    收起
    自动换行
    深色代码主题
    复制
     requestPermissionsOnSetting(context: UIContext, permissions: Array<Permissions>) {
    
        let keyPerms = JSON.stringify(permissions)
    
        let store = preferences.getPreferencesSync(context.getHostContext(), { name: 'permsHasOnSetting' });
    
        if (!store.hasSync(keyPerms)) {
    
          let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
    
          atManager.requestPermissionOnSetting(context.getHostContext(), permissions)
    
            .then((res: Array<abilityAccessCtrl.GrantStatus>) => {
    
              hilog.info(0x000, 'testTag', 'requestPermissions2 success', JSON.stringify(res))
    
              store.putSync(keyPerms, 1);
    
              store.flush()
    
            })
    
            .catch((err: BusinessError) => {
    
              hilog.info(0x000, 'testTag', 'requestPermissions2 err', JSON.stringify(err))
    
            })
    
        }
    
      }

  4. 第三次直接跳转至设置相关权限页面申请用户授权。
    收起
    自动换行
    深色代码主题
    复制
    export function openPermissionsInSystemSettings(context: common.UIAbilityContext, bundleName: string): void {
    
      let wantInfo: Want = {
    
        bundleName: 'com.huawei.hmos.settings',
    
        abilityName: 'com.huawei.hmos.settings.MainAbility',
    
        uri: 'application_info_entry',
    
        parameters: {
    
          settingsParamBundleName: bundleName
    
        }
    
      }
    
      context.startAbility(wantInfo)
    
    }

展开全部
4楼回复于2025-08-25 01:30 来自广东
示例代码我跑了一下是可以正常授权的,问一下,你线上版本之前能正常定位不,是不是应用升级了定位权限失效的。

那个context应该已经改了,你看下官网,都是this.getUIContext().getHostContext() 的方式获取context。

这个里面有完整代码:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/request-user-authorization#

2楼回复于2025-08-20 07:57 来自湖北
写回答
新增插入模板功能
一键使用模板,快速填写内容,轻松发帖~
知道了
  • 为了保障您的信息安全,请勿上传您的敏感个人信息(如您的密码等信息)和您的敏感资产信息(如关键源代码、签名私钥、调试安装包、业务日志等信息),且您需自行承担由此产生的信息泄露等安全风险。
  • 如您发布的内容为转载内容,请注明内容来源。

我要提问题

了解社区公约,与您携手共创和谐专业的开发者社区。