HarmonyOS鸿蒙Next中请问一下为啥这段代码会弹两次位置的授权呢

HarmonyOS鸿蒙Next中请问一下为啥这段代码会弹两次位置的授权呢 请问一下 为啥这段代码会弹两次位置的授权呢 ? 需要怎么修改拒绝后不再弹位置授权


更多关于HarmonyOS鸿蒙Next中请问一下为啥这段代码会弹两次位置的授权呢的实战教程也可以访问 https://www.itying.com/category-93-b0.html

8 回复

从你贴的现象看,不是系统“随机弹两次”,而是你的代码流程里 触发了两次权限请求链路

你现在的逻辑大概率是:

LocationUtil.requestLocationPermissions()
  .then((grant) => {
    if (grant) {
       LocationUtil.getCurrentLocationEasy()
    }
  })

而在 HarmonyOS NEXT 里,常见会出现二次弹窗的原因有这几种(你这个大概率是第 1 种):


原因1: getCurrentLocationEasy() 内部又触发了一次权限校验(最常见)

很多封装工具类会这么写:

static async getCurrentLocationEasy() {
   let granted = await this.requestLocationPermissions()
   if (!granted) {
      return
   }

   return geoLocationManager.getCurrentLocation(...)
}

这样外层:

requestLocationPermissions()

已经弹一次。

然后你调用:

getCurrentLocationEasy()

它里面又执行:

requestLocationPermissions()

于是第二次弹。

这和你截图现象完全一致:

  • 第一次:标准授权卡片
  • 第二次:权限详情选择页(始终允许 / 本次允许 / 不允许)

这是重复请求导致系统进入更细粒度确认。


怎么改(推荐)

把权限申请和定位获取彻底拆开。

LocationUtil.ts

import abilityAccessCtrl from '@ohos.abilityAccessCtrl'
import geoLocationManager from '@ohos.geoLocationManager'

export class LocationUtil {
  static async requestLocationPermissions(): Promise<boolean> {
    let atManager = abilityAccessCtrl.createAtManager()

    let result = await atManager.requestPermissionsFromUser(
      getContext(),
      ['ohos.permission.APPROXIMATELY_LOCATION',
       'ohos.permission.LOCATION']
    )

    return result.authResults.every(item => item === 0)
  }

  static async getCurrentLocation() {
    return await geoLocationManager.getCurrentLocation()
  }
}

页面调用

async getUserLocation() {
  const grant = await LocationUtil.requestLocationPermissions()

  if (!grant) {
    console.info('用户拒绝授权')
    return
  }

  const location = await LocationUtil.getCurrentLocation()

  console.info(JSON.stringify(location))
}

这样只会弹一次。


原因2:你申请了两组定位权限

HarmonyOS 定位常见:

  • ohos.permission.LOCATION
  • ohos.permission.APPROXIMATELY_LOCATION

如果你分开 request:

requestPermissionsFromUser(['LOCATION'])
requestPermissionsFromUser(['APPROXIMATELY_LOCATION'])

也会弹两次。

应该一次性申请:

requestPermissionsFromUser([
  'ohos.permission.LOCATION',
  'ohos.permission.APPROXIMATELY_LOCATION'
])

“拒绝后不再弹”的正确做法

你需要先检查授权状态,不要每次都直接 request。

推荐写法

static async checkLocationPermission(): Promise<boolean> {
  let atManager = abilityAccessCtrl.createAtManager()

  let grantStatus = await atManager.checkAccessToken(
    getContext(),
    'ohos.permission.LOCATION'
  )

  return grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED
}

页面逻辑:

async getUserLocation() {
  const hasPermission = await LocationUtil.checkLocationPermission()

  if (!hasPermission) {
    const grant = await LocationUtil.requestLocationPermissions()

    if (!grant) {
      return // 用户拒绝,直接结束,不再继续弹
    }
  }

  const location = await LocationUtil.getCurrentLocation()
}

如果用户明确拒绝后,后续不要再弹

自己记录一次状态:

AppStorage.setOrCreate('locationDenied', false)

用户拒绝:

AppStorage.set('locationDenied', true)

下次:

if (AppStorage.get('locationDenied')) {
   // 提示去系统设置开启
   return
}

跳设置:

wantAgent / openLink('settings')

总结(你这个问题的直接结论)

你这段代码弹两次,**90% 是 ** LocationUtil.getCurrentLocationEasy() **内部再次调用了 ** requestLocationPermissions()

去检查这个方法,把里面的权限申请删掉,改成:

  • 外层只申请一次权限
  • 成功后直接调用纯定位接口
  • 拒绝后直接 return,不再递归申请

重点检查:

LocationUtil.getCurrentLocationEasy()

这个方法源码。

里面一定还有一次权限请求。

更多关于HarmonyOS鸿蒙Next中请问一下为啥这段代码会弹两次位置的授权呢的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


如图:
cke_1193.png

弹两次是因为 requestLocationPermissionsgetCurrentLocationEasy 各触发了一次权限弹窗(或两个位置权限各弹一次)。修复方式:先 checkAccessToken() 静默检查状态,已拒绝的直接 return 不再弹窗;只在确实未决定时才调 requestPermissionsFromUser(),且合并为一次请求。

你的代码中 requestLocationPermissions() 是你显式调用的,getCurrentLocationEasy() 底层的 geoLocationManager.getLocation() 也可能在发现权限不完整时自行发起请求。如有帮助给个采纳谢谢

看一下你的LocationUtil具体实现,肯定是这里出了问题

这里用的OpenHarmony三方库中心仓的插件pura/harmony-utils,我看他代码确实会有两次不同的请求,但是我很奇怪的是,我注释掉其中任意一个,这个授权弹窗都不弹了

这权限UI还不一样,是不是有其它代码触发了

应该是你的权限函数内部有二次授权,可以看一下权限函数的代码

在HarmonyOS NEXT中,位置授权弹出两次通常是因为同时请求了ohos.permission.LOCATION(粗略位置)与ohos.permission.APPROXIMATELY_LOCATION(精准位置)两项权限。系统会分别弹窗授权,导致两次弹框。另一常见原因是权限检查与请求流程未做去重处理。

定位权限弹两次通常是因为在页面生命周期(如aboutToAppear)和某个事件回调中重复调用了requestPermissionsFromUser,或者短时间内多次触发了同一权限请求。
可以在应用内持久化一个标记,当用户选择“拒绝”后设置为true,再次需要权限时先检查该标记,若已拒绝则不再发起系统授权弹窗,改为提示用户跳转系统设置手动开启。这样能避免重复打扰用户。

回到顶部