当前位置:   article > 正文

Android 12 Wifi 开发(获取列表、连接、断开连接)_安卓wifi连接demo

安卓wifi连接demo

获取Wifi列表:

扫描(这个方法早在Android 9.0 就被弃用),不过如果不调用的话是没法及时获取Wifi列表的广播的。(不需要也能正常获取,没有延迟,经实验毫无区别)

  1. public static void searchWifiList(WifiManager manager) {
  2. manager.startScan();
  3. }

创建广播并接收:

  1. /**
  2. * 获取附近的WiFi列表
  3. *
  4. * @param manager WifiManager
  5. * @param flag 是否保留重名但BSSID不同的wifi true保留,false不保留
  6. * @return wifi列表
  7. */
  8. public static List<ScanResult> scanResults(WifiManager manager, boolean flag) {
  9. List<ScanResult> scanResults = new ArrayList<>();
  10. HashSet<String> hs = new HashSet<>();
  11. Log.d("WifiUtils", "scanResults: " + manager.getScanResults().size());
  12. if (flag) {
  13. scanResults = manager.getScanResults();
  14. return scanResults;
  15. }
  16. for (ScanResult scanResult : manager.getScanResults()) {
  17. if (hs.add(scanResult.SSID)) {
  18. scanResults.add(scanResult);
  19. }
  20. }
  21. return scanResults;
  22. }
  1. private final BroadcastReceiver receiver = new BroadcastReceiver() {
  2. @Override
  3. public void onReceive(Context context, Intent intent) {
  4. if (intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
  5. Log.d("WifiFragment", "onReceive: 刷新数据");
  6. results = WifiUtils.scanResults(manager, true);
  7. mainBinding.scanResult.getAdapter().notifyDataSetChanged();
  8. } else if (intent.getAction().equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
  9. int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 0);
  10. switch (wifiState) {
  11. case WifiManager.WIFI_STATE_DISABLED:
  12. Log.d("WifiFragment", "onReceive: wifi 关闭");
  13. mainBinding.switchWifi.setText("已停用");
  14. results = new ArrayList<>();
  15. mainBinding.scanResult.getAdapter().notifyDataSetChanged();
  16. break;
  17. case WifiManager.WIFI_STATE_DISABLING:
  18. case WifiManager.WIFI_STATE_ENABLING:
  19. case WifiManager.WIFI_STATE_UNKNOWN:
  20. break;
  21. case WifiManager.WIFI_STATE_ENABLED:
  22. Log.d("WifiFragment", "onReceive: wifi 打开");
  23. mainBinding.switchWifi.setText("已启用");
  24. break;
  25. }
  26. }
  27. }
  28. };

配置并连接(无系统签名):

  1. /**
  2. * 创建连接
  3. * @param manager WifiManager
  4. * @param ssid Wifi名称
  5. * @param bssid 唯一标识(可以为空)
  6. * @param passwd 密码 (当前网络是开放网络时,可以为空)
  7. * @param isHidden 是否是隐藏网络
  8. * @param capabilities 安全协议(根据协议选择连接方式)
  9. */
  10. @RequiresApi(api = Build.VERSION_CODES.Q)
  11. public static void connectWifiForQ(WifiManager manager, String ssid, String bssid, String passwd, boolean isHidden, String capabilities) {
  12. if (capabilities.contains("WPA-PSK") || capabilities.contains("WPA2-PSK")) {
  13. setWPA2ForQ(manager, ssid, bssid, passwd, isHidden);
  14. } else {
  15. setESSForQ(manager, ssid, isHidden);
  16. }
  17. }
  18. // WPA2-PSK
  19. @RequiresApi(api = Build.VERSION_CODES.Q)
  20. public static int setWPA2ForQ(WifiManager manager, String ssid, String bssid, String passwd, boolean isHidden) {
  21. WifiNetworkSuggestion suggestion;
  22. if (bssid == null) {
  23. suggestion= new WifiNetworkSuggestion.Builder()
  24. .setSsid(ssid)
  25. .setWpa2Passphrase(passwd)
  26. .setIsHiddenSsid(isHidden)
  27. .build();
  28. } else {
  29. suggestion= new WifiNetworkSuggestion.Builder()
  30. .setSsid(ssid)
  31. .setBssid(MacAddress.fromString(bssid))
  32. .setWpa2Passphrase(passwd)
  33. .setIsHiddenSsid(isHidden)
  34. .build();
  35. }
  36. List<WifiNetworkSuggestion> suggestions = new ArrayList<>();
  37. suggestions.add(suggestion);
  38. int status = manager.addNetworkSuggestions(suggestions);
  39. if (status != WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) {
  40. // 连接失败
  41. Log.d("WifiUtils", "setWPA2ForQ: 添加失败");
  42. } else {
  43. Log.d("WifiUtils", "setWPA2ForQ: 添加成功");
  44. }
  45. return status;
  46. }
  47. // ESS
  48. @RequiresApi(api = Build.VERSION_CODES.Q)
  49. public static int setESSForQ(WifiManager manager, String ssid, boolean isHidden) {
  50. WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
  51. .setSsid(ssid)
  52. .setIsHiddenSsid(isHidden)
  53. .build();
  54. List<WifiNetworkSuggestion> suggestions = new ArrayList<>();
  55. suggestions.add(suggestion);
  56. int status = manager.addNetworkSuggestions(suggestions);
  57. if (status != WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) {
  58. // 连接失败
  59. Log.d("WifiUtils", "setWPA2ForQ: 添加失败");
  60. } else {
  61. Log.d("WifiUtils", "setWPA2ForQ: 添加成功");
  62. }
  63. return status;
  64. }

配置并连接(有系统签名):

  1. /**
  2. * 连接wifi
  3. *
  4. * @param manager WifiManager
  5. * @param configuration Wifi配置
  6. * @return 是否连接成功
  7. */
  8. public static boolean connectWifi(WifiManager manager, WifiConfiguration configuration) {
  9. int id = manager.addNetwork(configuration);
  10. WifiInfo connectionInfo = manager.getConnectionInfo();
  11. manager.disableNetwork(connectionInfo.getNetworkId());
  12. boolean b = manager.enableNetwork(id, true);
  13. Log.d("WifiManagerUtils", "connectWifi: 连接状态=" + b);
  14. if (b) {
  15. manager.saveConfiguration();
  16. } else {
  17. Log.d("WifiManagerUtils", configuration.toString());
  18. }
  19. return b;
  20. }
  21. /**
  22. * 创建Wifi配置
  23. *
  24. * @param SSID wifi名称
  25. * @param password wifi密码
  26. * @param hidden 网络是否隐藏(该方法与添加隐藏网络通用)
  27. * @param capabilities 网络安全协议
  28. * @return 配置好的wifi
  29. */
  30. public static WifiConfiguration createWifiInfo(String SSID, String password, boolean hidden, String capabilities) {
  31. WifiConfiguration configuration = new WifiConfiguration();
  32. configuration.SSID = "\"" + SSID + "\"";
  33. if (hidden) {
  34. configuration.hiddenSSID = true;
  35. }
  36. Log.d("WifiManagerUtils", "createWifiInfo: " + capabilities);
  37. if (capabilities.contains("SAE") && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
  38. setWPA3(configuration, password);
  39. } else if (capabilities.contains("WPA-PSK") || capabilities.contains("WPA2-PSK")) {
  40. setWPA(configuration, password);
  41. } else if (capabilities.contains("WEP")) {
  42. setWEP(configuration, password);
  43. } else {
  44. setESS(configuration);
  45. }
  46. return configuration;
  47. }
  48. /**
  49. * 设置wpa3协议
  50. *
  51. * @param configuration 配置
  52. * @param password 密码
  53. */
  54. public static void setWPA3(WifiConfiguration configuration, String password) {
  55. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
  56. configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SAE);
  57. }
  58. configuration.preSharedKey = "\"" + password + "\"";
  59. }
  60. /**
  61. * WPA协议
  62. *
  63. * @param configuration 配置
  64. * @param password 密码
  65. */
  66. public static void setWPA(WifiConfiguration configuration, String password) {
  67. configuration.preSharedKey = "\"" + password + "\"";
  68. //公认的IEEE 802.11验证算法。
  69. configuration.allowedAuthAlgorithms.clear();
  70. configuration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
  71. //公认的的公共组密码。
  72. configuration.allowedGroupCiphers.clear();
  73. configuration.allowedGroupCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
  74. configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
  75. //公认的密钥管理方案。
  76. configuration.allowedKeyManagement.clear();
  77. configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
  78. //密码为WPA。
  79. configuration.allowedPairwiseCiphers.clear();
  80. configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
  81. configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
  82. //公认的安全协议。
  83. configuration.allowedProtocols.clear();
  84. configuration.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
  85. }
  86. /**
  87. * WEP协议
  88. *
  89. * @param configuration 配置
  90. * @param password 密码
  91. */
  92. public static void setWEP(WifiConfiguration configuration, String password) {
  93. configuration.wepKeys[0] = "\"" + password + "\"";
  94. configuration.wepTxKeyIndex = 0;
  95. configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
  96. configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
  97. }
  98. /**
  99. * 无密码
  100. *
  101. * @param configuration 配置
  102. */
  103. public static void setESS(WifiConfiguration configuration) {
  104. configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
  105. }

断开连接(无系统签名):

  1. //Android11及以上可以使用,清除建议列表,可以断开当前的网络
  2. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
  3. List<WifiNetworkSuggestion> networkSuggestions = wifiManager.getNetworkSuggestions();
  4. wifiManager.removeNetworkSuggestions(networkSuggestions);
  5. }

监听连接状态:

  1. //监听网络连接状态
  2. connectivityManager.registerDefaultNetworkCallback(new ConnectivityManager.NetworkCallback(){
  3. @Override
  4. public void onAvailable(@NonNull Network network) {
  5. super.onAvailable(network);
  6. Log.d("MainActivity", "onAvailable: 网络已连接");
  7. Toast.makeText(MainActivity.this, "已连接网络", Toast.LENGTH_SHORT).show();
  8. }
  9. @Override
  10. public void onUnavailable() {
  11. super.onUnavailable();
  12. Log.d("MainActivity", "onUnavailable: 网络已断开");
  13. Toast.makeText(MainActivity.this, "已断开网络", Toast.LENGTH_SHORT).show();
  14. }
  15. });

注意事项:

断开当前Wifi后,再重新连接该Wifi,可能会出现无法连接的情况。

这种情况我是通过关闭Wifi后再重新打开解决的,但是对Wifi的开关控制要涉及到权限问题——

需要System权限,在Manifest中添加:

android:sharedUserId="android.uid.system"

然后需要系统签名,可在系统源码中获得。

不知道各位有没有什么好的解决方法。

项目地址:

有系统签名(推荐)——

https://github.com/Ouanu/WIFI_DEMOicon-default.png?t=N176https://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命令

  1. adb shell svc wifi enable // 开启WIFI
  2. adb shell svc wifi disable // 关闭WIFI

4、应用端(App)对该文本进行读写

即可实现不需系统签名也可控制WIFI模块的开关

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/295515
推荐阅读
相关标签
  

闽ICP备14008679号