今天拿了个新需求,要求为工厂开发一个扫地机模组检测功能的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 {
@Override
public 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 {
@Override
public 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 {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if ((msg.what == -1)) {
// 清空之前的消息
removeCallbacksAndMessages(null);
// 提示失败
tv_result.setText("检测结果:检测失败!");
}
}
}