> 文章列表 > Android Wifi 扫描

Android Wifi 扫描

Android Wifi 扫描

今天拿了个新需求,要求为工厂开发一个扫地机模组检测功能的App,需求逻辑:

1.可以选择机器支持的WBR3 模组和WR3 模组;

2.可以选择机器热点名称的前缀:Thamtu 和 SmartLife,还有自定义输入前缀;

3.WBR3 模组是Wi-Fi 加蓝牙模组,需要显示扫描到的蓝牙名称;

4.可以设置一次扫描机器个数和扫描超时时间;

实现效果:

本节主要先完成Wi-Fi模组的检测功能;

一、需求分解:

1.扫描附近的Wifi,获取 Wifi列表,根据机器热点名称过滤;

2.匹配到的热点机器数量跟输入的机器数量相同,则代表测试的机器没有问题;

3.超时时间内输出匹配结果,超时时间到后输出失败。

二、核心API:

1.注册WifiManager.SCAN_RESULTS_AVAILABLE_ACTION WiFi扫描广播监听;

2.调用WifiManager.startScan() 开始扫描附近WiFi;

3.调用WifiManager.getScanResults() 获取WiFi扫描结果;

三、代码实现逻辑:

1)初始化布局:

private void initView() {cb_wbr3 = findViewById(R.id.cb_wbr3);cb_wbr3.setChecked(true);cb_wr3 = findViewById(R.id.cb_wr3);cb_wr3.setChecked(false);cb_thamtu = findViewById(R.id.cb_thamtu);cb_thamtu.setChecked(true);cb_smart_life = findViewById(R.id.cb_smart_life);cb_smart_life.setChecked(false);cb_wbr3.setOnCheckedChangeListener((buttonView, isChecked) -> {isWbr3 = isChecked;cb_wr3.setChecked(!isChecked);});cb_wr3.setOnCheckedChangeListener((buttonView, isChecked) -> {isWbr3 = !isChecked;cb_wbr3.setChecked(!isChecked);});cb_thamtu.setOnCheckedChangeListener((buttonView, isChecked) -> {if (isChecked) {hotName = THAM_TU;cb_smart_life.setChecked(!isChecked);}tv_hot_name.setText(hotName);});cb_smart_life.setOnCheckedChangeListener((buttonView, isChecked) -> {if (isChecked) {hotName = SMART_LIFE;cb_thamtu.setChecked(!isChecked);}tv_hot_name.setText(hotName);});tv_hot_name = findViewById(R.id.tv_hot_name);tv_hot_name.setText(hotName);tv_result = findViewById(R.id.tv_result);et_hot_name = findViewById(R.id.et_hot_name);et_number = findViewById(R.id.et_number);et_timeout = findViewById(R.id.et_timeout);
}

2)动态申请权限

private boolean initPermission() {if (!PermissionUtil.checksLocationPermission(BaseApp.getContext())) {DialogManager.getInstance().showDialog("为了您能正常使用相关功能,APP需要向您申请位置权限", this, () -> {if (PermissionUtil.deniedPermission()) {// 用户已拒绝权限,跳转系统设置页Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).setData(Uri.fromParts("package", getPackageName(), null));intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);startActivity(intent);} else {// 用户未拒绝权限,弹框动态申请权限PermissionUtil.requestLocationPermission(this);}});return false;}return true;
}

3)申请到权限后,初始化WifiManager

private void initWifi() {mWifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
}

4)注册WiFi扫描的广播接收器

@Override
protected void onResume() {super.onResume();IntentFilter filter = new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);registerReceiver(mWifiScanReceiver, filter); // 注册WiFi扫描的广播接收器
}// 定义一个扫描周边WiFi的广播接收器
private class WifiScanReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {//...}
}

5)开始扫描附近的Wifi设备

public void start(View view) {if (!initPermission()) return;if (mWifiManager == null) {initWifi();}if (mWifiManager != null) {mWifiManager.startScan();if (myHandler != null) {// 清空之前的消息myHandler.removeCallbacksAndMessages(null);// 延迟timeout秒后,再扫描一次myHandler.postDelayed(() -> {if (mWifiManager != null) {mWifiManager.startScan();}}, timeout * 1000);// 延迟(timeout + 2)秒后,提示检测失败Message msg = Message.obtain();msg.what = -1;myHandler.sendMessageDelayed(msg, (timeout + 2) * 1000);}}if (isWbr3) {// 扫描蓝牙}
}

6)扫描到Wifi设备广播会接收到通知,然后获取WiFi扫描的结果,过滤,判断测试结果

private class WifiScanReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {if (mWifiManager == null) return;// 获取WiFi扫描的结果列表List<ScanResult> scanList = mWifiManager.getScanResults();Log.i(TAG, "onReceive scanList size " + scanList.size());List<ScanResult> resultList = new ArrayList<>();for (ScanResult scanResult : scanList) {String ssid = scanResult.SSID;if (TextUtils.isEmpty(ssid)) continue;if (ssid.toLowerCase().contains(hotName.toLowerCase())) {resultList.add(scanResult);}}Log.i(TAG, "onReceive resultList size " + resultList.size());if (resultList != null) {runOnUiThread(() -> showScanResult(resultList));}}
}// 显示过滤后的WiFi扫描结果
private void showScanResult(List<ScanResult> list) {if (list.size() == number) {// 清空之前的消息myHandler.removeCallbacksAndMessages(null);tv_result.setText("检测结果:检测成功!");return;}StringBuilder sb = new StringBuilder();sb.append("检测结果:");sb.append("\\n");for (ScanResult scanResult : list) { // 遍历扫描发现的WiFi列表sb.append(scanResult.BSSID);sb.append(" | ");sb.append(scanResult.SSID);sb.append("\\n");}tv_result.setText(sb.toString());
}

7)超时的handler消息触发时,仍没有成功,提示本次检测失败

class MyHandler extends Handler {@Overridepublic void handleMessage(@NonNull Message msg) {super.handleMessage(msg);if ((msg.what == -1)) {// 清空之前的消息removeCallbacksAndMessages(null);// 提示失败tv_result.setText("检测结果:检测失败!");}}
}