android 基于wifi模块通信开发
这篇文章主要是我写完手机与wifi模块通信后所用来总结编写过程的文章,下面,我分几点来说一下编写的大概流程。
一、拉出按钮控件并设置它的点击事件
二、设置wifi权限
三、打开和关闭wifi
四、扫描wifi到列表中
(1)拉出ListView控件,并设置它的适配器和点击事件
(2)注册广播
(3)动态申请位置权限
(4)添加并显示到列表控件
(5)注销广播
五、连接wifi设备
一、拉出按钮控件并设置它的点击事件
首先,我们在新建的项目中的布局文件,即activity_main.xml文件中,添加按钮控件的声明。
<Button
android:id="@+id/OPEN"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="打开WiFi" />
然后,我们到MainActivity.java文件中,定义Button对象。
public Button openWifi;
然后,我们在MainActivity.java文件中的onCreate()方法中给Button的对象赋值,其中,fingViewById()的参数为我们在xml文件中定义的按钮的id名。
openWifi = (Button) findViewById(R.id.OPEN);
接下来,我们就可以开始设置点击事件了。我们在onCreate()中,调用setOnClickListener()方法。
openWifi.setOnClickListener(this);
最后,我们在MainActivity.java中重写onClick()方法即可。
@Override
public void OnClick(View v)
{
switch(v.getId())
{
case R.id.OPEN: break;
} }
二、设置wifi权限
我们可以在AndroidManifest.xml中添加权限。
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <!-- 允许改变wifi连接状态 -->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <!-- 允许应用获取网络状态信息 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- 允许应用获得WiFi信息 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <!-- 获取位置信息 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- 获取手机状态 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> <!-- 读写SD卡 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
三、打开和关闭wifi
首先,我们要先定义一个WifiManager类的对象。
final WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
然后我们只要在按钮的点击事件中添加以下代码即可。
wifiManager.setWifiEnabled(true); //开启wifi
wifiManager.setWifiEnabled(false); //关闭wifi
四、扫描wifi到列表中
(1)、拉出ListView控件,并设置它的适配器和点击事件
首先,我们要在activity_main.xml文件中,添加列表控件的声明。
<ListView
android:id="@+id/LIST"
android:layout_width="match_parent"
android:layout_height="wrap_content"></ListView>
然后,我们要在MainActivity.java文件中,定义ListView对象。
public ListView listView;
同理,我们要在onCreate()方法中设置列表的点击事件。
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { }
});
添加完后,我们就可以触发列表的点击事件了。但是,这样还是看不见列表里的变化的,因为我们还没有为列表添加适配器。我们可以先了解一下适配器是什么。适配器是一个连接数据和AdapterView(ListView就是一个典型的AdapterView)的桥梁,通过它能有效地实现数据与AdapterView的分离设置,使AdapterView与数据的绑定更加简便,修改更加方便。
接下来,我们就开始定义适配器和有个集合类对象。
public ArrayAdapter adapter;
public ArrayList<String> arrayList = new ArrayList(); //用于存放字符串
public ArrayList<ScanResult> scanList = new ArrayList(); //用于存放扫描到的设备的信息
然后,我们在onCreate()方法中给适配器赋值。
adapter = new ArrayAdapter(this, android.R.layout.simple_expandable_list_item_1, arrayList);
listView.setAdapter(adapter);//设置列表显示
(2)注册广播
首先,我们要在onCreate()中定义IntentFilter的对象。
IntentFilter filter = new IntentFilter();
filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
接下来我们要重写BroadcastReceiver类来定义广播。
private BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(final Context context, Intent intent) {
final WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
String action = intent.getAction();
if (action.equals(wifiManager.SCAN_RESULTS_AVAILABLE_ACTION))//搜索到可用的wifi
{
scanResults = wifiManager.getScanResults();//获取wifi的扫描结果
scanResults = getNewList(scanResults);
for (ScanResult scanResult : scanResults) {
arrayList.add(scanResult.SSID);
scanList.add(scanResult);
adapter.notifyDataSetChanged();
}
} if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
if (info.getState().equals(NetworkInfo.State.CONNECTED)) {
final WifiInfo wifiInfo = wifiManager.getConnectionInfo();
Toast.makeText(context, "已成功连接" + wifiInfo.getSSID(), Toast.LENGTH_SHORT).show();
} else if (info.getState().equals(NetworkInfo.State.DISCONNECTED)) {
Toast.makeText(context, "已断开连接", Toast.LENGTH_SHORT).show();
}
}
}
};
最后,在onCreate()中注册广播。
registerReceiver(receiver, filter);
(3)申请动态的位置权限
public void applypermission() {
if (Build.VERSION.SDK_INT >= 23) {
//检查是否已经给了权限
int checkpermission = ContextCompat.checkSelfPermission(getApplicationContext(),
Manifest.permission.ACCESS_FINE_LOCATION);
if (checkpermission != PackageManager.PERMISSION_GRANTED) {//没有给权限
Log.e("permission", "动态申请");
//参数分别是当前活动,权限字符串数组,requestcode
ActivityCompat.requestPermissions(WiFiMainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
}
}
} @Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(WiFiMainActivity.this, "已授权", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(WiFiMainActivity.this, "拒绝授权", Toast.LENGTH_SHORT).show();
} }
(4)添加并显示到列表控件
添加有个按钮控件,然后在调用startScan()方法就可以开始扫描了。
public void scanWiFi() {
adapter.clear(); //清空列表里的数据
adapter.notifyDataSetChanged(); //刷新
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
if (!wifiManager.isWifiEnabled()) { //判断wifi是否打开
wifiManager.setWifiEnabled(true); //如果没有打开就打开wifi
}
//开始扫描wifi设备
wifiManager.startScan();
}
public List<ScanResult> getNewList(List<ScanResult> list) {
List<ScanResult> lists = new ArrayList();
for (int i = 0; i < list.size(); i++) {
if (!lists.contains(list.get(i))) {
lists.add(list.get(i));
}
}
return lists;
}
(5)注销广播
在onCreate()中使用unregisterReceiver()方法注销广播。
protected void onDestroy() {
super.onDestroy();//解除注册
unregisterReceiver(receiver);
}
五、连接wifi设备
wifiManager.disconnect();
final ScanResult result = scanList.get(i);
String capabilities = result.capabilities;
int type = WIFICIPHER_WPA;
if (!TextUtils.isEmpty(capabilities))//判断字符串是否为null
{
if (capabilities.contains("WPA") || capabilities.contains("wpa")) {
type = WIFICIPHER_WPA;
} else if (capabilities.contains("WEP") || capabilities.contains("wep")) {
type = WIFICIPHER_WEP;
} else {
type = WIFICIPHER_NOPASS;
}
config = isExsits(result.SSID);
if (config == null) {
if (type != WIFICIPHER_NOPASS) {
final EditText editText = new EditText(WiFiMainActivity.this);
final int fianalType = type;
alertDialog = new AlertDialog.Builder(WiFiMainActivity.this);
alertDialog.setTitle("请输入WiFi密码:");
alertDialog.setView(editText);
alertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
config = createWifiInfo(result.SSID, editText.getText().toString(), fianalType);
connectWifi(config);
}
}); alertDialog.setNegativeButton("CANCEL", null).show();
} else {
config = createWifiInfo(result.SSID, "", type);
connectWifi(config);
}
} else {
connectWifi(config);
}
}
public void connectWifi(WifiConfiguration config) {
final WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
int wcgID = wifiManager.addNetwork(config);
wifiManager.enableNetwork(wcgID, true);
}
public WifiConfiguration createWifiInfo(String SSID, String password, int type) {
WifiConfiguration config = new WifiConfiguration();
config.allowedAuthAlgorithms.clear();
config.allowedGroupCiphers.clear();
config.allowedKeyManagement.clear();
config.allowedPairwiseCiphers.clear();
config.allowedProtocols.clear();
config.SSID = "\"" + SSID + "\""; if (type == WIFICIPHER_WEP) {
config.preSharedKey = "\"" + password + "\"";
config.hiddenSSID = true;
config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
config.wepTxKeyIndex = 0;
} else if (type == WIFICIPHER_WPA) {
config.preSharedKey = "\"" + password + "\"";
config.hiddenSSID = true;
config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
config.status = WifiConfiguration.Status.ENABLED;
}
return config;
}
private WifiConfiguration isExsits(String ssid) {
final WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
List<WifiConfiguration> existingConfigs = wifiManager.getConfiguredNetworks();
for (WifiConfiguration existingConfig : existingConfigs) {
if (existingConfig.SSID.equals("\"" + ssid + "\""))
return existingConfig;
}
return null;
}
android 基于wifi模块通信开发的更多相关文章
- ESA2GJK1DH1K升级篇: STM32远程乒乓升级,基于(Wi-Fi模块AT指令TCP透传方式),MQTT通信控制升级
实现功能概要 前面的版本都是,定时访问云端的程序版本,如果版本不一致,然后下载最新的升级文件,实现升级. 这一节,在用户程序里面加入MQTT通信,执行用户程序的时候,通过接收MQTT的升级命令实现升级 ...
- Android基于XMPP Smack openfire 开发的聊天室
Android基于XMPP Smack openfire 开发的聊天室(一)[会议服务.聊天室列表.加入] http://blog.csdn.net/lnb333666/article/details ...
- 基于.Net C# 通信开发-串口调试助手
基于.Net C# 通信开发-串口调试助手 1.概述 串口调试助手,广泛应用于工控领域的数据监控.数据采集.数据分析等工作,可以帮助串口应用设计.开发.测试人员检查所开发的串口应用软硬件的数据收发状况 ...
- 基于.Net C# 通信开发-网络调试助手
基于.Net C# 通信开发-网络调试助手1.概述 网络调试助手是集TCP/UDP服务端客户端一体的网络调试工具,可以帮助网络应用设计.开发.测试人员检查所开发的网络应用软硬件的数据收发状况,提高开发 ...
- Android基于WIFI实现电脑和手机间数据传输的技术方案研究
Android手机和电脑间基于wifi进行数据传输,从技术上讲,主要有两种方案: 一种是通过ftp协议实现,Android手机作为数据传输过程中的ftp服务器: 一种是通过http协议实现.Andro ...
- ESA2GJK1DH1K升级篇: STM32远程乒乓升级,基于Wi-Fi模块(ESP8266)AT指令TCP透传方式,MQTT通信控制升级(加入数据校验)
前言 这节演示下,上两节写的利用MQTT来控制STM32控制的程序 测试准备工作(默认访问我的服务器,改为自己的服务器,请看后面说明) 一,下载BootLoader程序(请自行下载) 首先BootLo ...
- ESA2GJK1DH1K升级篇: STM32远程乒乓升级,基于WIFI模块AT指令TCP透传方式,定时访问升级(含有数据校验)
实现功能概要 定时使用http访问云端的程序版本,如果版本不一致,然后通过http下载最新的升级文件,实现升级. 测试准备工作(默认访问我的服务器,改为自己的服务器,请看后面说明) 一,下载BootL ...
- ESA2GJK1DH1K升级篇: STM32远程乒乓升级,基于(WIFI模块AT指令TCP透传方式),定时访问升级
前言 学习此代码所需: 实现功能概要 定时使用http访问云端的程序版本,如果版本不一致,然后通过http下载最新的升级文件,实现升级. 测试准备工作(默认访问我的服务器,改为自己的服务器,请看后面说 ...
- android 基于百度地图api开发定位以及获取详细地址
一:百度地图开发必须要到百度开发平台android开发api下载相应的库,已经申请百度地图开发key. 二:新建项目baidumaplocation.设计main.xml文件这里注意的是MapView ...
随机推荐
- Go 程序是怎样跑起来的
目录 引入 编译链接概述 编译过程 词法分析 语法分析 语义分析 中间代码生成 目标代码生成与优化 链接过程 Go 程序启动 GoRoot 和 GoPath Go 命令详解 go build go i ...
- 【commons-lang3工具】JAVA脱敏工具
前言:commons-langbao中有很多方便的工具,无需我们自己去实现,能够节省很多开发时的问题: 1.工具包,引入依赖,jDK8对应的版本如下: <!-- https://mvnrepos ...
- 【简易bat脚本】启动java程序
前置条件:path中添加了JAVAHOME配置了java环境变量 1.新建txt文本文件 2.粘贴以下内容 @echo off set path=%path%;.;java -classpath &q ...
- AD域控制器安装使用
AD域控制器安装使用 一. 在服务器上安装域控制器 二. 将此服务器提升为域控制器 三. 将主机加入到我们创建的域中 在AD域控制器上查看加入的主机
- HDU 4462:Scaring the Birds(暴力枚举+状态压缩)
http://acm.hdu.edu.cn/showproblem.php?pid=4462 题意:有一个n*n的地图,有k个空地可以放稻草人,给出每个空地可以放的稻草人属性,属性中有个R代表这个位置 ...
- c++复杂桶排序Java版
c++复杂桶排序Java版 题目和我的前几个排序一样 这次是Java版的 代码 + 注释 package com.vdian.qatest.supertagbiz.test.niu; /** * Cr ...
- Akka-CQRS(16)- gRPC用JWT进行权限管理
前面谈过gRPC的SSL/TLS安全机制,发现设置过程比较复杂:比如证书签名:需要服务端.客户端两头都设置等.想想实际上用JWT会更加便捷,而且更安全和功能强大,因为除JWT的加密签名之外还可以把私密 ...
- 【深入浅出-JVM】(3):浮点数
-5 浮点数推导 二进制转十进制 1 10000001 01000000000000000000000 1 10000001 101000000000000000000000 如果指数位不全为 0 则 ...
- windows中实现python,redis服务自动重启(任务计划程序+bat脚本)
需求:银行电脑无法自动开机,只能 通过 应用相关服务每天自动重启的方式实现 服务更新并且防止服务假死,内存过大 等情况 相关工具:win10系统中,使用windows自带的任务计划程序 和 bat脚本 ...
- 【不带权图算法之拓扑排序】-C++
拓扑排序算法主要由以下两步循环执行,直到不存在入度为 的顶点为止. 选择一个入度为 的顶点并将它输出: 删除从该顶点连出的所有边. 循环结束,若输出的顶点数小于图中的顶点数,则表示该图中存在回路,也就 ...