第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 看成是从噪声数据中抽取相关特征.从生 ...
随机推荐
- 解决springmvc返回json中文乱码
在pringmvc中通过设置@ResponseBody返回json乱码问题,这个问题上网找了很久,发现答案真是人云亦云,奉上我的解决方案: 解决方案一:需要导入 jackson-core-asl-1. ...
- .mm c++ oc 混编
When you create a static library you don't link in the dependent libraries. As a result, when you re ...
- Django中 基于form的注册,基于ajax的登录
1 form.py中写register的的form组件 from django import forms class Register(forms.Form): # 注册的form username ...
- CAD绘制一个直径标注(com接口VB语言)
主要用到函数说明: _DMxDrawX::DrawDimDiametric 绘制一个直径标注.详细说明如下: 参数 说明 DOUBLE dChordPointX 在被标注的曲线上的第一个点X值 DOU ...
- ubuntu14.04远程软件VNC的安装、设置方法
ubuntu中VNCX11開機啟動保持靜默狀態方法: 1首先安裝vncx11. 2.設置vnc密碼,會自動保存在/home/test/.vnc/passwd中 3.將密碼複製到/etc中 4.在/et ...
- Python-程序的控制结构
程序的分支结构 >单分支结构 根据判断条件结果而选择不同向前路径的运行方式 if <条件>: <语句块> 代码示例: guess = eval(input()) if g ...
- HDU 3401 Trade
Trade Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID: 3401 ...
- 清北学堂模拟赛d5t6 cube
题面有误!10,11,12操作类别为A,13,14,15类别为B,16,17,18类别为C. 分析:一道大暴力,每次记录一下走了多少步,上一步操作类别是啥就可以了.最后只需要写6种操作,每一次操作进行 ...
- java 多线程面试题
1.什么是线程? 线程是操作系统能够运行的最小调度单位,他被包含在进程中,是进程中实际运作的单位. 2.线程和进程的区别 线程是进程的子集,一个进程有很多线程,每个线程执行不同的任务,不同的进程使用不 ...
- java.lang.ClassFormatError: Unknown constant tag 0 in class file
在通过文件上传之后,运行java程序,突然发现这么一个错误:java.lang.ClassFormatError: Unknown constant tag 0 in class file,通过网上查 ...