第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"
        />

 

posted on 2017-09-22 16:46  绿茵好莱坞  阅读(343)  评论(0编辑  收藏  举报

导航