我正在开发 Wifi 自动连接功能,但令我震惊的是该 API 的损坏程度。
我现在正在使用 5 个不同的 API,但我仍然没有以用户期望的方式得到它。
我有一个设置可以在 Android 10+ 上启用 wifi 自动连接,我将尝试以下操作:
ACCESS_WIFI_STATE权限:
appOpsManager.unsafeCheckOp("android:change_wifi_state", Process.myUid(), context.packageName) == AppOpsManager.MODE_ALLOWED
Run Code Online (Sandbox Code Playgroud)
当我拥有许可时,我会继续执行 2。如果没有,我会继续执行 6。wifiManager.networkSuggestions.isNotEmpty()如果是这样的话)我检查我当前连接的 Wifi,请参阅步骤 x。在较低级别我会跳过此步骤并转到步骤 3WifiNetworkSuggestion.Builder()建议用户使用我的 wifi
val status = wifiManager.addNetworkSuggestions(listOf(suggestion))
// Strage bug: On first usage the return value is always SUCCESS
val success = status == WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS
Run Code Online (Sandbox Code Playgroud)
Settings.ACTION_WIFI_ADD_NETWORKS始终可以添加 Wifi 的意图(缺点是用户可以共享 wifi 密码)ACCESS_WIFI_STATE、ACCESS_NETWORK_STATE和ACCESS_COARSE_LOCATION的权限ACCESS_FINE_LOCATION。然而ConnectivityManagerAPI 并没有返回实际的SSID,这让我发疯。Settings.Panel.ACTION_WIFI操作让用户连接到正确的 wifi总结一下:
WifiNetworkSuggestionAPISettings.ACTION_WIFI_ADD_NETWORKS可能的地方Settings.Panel.ACTION_WIFI我尝试帮助用户通过该操作连接到正确的 wifi(甚至打开 wifi)这真的很混乱还是有更简单的方法?
我目前正在这样访问 SSID:
private val currentSsid: String?
get() =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
val wifiInfo = connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)?.transportInfo as? WifiInfo
wifiInfo?.ssid
} else {
wifiManager.connectionInfo?.ssid
}
Run Code Online (Sandbox Code Playgroud)
基于在 Android 12 中无法使用 onCapativityChanged 获取 WIFI SSID,我认为不支持我访问该值的方式。我目前得到的值"<unknown ssid>"。
嗯,只是一半的答案,但无论如何它可能会有所帮助。以下是我获取用户当前SSID的方法(需要持有位置权限):
fun updateSsid(networkCapabilities: NetworkCapabilities) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
currentSsid = (networkCapabilities.transportInfo as? WifiInfo)?.ssid?.trim('"')
}
}
wifiCallback = when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
object: ConnectivityManager.NetworkCallback(FLAG_INCLUDE_LOCATION_INFO) {
override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) {
updateSsid(networkCapabilities)
}
}
}
Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q -> {
object: ConnectivityManager.NetworkCallback() {
override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) {
updateSsid(networkCapabilities)
}
}
}
else -> null
}
wifiCallback?.let {
fragment.lifecycle.addObserver(object: DefaultLifecycleObserver {
override fun onResume(owner: LifecycleOwner) {
connectivityManager.registerNetworkCallback(request, it)
}
override fun onPause(owner: LifecycleOwner) {
connectivityManager.unregisterNetworkCallback(it)
}
})
}
Run Code Online (Sandbox Code Playgroud)
所以基本上你的代码的各个方面都需要检查 api 的级别 <10、10、11 和 12。真是一团糟。
如果您希望用户选择已配置的 wifi,这可能会非常方便:
fun showWifiDialog() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
try {
fragment.startActivity(Intent(android.provider.Settings.Panel.ACTION_WIFI))
} catch (e: Exception) {
// ignored
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1109 次 |
| 最近记录: |