Android 12 Wifi 开发(获取列表、连接、断开连接)
获取Wifi列表:
扫描(这个方法早在Android 9.0 就被弃用),不过如果不调用的话是没法及时获取Wifi列表的广播的。(不需要也能正常获取,没有延迟,经实验毫无区别)
public static void searchWifiList(WifiManager manager) { manager.startScan();}
创建广播并接收:
public static List scanResults(WifiManager manager, boolean flag) { List scanResults = new ArrayList<>(); HashSet hs = new HashSet<>(); Log.d("WifiUtils", "scanResults: " + manager.getScanResults().size()); if (flag) { scanResults = manager.getScanResults(); return scanResults; } for (ScanResult scanResult : manager.getScanResults()) { if (hs.add(scanResult.SSID)) { scanResults.add(scanResult); } } return scanResults; }
private final BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { Log.d("WifiFragment", "onReceive: 刷新数据"); results = WifiUtils.scanResults(manager, true); mainBinding.scanResult.getAdapter().notifyDataSetChanged(); } else if (intent.getAction().equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 0); switch (wifiState) { case WifiManager.WIFI_STATE_DISABLED: Log.d("WifiFragment", "onReceive: wifi 关闭"); mainBinding.switchWifi.setText("已停用"); results = new ArrayList<>(); mainBinding.scanResult.getAdapter().notifyDataSetChanged(); break; case WifiManager.WIFI_STATE_DISABLING: case WifiManager.WIFI_STATE_ENABLING: case WifiManager.WIFI_STATE_UNKNOWN: break; case WifiManager.WIFI_STATE_ENABLED: Log.d("WifiFragment", "onReceive: wifi 打开"); mainBinding.switchWifi.setText("已启用"); break; } } } };
配置并连接(无系统签名):
@RequiresApi(api = Build.VERSION_CODES.Q) public static void connectWifiForQ(WifiManager manager, String ssid, String bssid, String passwd, boolean isHidden, String capabilities) { if (capabilities.contains("WPA-PSK") || capabilities.contains("WPA2-PSK")) { setWPA2ForQ(manager, ssid, bssid, passwd, isHidden); } else { setESSForQ(manager, ssid, isHidden); } } // WPA2-PSK @RequiresApi(api = Build.VERSION_CODES.Q) public static int setWPA2ForQ(WifiManager manager, String ssid, String bssid, String passwd, boolean isHidden) { WifiNetworkSuggestion suggestion; if (bssid == null) { suggestion= new WifiNetworkSuggestion.Builder() .setSsid(ssid) .setWpa2Passphrase(passwd) .setIsHiddenSsid(isHidden) .build(); } else { suggestion= new WifiNetworkSuggestion.Builder() .setSsid(ssid) .setBssid(MacAddress.fromString(bssid)) .setWpa2Passphrase(passwd) .setIsHiddenSsid(isHidden) .build(); } List suggestions = new ArrayList<>(); suggestions.add(suggestion); int status = manager.addNetworkSuggestions(suggestions); if (status != WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) { // 连接失败 Log.d("WifiUtils", "setWPA2ForQ: 添加失败"); } else { Log.d("WifiUtils", "setWPA2ForQ: 添加成功"); } return status; } // ESS @RequiresApi(api = Build.VERSION_CODES.Q) public static int setESSForQ(WifiManager manager, String ssid, boolean isHidden) { WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() .setSsid(ssid) .setIsHiddenSsid(isHidden) .build(); List suggestions = new ArrayList<>(); suggestions.add(suggestion); int status = manager.addNetworkSuggestions(suggestions); if (status != WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) { // 连接失败 Log.d("WifiUtils", "setWPA2ForQ: 添加失败"); } else { Log.d("WifiUtils", "setWPA2ForQ: 添加成功"); } return status; }
配置并连接(有系统签名):
public static boolean connectWifi(WifiManager manager, WifiConfiguration configuration) { int id = manager.addNetwork(configuration); WifiInfo connectionInfo = manager.getConnectionInfo(); manager.disableNetwork(connectionInfo.getNetworkId()); boolean b = manager.enableNetwork(id, true); Log.d("WifiManagerUtils", "connectWifi: 连接状态=" + b); if (b) { manager.saveConfiguration(); } else { Log.d("WifiManagerUtils", configuration.toString()); } return b; } public static WifiConfiguration createWifiInfo(String SSID, String password, boolean hidden, String capabilities) { WifiConfiguration configuration = new WifiConfiguration(); configuration.SSID = "\"" + SSID + "\""; if (hidden) { configuration.hiddenSSID = true; } Log.d("WifiManagerUtils", "createWifiInfo: " + capabilities); if (capabilities.contains("SAE") && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { setWPA3(configuration, password); } else if (capabilities.contains("WPA-PSK") || capabilities.contains("WPA2-PSK")) { setWPA(configuration, password); } else if (capabilities.contains("WEP")) { setWEP(configuration, password); } else { setESS(configuration); } return configuration; } public static void setWPA3(WifiConfiguration configuration, String password) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SAE); } configuration.preSharedKey = "\"" + password + "\""; } public static void setWPA(WifiConfiguration configuration, String password) { configuration.preSharedKey = "\"" + password + "\""; //公认的IEEE 802.11验证算法。 configuration.allowedAuthAlgorithms.clear(); configuration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN); //公认的的公共组密码。 configuration.allowedGroupCiphers.clear(); configuration.allowedGroupCiphers.set(WifiConfiguration.PairwiseCipher.CCMP); configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP); //公认的密钥管理方案。 configuration.allowedKeyManagement.clear(); configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); //密码为WPA。 configuration.allowedPairwiseCiphers.clear(); configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP); configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP); //公认的安全协议。 configuration.allowedProtocols.clear(); configuration.allowedProtocols.set(WifiConfiguration.Protocol.RSN); } public static void setWEP(WifiConfiguration configuration, String password) { configuration.wepKeys[0] = "\"" + password + "\""; configuration.wepTxKeyIndex = 0; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40); } public static void setESS(WifiConfiguration configuration) { configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); }
断开连接(无系统签名):
//Android11及以上可以使用,清除建议列表,可以断开当前的网络 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { List networkSuggestions = wifiManager.getNetworkSuggestions(); wifiManager.removeNetworkSuggestions(networkSuggestions); }
监听连接状态:
//监听网络连接状态 connectivityManager.registerDefaultNetworkCallback(new ConnectivityManager.NetworkCallback(){ @Override public void onAvailable(@NonNull Network network) { super.onAvailable(network); Log.d("MainActivity", "onAvailable: 网络已连接"); Toast.makeText(MainActivity.this, "已连接网络", Toast.LENGTH_SHORT).show(); } @Override public void onUnavailable() { super.onUnavailable(); Log.d("MainActivity", "onUnavailable: 网络已断开"); Toast.makeText(MainActivity.this, "已断开网络", Toast.LENGTH_SHORT).show(); } });
注意事项:
断开当前Wifi后,再重新连接该Wifi,可能会出现无法连接的情况。
这种情况我是通过关闭Wifi后再重新打开解决的,但是对Wifi的开关控制要涉及到权限问题——
需要System权限,在Manifest中添加:
android:sharedUserId="android.uid.system"
然后需要系统签名,可在系统源码中获得。
不知道各位有没有什么好的解决方法。
项目地址:
有系统签名(推荐)——
https://github.com/Ouanu/WIFI_DEMOhttps://github.com/Ouanu/WIFI_DEMO无系统签名——
https://github.com/Ouanu/WifiDemohttps://github.com/Ouanu/WifiDemo
不需系统签名的方法(需要root):
步骤如下——
在/data目录下创建一个文本,用来标识Wifi是打开或者关闭状态,比如:
文本文件名字:node
内容:0 // (0是关,1是开)
chmod 666 /data/node (赋予该文件的读写权限)
创建循环检测该文件内容的脚本,并针对内容执行adb命令
adb shell svc wifi enable // 开启WIFIadb shell svc wifi disable // 关闭WIFI
应用端(App)对该文本进行读写
即可实现不需系统签名也可控制WIFI模块的开关
来源地址:https://blog.csdn.net/weixin_44917215/article/details/128609280
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341