上面的截图,就是本文要介绍的主要功能。
1.准备工作,声明权限:
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /><uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/><uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/><uses-permission android:name="android.permission.WRITE_SETTINGS"tools:ignore="ProtectedPermissions" />
2.打开WIfi:
1)申请权限:注意的一点就是,打开wifi需要申请位置权限
String[] permsLocation = {"android.permission.ACCESS_WIFI_STATE", "android.permission.CHANGE_WIFI_STATE", "android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION"};
//获取权限private void getPerMission() {mPermissionsChecker = new PermissionsChecker(MainActivity.this);if (mPermissionsChecker.lacksPermissions(permsLocation)) {ActivityCompat.requestPermissions(MainActivity.this, permsLocation, 1000);}}
2)打开wifi
获取WifiManager:
wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
public boolean openWifi(WifiManager mWifiManager) {boolean bRet = true;Log.e("nyz", "wifi enable " + mWifiManager.isWifiEnabled());//android Q 不能使用,只能跳转设置界面,手动开启。startActivity(Intent(Settings.ACTION_WIFI_SETTINGS))if (!mWifiManager.isWifiEnabled()) {bRet = mWifiManager.setWifiEnabled(true);}Log.e("nyz", "wifi result " + bRet);return bRet;}
需要注意的一点就是,Android10以上下面的打开Wifi的功能将会失效,需要跳转到设置界面,由用户手动打开。
* @deprecated Starting with Build.VERSION_CODES#Q, applications are not allowed to* enable/disable Wi-Fi.* <b>Compatibility Note:</b> For applications targeting* {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return {@code false}* and will have no effect. If apps are targeting an older SDK (* {@link android.os.Build.VERSION_CODES#P} or below), they can continue to use this API.*/@Deprecatedpublic boolean setWifiEnabled(boolean enabled) {try {return mService.setWifiEnabled(mContext.getOpPackageName(), enabled);} catch (RemoteException e) {throw e.rethrowFromSystemServer();}}
3.获取WIfi列表:
1)创建一个BroadCastReceiver:
收到 WifiManager.SCAN_RESULTS_AVAILABLE_ACTION 广播后,可以获取WIfi列表
class WifiReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {if (TextUtils.isEmpty(intent.getAction())) {return;}String action = intent.getAction();Log.e("nyz", "action " + action);if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action)) {boolean result = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false);List<ScanResult> wifiList = wifiManager.getScanResults();Log.e("nyz", "results " + wifiList.size() + " result " + result);if (wifiList != null) {for (int i = 0; i < wifiList.size(); i++) {ScanResult wifi = wifiList.get(i);if (TextUtils.isEmpty(wifi.SSID)) {continue;}Log.e("nyz", "BSSID " + wifi.BSSID);Log.e("nyz", "SSID " + wifi.SSID);Log.e("nyz", "level " + wifi.level);Log.e("nyz", "capabilities " + wifi.capabilities);//拿到结果后,可以更新界面,在界面展示}}} else if (WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION.equals(action)) {} else if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) {}}}
2)注册和反注册:
private void registerReceiver() {wifiReceiver = new WifiReceiver();IntentFilter filter = new IntentFilter();filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);filter.addAction(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION);registerReceiver(wifiReceiver, filter);}@Overrideprotected void onDestroy() {super.onDestroy();unregisterReceiver(wifiReceiver);}
3)开始扫描Wifi:
调用 wifiManager.startScan();开始扫描。搜索到附近的Wifi后,系统会发布广播,可以在广播接收者中,收到wifi列表信息。
findViewById(R.id.scan).setOnClickListener(v -> {if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(MainActivity.this, permsLocation, 1000);return;}boolean result = wifiManager.startScan();Log.e("nyz", "result " + result);List<ScanResult> wifiList = wifiManager.getScanResults();Log.e("nyz", "size " + wifiList.size());
// if (wifiList != null) {
// for (int i = 0; i < wifiList.size(); i++) {
// ScanResult wifi = wifiList.get(i);
// Log.e("nyz", "BSSID " + wifi.BSSID);
// Log.e("nyz", "SSID " + wifi.SSID);
// Log.e("nyz", "level " + wifi.level);
// Log.e("nyz", "capabilities " + wifi.capabilities);
// }
// }WifiInfo wifiInfo = wifiManager.getConnectionInfo();Log.e("nyz", "wifiInfo = " + (wifiInfo == null));});
4.链接wifi:
private void connWifi(Context context, String ssid, String pwd) {if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {return;}Log.e("nyz", "sdk " + Build.VERSION.SDK_INT);if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {WifiConfiguration config = createWifiInfo(ssid, pwd);int netId = wifiManager.addNetwork(config);Log.e("nyz", "netID " + netId);boolean isConn = wifiManager.enableNetwork(netId, true);Log.e("nyz", "isConn " + isConn);} else {
// connectSuggestion(ssid, pwd);connectSpecifier(ssid, pwd);}}
在Android10以前,可以通过addNetwork的方式进行链接,在Android10以后,这种方式就不推荐使用了。
* @deprecated* a) See {@link WifiNetworkSpecifier.Builder#build()} for new* mechanism to trigger connection to a Wi-Fi network.* b) See {@link #addNetworkSuggestions(List)},* {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration* when auto-connecting to wifi.* <b>Compatibility Note:</b> For applications targeting* {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return {@code -1}.*/@Deprecatedpublic int addNetwork(WifiConfiguration config) {if (config == null) {return -1;}config.networkId = -1;return addOrUpdateNetwork(config);}
Android10以后链接wifi:
1)建议的方式:
官方文档:适用于互联网连接的 WLAN 建议 API | Android 开发者 | Android Developers
@RequiresApi(api = Build.VERSION_CODES.Q)private void connectSuggestion(String ssid, String pwd) {WifiNetworkSuggestion suggestion2 =new WifiNetworkSuggestion.Builder().setSsid(ssid).setWpa2Passphrase(pwd)//是否可以接收到android.net.wifi.action.WIFI_NETWORK_SUGGESTION_POST_CONNECTION.setIsAppInteractionRequired(true).build();List<WifiNetworkSuggestion> suggestionsList = new ArrayList<WifiNetworkSuggestion>();suggestionsList.add(suggestion2);int status = wifiManager.addNetworkSuggestions(suggestionsList);Log.e("nyz", "status " + status);if (status != WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) {}}
2)点对点的方式:
官方文档:WifiNetworkSpecifier | Android Developers
@RequiresApi(api = Build.VERSION_CODES.Q)private void connectSpecifier(String ssid, String pwd) {WifiNetworkSpecifier specifier = new WifiNetworkSpecifier.Builder().setSsidPattern(new PatternMatcher(ssid, PatternMatcher.PATTERN_PREFIX)).setWpa2Passphrase(pwd).build();NetworkRequest request = new NetworkRequest.Builder().addTransportType(NetworkCapabilities.TRANSPORT_WIFI).setNetworkSpecifier(specifier).build();ConnectivityManager manager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);manager.requestNetwork(request, new ConnectivityManager.NetworkCallback() {@Overridepublic void onAvailable(@NonNull Network network) {super.onAvailable(network);Log.e("nyz", "onAvailable");if (network != null) {}}@Overridepublic void onUnavailable() {super.onUnavailable();Log.e("nyz", "onUnavailable");}@Overridepublic void onCapabilitiesChanged(@NonNull Network network, @NonNull NetworkCapabilities networkCapabilities) {super.onCapabilitiesChanged(network, networkCapabilities);Log.e("nyz", "网络变化");}});}