You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 13调用WifiManager#startLocalOnlyHotspot遇权限异常

解决Android 13调用WifiManager#startLocalOnlyHotspot的SecurityException问题

问题分析

你遇到的SecurityException核心原因是:Android 13(API 33)及以上版本中,NEARBY_WIFI_DEVICES属于危险权限,仅在AndroidManifest.xml中声明静态权限无法让应用实际获取该权限,必须在运行时动态向用户申请授权。

解决步骤

1. 优化Manifest权限配置

你当前的权限声明已覆盖基础需求,可补充权限标记简化申请流程(若无需通过该权限获取位置信息):

<uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES"
    android:usesPermissionFlags="neverForLocation" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

2. 动态申请权限

在调用startLocalOnlyHotspot前,必须先完成权限申请。以下是基于ActivityResultContracts的实现示例:

// 在Activity/Fragment中注册权限请求回调
private val requestNearbyWifiPermission = registerForActivityResult(
    ActivityResultContracts.RequestPermission()
) { isGranted ->
    if (isGranted) {
        // 权限授予成功,执行热点启动逻辑
        launchLocalHotspot()
    } else {
        // 权限被拒绝,提示用户开启权限
        Toast.makeText(this, "需开启附近设备权限才能启动本地热点", Toast.LENGTH_SHORT).show()
    }
}

// 触发权限申请的入口方法
fun initHotspot() {
    if (ContextCompat.checkSelfPermission(
            this,
            Manifest.permission.NEARBY_WIFI_DEVICES
        ) != PackageManager.PERMISSION_GRANTED
    ) {
        requestNearbyWifiPermission.launch(Manifest.permission.NEARBY_WIFI_DEVICES)
    } else {
        // 已拥有权限,直接启动热点
        launchLocalHotspot()
    }
}

// 本地热点启动逻辑
private fun launchLocalHotspot() {
    val wifiManager = getSystemService(Context.WIFI_SERVICE) as WifiManager
    wifiManager.startLocalOnlyHotspot(object : WifiManager.LocalOnlyHotspotCallback() {
        override fun onStarted(reservation: WifiManager.LocalOnlyHotspotReservation?) {
            // 热点启动成功后的处理(如获取SSID、密码)
        }

        override fun onStopped() {
            // 热点停止后的处理
        }

        override fun onFailed(reason: Int) {
            // 热点启动失败的处理
        }
    }, Handler(Looper.getMainLooper()))
}

3. 关键注意事项

  • 必须在主线程中调用startLocalOnlyHotspot,否则会引发线程异常;
  • 若用户拒绝权限并勾选「不再询问」,需引导用户到应用设置页面手动开启权限。

内容的提问来源于stack exchange,提问作者Daniel Walker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 12:03:10