这篇文章主要是我写完手机与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模块通信开发的更多相关文章

  1. ESA2GJK1DH1K升级篇: STM32远程乒乓升级,基于(Wi-Fi模块AT指令TCP透传方式),MQTT通信控制升级

    实现功能概要 前面的版本都是,定时访问云端的程序版本,如果版本不一致,然后下载最新的升级文件,实现升级. 这一节,在用户程序里面加入MQTT通信,执行用户程序的时候,通过接收MQTT的升级命令实现升级 ...

  2. Android基于XMPP Smack openfire 开发的聊天室

    Android基于XMPP Smack openfire 开发的聊天室(一)[会议服务.聊天室列表.加入] http://blog.csdn.net/lnb333666/article/details ...

  3. 基于.Net C# 通信开发-串口调试助手

    基于.Net C# 通信开发-串口调试助手 1.概述 串口调试助手,广泛应用于工控领域的数据监控.数据采集.数据分析等工作,可以帮助串口应用设计.开发.测试人员检查所开发的串口应用软硬件的数据收发状况 ...

  4. 基于.Net C# 通信开发-网络调试助手

    基于.Net C# 通信开发-网络调试助手1.概述 网络调试助手是集TCP/UDP服务端客户端一体的网络调试工具,可以帮助网络应用设计.开发.测试人员检查所开发的网络应用软硬件的数据收发状况,提高开发 ...

  5. Android基于WIFI实现电脑和手机间数据传输的技术方案研究

    Android手机和电脑间基于wifi进行数据传输,从技术上讲,主要有两种方案: 一种是通过ftp协议实现,Android手机作为数据传输过程中的ftp服务器: 一种是通过http协议实现.Andro ...

  6. ESA2GJK1DH1K升级篇: STM32远程乒乓升级,基于Wi-Fi模块(ESP8266)AT指令TCP透传方式,MQTT通信控制升级(加入数据校验)

    前言 这节演示下,上两节写的利用MQTT来控制STM32控制的程序 测试准备工作(默认访问我的服务器,改为自己的服务器,请看后面说明) 一,下载BootLoader程序(请自行下载) 首先BootLo ...

  7. ESA2GJK1DH1K升级篇: STM32远程乒乓升级,基于WIFI模块AT指令TCP透传方式,定时访问升级(含有数据校验)

    实现功能概要 定时使用http访问云端的程序版本,如果版本不一致,然后通过http下载最新的升级文件,实现升级. 测试准备工作(默认访问我的服务器,改为自己的服务器,请看后面说明) 一,下载BootL ...

  8. ESA2GJK1DH1K升级篇: STM32远程乒乓升级,基于(WIFI模块AT指令TCP透传方式),定时访问升级

    前言 学习此代码所需: 实现功能概要 定时使用http访问云端的程序版本,如果版本不一致,然后通过http下载最新的升级文件,实现升级. 测试准备工作(默认访问我的服务器,改为自己的服务器,请看后面说 ...

  9. android 基于百度地图api开发定位以及获取详细地址

    一:百度地图开发必须要到百度开发平台android开发api下载相应的库,已经申请百度地图开发key. 二:新建项目baidumaplocation.设计main.xml文件这里注意的是MapView ...

随机推荐

  1. HBase 学习之路(八)——HBase协处理器

    一.简述 在使用HBase时,如果你的数据量达到了数十亿行或数百万列,此时能否在查询中返回大量数据将受制于网络的带宽,即便网络状况允许,但是客户端的计算处理也未必能够满足要求.在这种情况下,协处理器( ...

  2. VMware安装linux系统

  3. 一篇文章概括 Java Date Time 的使用

    本文目的:掌握 Java 中日期和时间常用 API 的使用. 参考:Jakob Jenkov的英文教程Java Date Time Tutorial 和 JavaDoc 概览 Java 8 新增 AP ...

  4. ES5_05_Function扩展

    Function 构造器的语法: 注意: 参数 arg1 , arg2 , argN 被函数使用的参数的名称必须是合法命名的.参数名称是一个有效的JavaScript标识符的字符串,或者一个用逗号分隔 ...

  5. HDU 1811:Rank of Tetris(并查集+拓扑排序)

    http://acm.hdu.edu.cn/showproblem.php?pid=1811 Rank of Tetris Problem Description   自从Lele开发了Rating系 ...

  6. Codeforces Gym100962J:Jimi Hendrix(树型DP)

    http://codeforces.com/gym/100962/attachments 题意:有一个n个节点的字母树,给出n-1条边的信息,代表边上有一个字母,然后给出长度为m的字符串,问是否能在这 ...

  7. Go - 循环

    目录 概述 循环 array 循环 slice 循环 map break continue goto switch 推荐阅读 概述 前几篇文章分享了 array 数组.slice 切片.map 集合, ...

  8. Managing Network Usage

    This lesson describes how to write applications that have fine-grained control over their usage of n ...

  9. [记录]Python高并发编程

    ========== ==多进程== ========== 要让Python程序实现多进程(multiprocessing),我们先了解操作系统的相关知识. Unix/Linux操作系统提供了一个fo ...

  10. VNC服务配置

    Windows通过VNC远程桌面访问Ubuntu设备:一个WIN7的机器,一个系统为Ubuntu的机器 (二者可以均可为虚拟机或实体机) 目的:在Windows系统上通过VNC远程访问Ubuntu. ...