Android 31下无网WiFi与移动数据共存的程序化连接实现方法
API 31 下无提示连接无互联网WiFi并保留移动数据的实现方案
核心逻辑
Android 12(API 31)虽收紧了WiFi连接权限,但针对本地无互联网的设备网络(比如你的田间摄像头),可通过WifiNetworkSpecifier和ConnectivityManager的专属API实现静默连接,同时通过网络绑定机制让移动数据保持活跃。
具体实现步骤
1. 声明必要权限
在AndroidManifest.xml中添加以下权限:
<!-- WiFi扫描与状态权限 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <!-- API31+ 连接附近WiFi设备的权限 --> <uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" />
注:NEARBY_WIFI_DEVICES无需运行时请求,但WiFi扫描仍需动态申请ACCESS_FINE_LOCATION权限。
2. 构建无互联网WiFi的连接配置
使用WifiNetworkSpecifier.Builder创建目标WiFi的专属配置,核心是明确标记该网络无需互联网:
// 构建目标WiFi的连接规则 val wifiSpecifier = WifiNetworkSpecifier.Builder() .setSsid("你的摄像头WiFi名称") .setWpa2Passphrase("WiFi密码") // 开放网络可移除这一行 .setNetworkSelectionStatus( WifiNetworkSpecifier.NetworkSelectionStatus.Builder() .setNoInternetAccessExpected(true) // 关键:告知系统此网络无需互联网 .build() ) .build() // 构建网络请求 val networkRequest = NetworkRequest.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) .setNetworkSpecifier(wifiSpecifier) .build()
3. 发起静默连接并绑定应用到该网络
通过ConnectivityManager发起连接请求,监听连接状态,成功后将应用进程绑定到该WiFi网络:
val connectivityManager = requireContext().getSystemService(ConnectivityManager::class.java) val networkCallback = object : ConnectivityManager.NetworkCallback() { override fun onAvailable(network: Network) { // 连接成功后,将当前应用绑定到该WiFi网络 connectivityManager.bindProcessToNetwork(network) // 此处可启动摄像头图像获取逻辑 } override fun onUnavailable() { // 连接失败的处理逻辑(比如重试、提示用户) } } // 发起连接请求 connectivityManager.requestNetwork(networkRequest, networkCallback)
4. 保持移动数据活跃
bindProcessToNetwork仅将当前应用的网络请求定向到WiFi,系统其他应用仍可正常使用移动数据。若本应用需要部分请求走移动数据,可随时解除绑定:
// 解除绑定,应用恢复使用默认网络(移动数据) connectivityManager.bindProcessToNetwork(null)
5. 资源清理
在Fragment销毁时注销网络回调,避免内存泄漏:
override fun onDestroyView() { super.onDestroyView() connectivityManager.unregisterNetworkCallback(networkCallback) }
为什么同事的应用能实现?
他们大概率也是利用了WifiNetworkSpecifier的setNoInternetAccessExpected(true)配置——针对本地无互联网的设备网络,系统允许应用直接连接,无需用户弹窗确认,这类场景属于Android 12后放开的特殊权限范围。
内容的提问来源于stack exchange,提问作者ArchkWay
相关产品推荐
相关产品推荐

