上面的截图,就是本文要介绍的主要功能。
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.
- * Compatibility Note: 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.
- */
- @Deprecated
- public 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 {
- @Override
- public 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);
-
- }
-
- @Override
- protected 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}.
- */
- @Deprecated
- public 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() {
- @Override
- public void onAvailable(@NonNull Network network) {
- super.onAvailable(network);
- Log.e("nyz", "onAvailable");
- if (network != null) {
- }
-
- }
-
- @Override
- public void onUnavailable() {
- super.onUnavailable();
- Log.e("nyz", "onUnavailable");
- }
-
- @Override
- public void onCapabilitiesChanged(@NonNull Network network, @NonNull NetworkCapabilities networkCapabilities) {
- super.onCapabilitiesChanged(network, networkCapabilities);
- Log.e("nyz", "网络变化");
- }
- });
-
- }