赞
踩
获取Wifi列表:
扫描(这个方法早在Android 9.0 就被弃用),不过如果不调用的话是没法及时获取Wifi列表的广播的。(不需要也能正常获取,没有延迟,经实验毫无区别)
- public static void searchWifiList(WifiManager manager) {
- manager.startScan();
- }
创建广播并接收:
- /**
- * 获取附近的WiFi列表
- *
- * @param manager WifiManager
- * @param flag 是否保留重名但BSSID不同的wifi true保留,false不保留
- * @return wifi列表
- */
- public static List<ScanResult> scanResults(WifiManager manager, boolean flag) {
- List<ScanResult> scanResults = new ArrayList<>();
- HashSet<String> 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;
- }
- }
- }
- };
配置并连接(无系统签名):
- /**
- * 创建连接
- * @param manager WifiManager
- * @param ssid Wifi名称
- * @param bssid 唯一标识(可以为空)
- * @param passwd 密码 (当前网络是开放网络时,可以为空)
- * @param isHidden 是否是隐藏网络
- * @param capabilities 安全协议(根据协议选择连接方式)
- */
- @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<WifiNetworkSuggestion> 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<WifiNetworkSuggestion> 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;
-
- }
配置并连接(有系统签名):
- /**
- * 连接wifi
- *
- * @param manager WifiManager
- * @param configuration Wifi配置
- * @return 是否连接成功
- */
- 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;
- }
-
- /**
- * 创建Wifi配置
- *
- * @param SSID wifi名称
- * @param password wifi密码
- * @param hidden 网络是否隐藏(该方法与添加隐藏网络通用)
- * @param capabilities 网络安全协议
- * @return 配置好的wifi
- */
- 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;
- }
-
- /**
- * 设置wpa3协议
- *
- * @param configuration 配置
- * @param password 密码
- */
- 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 + "\"";
- }
-
- /**
- * WPA协议
- *
- * @param configuration 配置
- * @param 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);
- }
-
- /**
- * WEP协议
- *
- * @param configuration 配置
- * @param password 密码
- */
- 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);
- }
-
-
- /**
- * 无密码
- *
- * @param configuration 配置
- */
- public static void setESS(WifiConfiguration configuration) {
- configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
- }
断开连接(无系统签名):
- //Android11及以上可以使用,清除建议列表,可以断开当前的网络
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
- List<WifiNetworkSuggestion> 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):
步骤如下——
1、在/data目录下创建一个文本,用来标识Wifi是打开或者关闭状态,比如:
文本文件名字:node
内容:0 // (0是关,1是开)
2、chmod 666 /data/node (赋予该文件的读写权限)
3、创建循环检测该文件内容的脚本,并针对内容执行adb命令
- adb shell svc wifi enable // 开启WIFI
- adb shell svc wifi disable // 关闭WIFI
4、应用端(App)对该文本进行读写
即可实现不需系统签名也可控制WIFI模块的开关
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。