第14章 Wi-Fi系统应用 14.1 了解Wi-Fi系统的结构
Android平台中Wi-Fi系统从上到下主要包括Java框架类、Android适配器库、wpa_supplicant守护进程、驱动程序和协议,这几部分的系统结构如图14-3所示。
(1)Wi-Fi用户空间的程序和库,对应路径如下所示。
14.3 开发Wi-Fi应用程序
14.3.1 类WifiManager
例如下面一段代码是通用的Wi-Fi应用程序。
package com.example.wifiadmin; import java.util.List; import android.content.Context;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.WifiLock; public class WifiAdmin {
//定义WifiManager对象
private WifiManager mWifiManager;
//定义WifiInfo对象
private WifiInfo mWifiInfo;
//扫描出的网络连接列表
private List<ScanResult> mWifiList;
//网络连接列表
private List<WifiConfiguration> mWifiConfiguration;
//定义一个WifiLock
WifiLock mWifiLock;
//构造器
public WifiAdmin(Context context) {
//取得WifiManager对象
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
if(mWifiManager != null){
List<ScanResult> wifiscanResults = mWifiManager.getScanResults();
if(wifiscanResults != null && wifiscanResults.size() !=0){ }
}
//取得WifiInfo对象
mWifiInfo = mWifiManager.getConnectionInfo();
}
//打开Wi-Fi
public void OpenWifi(){
if (!mWifiManager.isWifiEnabled())
{
mWifiManager.setWifiEnabled(true);
}
} //关闭Wi-Fi
public void CloseWifi(){
if (!mWifiManager.isWifiEnabled()){
mWifiManager.setWifiEnabled(false);
}
}
//锁定WifiLock,当下载大文件时需要锁定
public void AcquireWifiLock()
{
mWifiLock.acquire();
}
//解锁WifiLock
public void ReleaseWifiLock()
{
//判断时候锁定
if(mWifiLock.isHeld())
{
mWifiLock.acquire();
}
}
//创建一个WifiLock
public void CreatWifiLock(){
mWifiLock = mWifiManager.createWifiLock("Test");
} //得到配置好的网络
public List<WifiConfiguration> GetConfiguration()
{
return mWifiConfiguration;
}
//指定配置好的网络进行连接
public void ConnectConfiguration(int index){
//索引大于配置好的网络,索引返回
if(index > mWifiConfiguration.size()){
return;
}
//连接配置好的指定ID的网络
mWifiManager.enableNetwork(mWifiConfiguration.get(index).networkId, true);
} // 得到网络列表
public List<ScanResult> GetWifiList()
{
return mWifiList;
}
//查看扫描结果
public StringBuilder LookUpScan()
{
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < mWifiList.size(); i++){
stringBuilder.append("Index_"+new Integer(i+1).toString() + ":");
//将ScanResult信息转换成一个字符串包
//其中包括:BSSID、SSID、capabilities、frequency、level
stringBuilder.append((mWifiList.get(i)).toString());
stringBuilder.append("\n");
}
return stringBuilder;
} // 得到MAC地址
public String GetMacAddress(){
return (mWifiInfo == null) ? "NULL" : mWifiInfo.getMacAddress();
}
// 得到接入点的BSSID
public String GetBSSID()
{
return (mWifiInfo == null) ? "NULL" : mWifiInfo.getBSSID();
}
//得到IP地址
public int GetIPAdress(){
return (mWifiInfo == null) ? 0 : mWifiInfo.getIpAddress();
}
//得到连接的ID
public int GetNetworkId(){
return (mWifiInfo == null ) ? 0 : mWifiInfo.getNetworkId();
}
//得到WifiInfo的所有信息包
public String GetWifiInfo()
{
return (mWifiInfo == null ) ? "NULL" : mWifiInfo.toString();
} //添加一个网络并连接
public void AddNetwork(WifiConfiguration wifiConfiguration)
{
int wcgID = mWifiManager.addNetwork(wifiConfiguration);
mWifiManager.enableNetwork(wcgID, true);
}
//断开指定ID的网络
public void DisconnectWifi(int netId){
mWifiManager.disableNetwork(netId);
mWifiManager.disconnect();
}
}
第二点是需要在程序中声明一些相关的权限,Wi-Fi的主要操作权限有如下四个。
● CHANGE_NETWORK_STATE: 允许修改网络状态的权限。
● CHANGE_WIFI_STATE:允许修改Wi-Fi状态的权限。
● ACCESS_NETWORK_STATE:允许访问网络状态的权限。
● ACCESS_WIFI_STATE:允许访问Wi-Fi状态的权限。
例如下面的代码。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.wifiadmin"
android:versionCode="1"
android:versionName="1.0" > <uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-permission
android:name="android.permission.ACCESS_WIFI_STATE"
/>
<uses-permission
android:name="android.permission.ACCESS_CHECKIN_PROPERTIES"
/>
<uses-permission
android:name="android.permission.WAKE_LOCK"
/>
<uses-permission
android:name="android.permission.INTERNET"
/>
<uses-permission
android:name="android.permission.CHANGE_WIFI_STATE"
/>
<uses-permission
android:name="android.permission.MODIFY_PHONE_STATE" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.wifiadmin.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application> </manifest>
14.3.2 实战演练——在Android系统中控制Wi-Fi
了解了Wi-Fi的基本知识后,下面将通过具体的演示实例来讲解在Android系统中开发Wi-Fi应用程序的流程。本实例的功能是在Android系统中控制Wi-Fi的状态。
本实例的具体实现流程如下所示。
(1)编写布局文件main.xml,具体代码如下。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="@drawable/white"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
> <TextView
android:id="@+id/myTextView1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="@drawable/blue"
android:text="@string/hello" /> <CheckBox
android:id="@+id/myCheckBox1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/str_checked"
android:textColor="@drawable/blue"
/> </LinearLayout>
(2)开始实现主程序文件control.java,具体实现流程如下。
● 创建Wi-fiManager对象mWi-FiManager01,具体代码如下。
● 定义mTextView01和mCheckBox01,分别用于显示提示文本和获取复选框的选择状态,具体代码如下。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mTextView01 = (TextView) findViewById(R.id.myTextView1);
mCheckBox01 = (CheckBox) findViewById(R.id.myCheckBox1);
● 以getSystemService取得WIFI_SERVICE,具体代码如下所示。
mWiFiManger01 = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
● 通过if语句判断运行程序后的Wi-Fi状态是否打开或处于打开中,这样便可显示对应的提示信息,具体代码如下所示。
//判断运行程序后的Wi-Fi转台是否打开或处于打开中
if(mWiFiManger01.isWifiEnabled())
{
//判断Wi-Fi状态是否“已打开”
if(mWiFiManger01.getWifiState()==WifiManager.WIFI_STATE_ENABLED){
/*若Wi-Fi已打开,将选取项打钩*/
mCheckBox01.setChecked(true);
/*更改选取项文字为关闭Wi-Fi*/
mCheckBox01.setText(R.string.str_uncheck);
}
else{
/* 若Wi-Fi未打开,将选取项勾选取消 */
mCheckBox01.setChecked(false);
/* 更改选取项文字为打开Wi-Fi */
mCheckBox01.setText(R.string.str_checked);
}
}else{
mCheckBox01.setChecked(false);
mCheckBox01.setText(R.string.str_checked);
}
● 通过mCheckBox01.setOnClickListener来捕捉CheckBox的单击事件,用onClick(View v)方法获取用户的单击,然后if语句根据操作需求执行对应的操作,并根据需要输出对应的提示信息,具体代码如下所示。
mCheckBox01.setOnClickListener(new CheckBox.OnClickListener() { @Override
public void onClick(View v) {
// TODO Auto-generated method stub /* 当选取项为取消选取状态 */
if (mCheckBox01.isChecked() == false)
{
/* 尝试关闭Wi-Fi服务 */
try {
// 判断Wi-Fi状态是否为已打开
if (mWiFiManger01.isWifiEnabled()) {
// 关闭Wi-Fi
if (mWiFiManger01.setWifiEnabled(false)) {
mTextView01
.setText(R.string.str_stop_wifi_done);
} else {
mTextView01
.setText(R.string.str_stop_wifi_failed);
}
} else {
/* Wi-Fi状态不为已打开状态时 */
switch (mWiFiManger01.getWifiState()) {
/* Wi-Fi正在打开过程中,导致无法关闭..... */
case WifiManager.WIFI_STATE_ENABLING:
mTextView01.setText(getResources().getText(
R.string.str_stop_wifi_failed)
+ ":"
+ getResources().getText(
R.string.str_wifi_enabling));
break;
/* Wi-Fi正在关闭过程中,导致无法关闭...... */
case WifiManager.WIFI_STATE_DISABLING:
mTextView01.setText(getResources().getText(
R.string.str_stop_wifi_failed)
+ ":"
+ getResources().getText(
R.string.str_wifi_disabling));
break;
/* Wi-Fi已经关闭 */
case WifiManager.WIFI_STATE_DISABLED:
mTextView01.setText(getResources().getText(
R.string.str_stop_wifi_failed)
+ ":"
+ getResources().getText(
R.string.str_wifi_disabled));
break;
/* 无法取得或辨识Wi-Fi状态 */
case WifiManager.WIFI_STATE_UNKNOWN:
default:
mTextView01.setText(getResources().getText(
R.string.str_stop_wifi_failed)
+ ":"
+ getResources().getText(
R.string.str_wifi_unknow));
break;
}
mCheckBox01.setText(R.string.str_checked);
}
} catch (Exception e) {
(3)编写文件strings.xml,在此设置了在屏幕中显示的文本内容,具体代码如下所示。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello"></string>
<string name="app_name"></string>
<string name="str_checked">打开....</string>
<string name="str_uncheck">关闭....</string>
<string name="str_start_wifi_failed">打开失败</string>
<string name="str_start_wifi_done">打开成功</string>
<string name="str_stop_wifi_failed">打开失败</string>
<string name="str_stop_wifi_done">关闭成功</string>
<string name="str_wifi_enabling">正在启动....</string>
<string name="str_wifi_disabling">正在关闭....</string>
<string name="str_wifi_disabled">已关闭</string>
<string name="str_wifi_unknow">未知....</string>
</resources>
(4)最后,在文件AndroidManifest.xml中添加对Wi-Fi的访问以及网络权限的权限,具体代码如下所示。
<uses-permission
android:name="android.permission.CHANGE_NETWORK_STATE"
/>
<uses-permission
android:name="android.permission.CHANGE_WIFI_STATE"
/>
<uses-permission
android:name="android.permission.ACCESS_NETWORK_STATE"
/>
<uses-permission
android:name="android.permission.ACCESS_WIFI_STATE"
/>
<uses-permission
android:name="android.permission.INTERNET"
/>
<uses-permission
android:name="android.permission.WAKE_LOCK"
/>
第14章 Wi-Fi系统应用 14.1 了解Wi-Fi系统的结构的更多相关文章
- 【STM32H7教程】第14章 STM32H7的电源,复位和时钟系统
完整教程下载地址:http://forum.armfly.com/forum.php?mod=viewthread&tid=86980 第14章 STM32H7的电源,复位和时钟系 ...
- ASM:《X86汇编语言-从实模式到保护模式》第14章:保护模式下的特权保护和任务概述
★PART1:32位保护模式下任务的隔离和特权级保护 这一章是全书的重点之一,这一张必须要理解特权级(包括CPL,RPL和DPL的含义)是什么,调用门的使用,还有LDT和TSS的工作原理(15章着重 ...
- 敏捷软件开发:原则、模式与实践——第14章 使用UML
第14章 使用UML 在探索UML的细节之前,我们应该先讲讲何时以及为何使用它.UML的误用和滥用已经对软件项目造成了太多的危害. 14.1 为什么建模 建模就是为了弄清楚某些东西是否可行.当模型比要 ...
- 第14章 使用DHCP动态管理主机地址
章节简述: DHCP协议服务能够自动化的管理局域网内的主机IP地址,有效的提升IP地址使用率,提高配置效率,减少管理与维护成本. 学习dhcpd服务程序的使用方法并逐条讲解配置参数,完整演示自动化分配 ...
- Linux就这个范儿 第14章 身在江湖
Linux就这个范儿 第14章 身在江湖 “有人的地方就有江湖”,如今的计算机世界就像一个“江湖”.且不说冠希哥有多么无奈,把微博当QQ的局长有多么失败,就说如此平凡的你我什么时候就成了任人摆布的羔羊 ...
- JavaScript高级程序设计(第三版)学习笔记13、14章
第13章,事件 事件冒泡 IE的事件叫做事件冒泡:由具体到不具体 <!DOCTYPE html> <html> <head> <title>E ...
- 《Android开发艺术探索》读书笔记 (13) 第13章 综合技术、第14章 JNI和NDK编程、第15章 Android性能优化
第13章 综合技术 13.1 使用CrashHandler来获取应用的Crash信息 (1)应用发生Crash在所难免,但是如何采集crash信息以供后续开发处理这类问题呢?利用Thread类的set ...
- 第14章 命令模式(Command Pattern)
原文 第14章 命令模式(Command Pattern) 命令模式(Command Pattern) 概述 在软件系统中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”.但在某些场合,比如 ...
- 【机器学习实战】第14章 利用SVD简化数据
第14章 利用SVD简化数据 SVD 概述 奇异值分解(SVD, Singular Value Decomposition): 提取信息的一种方法,可以把 SVD 看成是从噪声数据中抽取相关特征.从生 ...
随机推荐
- [Windows Server 2012] Filezilla安装方法
★ 欢迎来到[护卫神·V课堂],网站地址:http://v.huweishen.com ★ 护卫神·V课堂 是护卫神旗下专业提供服务器教学视频的网站,每周更新视频. ★ 本节我们将带领大家:FileZ ...
- vim之补全1(完全个人定制版)
关于vim的补全最初的感觉是蛋疼, 真正的蛋疼! 由于在接触linux之前曾经在windows下面学过一段时间软件开发, 那时使用的是vs2010, 现在看来虽然vs启动相当的慢, 编辑器的定制和配置 ...
- Mysql 之show status数据详解
状态名 作用域 详细解释 Aborted_clients Global 由于客户端没有正确关闭连接导致客户端终止而中断的连接数 Aborted_connects Global 试图连接到MySQL服务 ...
- 微信小程序video监测播放进度
video组件提供的进度相关的监测只有 bindtimeupdate ,官方说明这个函数250ms触发一次,在开发者工具上基本符合,但在真机上每隔1秒触发一次.达不到我们要求的精度.对比下音频,wx. ...
- Linux内核系统调用处理过程
原创作品转载请注明出处 + https://github.com/mengning/linuxkernel/ 学号末三位:168 下载并编译Linux5.0 xz -d linux-.tar.xz . ...
- JS获取图片的原始宽度和高度
页面中的img元素,想要获取它的原始尺寸,以宽度为例,可能首先想到的是元素的innerWidth属性,或者jQuery中的width()方法.如下: <img id="img" ...
- perf-perf stat用户层代码分析
perf_event 源码分析 前言 简单来说,perf是一种性能监测工具,它首先对通用处理器提供的performance counter进行编程,设定计数器阈值和事件,然后性能计数器就会在设定事件发 ...
- HDU 3152 Obstacle Course(优先队列,广搜)
题目 用优先队列优化普通的广搜就可以过了. #include<stdio.h> #include<string.h> #include<algorithm> usi ...
- Python学习【第5篇】:Python之函数(自定义函数,内置函数,装饰器,迭代器,生成器、模块)
一.为什么要使用函数? 1.避免代码重用 2.提高代码的可读性 二.函数的定义与调用 1. def 函数名(参数1,参数2): ''' 函数注释''' print('函数体') return 返回值 ...
- 线索二叉树【C语言】
#include<stdio.h> #include<stdlib.h> typedef char ElemType; typedef enum{Link,Thread} Po ...