Android Wifi 扫描

news2024/11/15 8:29:47

今天拿了个新需求,要求为工厂开发一个扫地机模组检测功能的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("检测结果:检测失败!");
		}
	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/452810.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java概述

Java语言简史&#xff1a; 是SUN(Stanford University Network&#xff0c;斯坦福大学网络公司 ) 1995年推出的一门高级编程语言。 是一种面向Internet的编程语言。Java一开始富有吸引力是因为Java程序可以在Web浏览器中运行。这些Java程序被称为Java小程序&#xff08;applet&…

foldersync使用感受

foldersync简介 ​ FolderSync pro是一款功能非常强大的设备本地存储(包括SD卡)文件/文件夹与云存储同步应用。它可以将手机中的文件自动同步到云端空间&#xff0c;支持包括 FTP、WebDAV、Dropbox、 Google Docs 在内的众多空间。 FolderSync Pro 支持各种不同的云服务商和文件…

CTA策略趋势类

趋势策略 趋势策略日内策略Hilbert 策略R-Braker 策略Dual Thrust 策略菲阿里四价策略空中花园策略 日间策略移动平均线MACD 策略Aberration 策略ATR 策略动量策略肯特纳通道自动识别趋势的追涨交易策略 趋势策略 市场只有两种状态&#xff1a;震荡和单边。 而两种市场状态只…

springboot项目:瑞吉外卖 前后端详细分析 part4

part 1 part 2 part 3 part 4 本页 文章目录 5 套餐管理5.1 新增套餐5.1.1 整体分析5.1.2 前端分析5.1.3 后端分析 持续更新中 5 套餐管理 5.1 新增套餐 5.2 套餐信息分页查询 5.3 删除套餐 其他小功能都比较简单且类似&#xff0c;不再赘述 5.1 新增套餐 5.1.1 整体分析 套…

jmeter取样器javaRequest脚本8

1,创建一个maven工程2,通过maven编译打包生成一个jar包3,重启jmeter&#xff0c;新建java request请求4,开始执行脚本本文永久更新地址: 1,创建一个maven工程 在pom.xml文件中添加 maven下载地址&#xff1a;https://mvnrepository.com/artifact/org.apache.jmeter/ApacheJMe…

【MySQL】关于 SQL 语句执行分析的二三事

一、为什么要发生这件事 确实&#xff0c; 平时我们增删改查写的好好的&#xff0c; 各种业务代码&#xff0c;各种小接口写的不亦乐乎&#xff0c;正常是没时间干这个的&#xff0c;但是但是&#xff0c;这不是还有点技术追求嘛&#xff0c;假如我们平时测一个小接口&#xf…

【LeetCode】199.二叉树的右视图

1.问题 给定一个二叉树的 根节点 root&#xff0c;想象自己站在它的右侧&#xff0c;按照从顶部到底部的顺序&#xff0c;返回从右侧所能看到的节点值。 示例 1: 输入: [1,2,3,null,5,null,4] 输出: [1,3,4] 示例 2: 输入: [1,null,3] 输出: [1,3] 示例 3: 输入: [] 输出: []…

类加载过程

基本说明 反射机制是Java实现动态语言的关键&#xff0c;也就是通过反射实现类动态加载。 静态加载&#xff1a;编译时加载相关的类&#xff0c;如果没有则报错&#xff0c;依赖性太强动态加载&#xff1a;运行时加载需要的类&#xff0c;如果运行时不用该类&#xff0c;即使…

C++关于线程的一些操作

线程创建和接收 std::this_thread::get_id()获取当前线程的线程ID std::this_thread::yield()让步结束当前线程的时间片 int main() {vector<thread> threads(2);threads[0] thread([]() {cout << this_thread::get_id() << endl;});threads[1] thread([](…

Baumer工业相机中偏振相机如何使用Baumer堡盟GAPI SDK来进行偏振数据的计算转换输出(C#)

项目场景 Baumer工业相机堡盟相机是一种高性能、高质量的工业相机&#xff0c;可用于各种应用场景&#xff0c;如物体检测、计数和识别、运动分析和图像处理。 Baumer的万兆网相机拥有出色的图像处理性能&#xff0c;可以实时传输高分辨率图像。此外&#xff0c;该相机还具…

ansible自动运维——ansible使用临时命令通过模块来执行任务

大家好&#xff0c;这里是天亮之前ict&#xff0c;本人网络工程大三在读小学生&#xff0c;拥有锐捷的ie和红帽的ce认证。每天更新一个linux进阶的小知识&#xff0c;希望能提高自己的技术的同时&#xff0c;也可以帮助到大家 另外其它专栏请关注&#xff1a; 锐捷数通实验&…

【机器学习实战】Python基于SVD奇异值分解进行矩阵分解(八)

文章目录 1 前言1.1 奇异值分解1.2 奇异值分解的应用 2 简单计算SVD2.1 NumPy 计算 SVD2.2 scikit-learn 计算截断 SVD2.3 scikit-learn 计算随机 SVD 3 demo数据演示3.1 导入函数3.2 导入数据3.3 计算SVD 4 讨论 1 前言 1.1 奇异值分解 奇异值分解&#xff08;Singular Valu…

信息安全复习四:置换密码乘积密码隐写术

一、章节梗概 置换密码、Rail Fence密码、行置换密码、乘积密码、转子机、隐写术 二、置换技术 2.1 定义 重新排列明文字母&#xff0c;达到信息加密的目的。 与替代密码不同的是&#xff0c;原来明文中的字母同样出现在密文中&#xff0c;只是顺序被打断。 古典的置换密码…

.net6 core Worker Service项目发布部署到Linux,以守护进程服务的形式部署启动

一、发布项目 1、以文件夹形式 2、目标运行时选对应的平台&#xff08;Linux-x64&#xff09; 3、文件夹选项&#xff1a;在发布前删除所有现有文件 二、部署项目&#xff08;安装.net6环境&#xff1a;参考Linux安装 dotnet sdk 6.0&#xff09; &#xff08;1&#xff09;…

《Spring MVC》 第二章 让程序run起来

前言 Spring MVC 是 Spring 框架提供的一款基于 MVC 模式的轻量级 Web 开发框架。 Spring MVC 本质是对 Servlet 的进一步封装&#xff0c;其最核心的组件是DispatcherServlet&#xff0c;它是 Spring MVC 的前端控制器&#xff0c;主要负责对请求和响应的统一地处理和分发。C…

用好Python自然语言工具包-- 实例“基于本地知识库的自动问答”

首先鸣谢thomas-yanxin 本问中示例来自他在GitHub上的开源项目“基于本地知识库的自动问答”&#xff0c;链接如下&#xff1a; thomas-yanxin/LangChain-ChatGLM-Webui: 基于LangChain和ChatGLM-6B的针对本地知识库的自动问答 (github.com) 目录 1. 基础知识&#xff1a; …

JVM调优最佳参数

项目背景 C端的项目&#xff0c;用户量比较多&#xff0c;请求比较多。 启动参数表 Xmx指定应用程序可用的最大堆大小。 Xms指定应用程序可用的最小堆大小。 &#xff08;一般情况下&#xff0c;需要设置Xmx和Xms为相等的值&#xff0c;且为一个固定的值&#xff09; 如果该值…

HCIP之链路聚合、VRRP

链路聚合 链路聚合 --- 可以将多个物理接口绑定成一个逻辑接口&#xff0c;即将N条物理链路聚合为一条逻辑链路。可以在不升级硬件的条件下&#xff0c;达到增加带宽的效果 我们将逻辑链路&#xff0c;称为聚合链路&#xff0c;在华为设备中称为ETH-TRUNK链路&#xff08;这个技…

Vue表单进阶操作

多选框另类使用场景 这个复选框和上面爱好那个复选框是不一样的&#xff0c;它不需要收集value值&#xff0c;只需要知道是否被选择&#xff0c;也就是ture或false&#xff0c;这时候就可以安装输入框的方式去写&#xff0c;直接去定义字符串&#xff0c;而不是数组 然后把全部…

“esp8266mod模块连接机智云Arduino实现pwm调节led的亮度“+_+

经过几天的漫长的探索和调试&#xff0c;终于连上机智云了。 历经的困难&#xff1a;esp8266总是连接机智云app超时&#xff0c;连接无反应&#xff0c;无数据。 1、机智云开发者中心&#xff0c;新建数据点&#xff0c;生成muc代码包&#xff0c;具体配置可以参考其他文章。…