WIFI层次结构

wifi系统的上层接口包括数据部分和控制部分,数据部分通常是一个和以太网类似的网络设备,控制部分用于实现接入点操作和安全验证处理
    在软件层,wifi系统包括linux内核程序和协议,还包括本地部分,java框架类,wifi系统和java应用程序提供了控制类的接口

(ps,自己画的图,蛮丑)

Android打开wifi的代码位置 androidwifi开发_Android打开wifi的代码位置

android的wifi系统从上到下主要包括java框架类,android适配器库,wpa_supplicant守护进程,驱动程序和协议,

Android打开wifi的代码位置 androidwifi开发_网络_02

接下来步入正题, wifi开发中很重要的几个类就是WifiManager,WifiInfo,ScanResult

wifi的几个状态

从WifiManager类中我们可以看出,wifi有如下几个状态
WIFI_STATE_DISABLED:WIFI不能使用,值是:1.
WIFI_STATE_DISABLING:WIFI正在关闭中,由于WIFI关闭是需要一个过程,值是:0
WIFI_STATE_ENABLED:WIFI可以使用,值是:3.
WIFI_STATE_ENABLING:WIFI正在开启中, 值是:2.
WIFI_STATE_UNKNOWN:WIFI未知网卡状态,当手机或程序出现错误引起WIFi不可用,值是:4.

wifi有关的几个权限

<uses-permission android:name="android.permission.ACCESS_WIFI_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.CHANGE_NETWORK_STATE"/>

实战,code says anything

界面效果如图

Android打开wifi的代码位置 androidwifi开发_Android打开wifi的代码位置_03


五个Button按钮,一个TextView和一个LIstView

activity_main.xml布局文件如下

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="cn.aiyuan1996.MainActivity" >

    <Button 
        android:id="@+id/btn_open"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="打开wifi"/>
    <Button 
        android:id="@+id/btn_close"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="关闭wifi"/>
    <Button 
        android:id="@+id/btn_getwifilist"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="获取wifi列表"/>
    <Button 
        android:id="@+id/btn_getwifiinfo"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="得到wifi信息"/>
    <Button 
        android:id="@+id/btn_getwifistate"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="wifi状态"/>
    <TextView 
        android:id="@+id/tv_getwifiinfo"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    <ListView 
        android:id="@+id/lv_wifilist"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>

MainActivity.java活动如下

package cn.aiyuan1996;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {
    private Button btn_open;
    private Button btn_close;
    private Button btn_getWifiList;
    private Button btn_getWifiInfo;
    private Button btn_getWifiState;
    private TextView tv_wifiInfo;
    private ListView lv_getWifiList;
    private WifiManager wifiManager;
    private List<ScanResult>mWifiList;
    private List<String>wifiList;
    private WifiInfo wifiInfo;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
        findView();
        setListener();
    }

    private void setListener() {
        btn_open.setOnClickListener(listener);
        btn_close.setOnClickListener(listener);
        btn_getWifiList.setOnClickListener(listener);
        btn_getWifiInfo.setOnClickListener(listener);
        btn_getWifiState.setOnClickListener(listener);
    }

    OnClickListener listener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            switch (v.getId()) {
            case R.id.btn_open:
                if(!wifiManager.isWifiEnabled()){
                    wifiManager.setWifiEnabled(true);
                    Toast.makeText(MainActivity.this, "wifi已经开启", Toast.LENGTH_SHORT).show();
                }
                break;
            case R.id.btn_close:
                if(wifiManager.isWifiEnabled()){
                    wifiManager.setWifiEnabled(false);
                    Toast.makeText(MainActivity.this, "wifi已经关闭", Toast.LENGTH_SHORT).show();
                }
                break;
            case R.id.btn_getwifilist:
                //先判断wifi是否已经开启
                if(wifiManager.isWifiEnabled()){
                    wifiManager.startScan();
                    mWifiList = wifiManager.getScanResults();
                    //把mwifilist里面的内容放在wifilist里面
                    for(int i = 0;i < mWifiList.size();i++){
                        wifiList.add(mWifiList.get(i).SSID);//The network name.
                    }
                    setAdapter();

                }else {
                    Toast.makeText(MainActivity.this, "wifi没有开启,无法扫描", Toast.LENGTH_SHORT).show();
                }
                break;
            case R.id.btn_getwifiinfo:
                String SSID = wifiInfo.getSSID();
                String bssid = wifiInfo.getBSSID();//The address of the access point.
                String macAddress = wifiInfo.getMacAddress();//The mac address of the access point.
                int ipAddress = wifiInfo.getIpAddress();//The IP address of the access point.
                int netWorkId = wifiInfo.getNetworkId();//the network ID, or -1 if there is no currently connected network
                int speed = wifiInfo.getLinkSpeed();
                tv_wifiInfo.setText("目前连入的wifi是:" + SSID + "\n接入点的BSSID为:" + bssid + "\nMAC地址:" + macAddress
                        + "\nIP地址:" + ipAddress + "\n连接的ID:" + netWorkId + "\n速度:" + speed);
                break;
            case R.id.btn_getwifistate:
                int wifiState = wifiManager.getWifiState();
                Toast.makeText(MainActivity.this, "wifi状态为:" + wifiState, Toast.LENGTH_SHORT).show();
            default:
                break;
            }

        }
    };

    private void findView() {
        btn_open = (Button) findViewById(R.id.btn_open);
        btn_close = (Button) findViewById(R.id.btn_close);
        btn_getWifiList = (Button) findViewById(R.id.btn_getwifilist);
        btn_getWifiInfo = (Button) findViewById(R.id.btn_getwifiinfo);
        btn_getWifiState = (Button) findViewById(R.id.btn_getwifistate);
        tv_wifiInfo = (TextView) findViewById(R.id.tv_getwifiinfo);
        lv_getWifiList = (ListView) findViewById(R.id.lv_wifilist);
    }

    protected void setAdapter() {
        ArrayAdapter<String> adapter=new ArrayAdapter<String>
        (MainActivity.this, android.R.layout.simple_list_item_1, wifiList);
        lv_getWifiList.setAdapter(adapter);
    }

    private void init() {
        wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
        wifiInfo = wifiManager.getConnectionInfo();
        mWifiList = new ArrayList<ScanResult>();
        wifiList = new ArrayList<String>();
    }


}

当然别忘了加入与wifi有关的权限,上面有提到。

效果图

开始,我wifi关着的,wifi状态应该是1,然后按一下“wifi状态”按钮

Android打开wifi的代码位置 androidwifi开发_android_04


按钮“打开wifi”按钮

Android打开wifi的代码位置 androidwifi开发_wi-fi_05


然后按下“wifi状态”按钮,此时正在打开,应该为2

Android打开wifi的代码位置 androidwifi开发_List_06


过会儿,再点击“wifi状态”按钮,此时已经打开,应该为3

Android打开wifi的代码位置 androidwifi开发_List_07


点击“wifi列表”按钮,查看目前周围有哪些wifi

Android打开wifi的代码位置 androidwifi开发_wi-fi_08


最后,点击“wifi信息”按钮,查看当前所连接wifi的信息

Android打开wifi的代码位置 androidwifi开发_wi-fi_09

几个重要函数

判断wifi是否打开的函数

isWifiEnabled
public boolean isWifiEnabled()
Return whether Wi-Fi is enabled or disabled.

返回:true if Wi-Fi is enabled另请参见:getWifiState()

判断wifi状态的函数

getWifiState
public int getWifiState()
Ges the Wi-Fi enabled state.

返回:One of WIFI_STATE_DISABLED,
         WIFI_STATE_DISABLING, WIFI_STATE_ENABLED,
         WIFI_STATE_ENABLING, WIFI_STATE_UNKNOWN另请参见:isWifiEnabled()

开始扫描周围wifi的函数

startScan
public boolean startScan()
Request a scan for access points. Returns immediately. The availability
 of the results is made known later by means of an asynchronous event sent
 on completion of the scan.

返回:true if the operation succeeded, i.e., the scan was initiated

得到扫描结果的函数

getScanResults
public List<ScanResult> getScanResults()
Return the results of the latest access point scan.

返回:the list of access points found in the most recent scan.

设置打开或关闭wifi的函数

setWifiEnabled
public boolean setWifiEnabled(boolean enabled)
Enable or disable Wi-Fi.

参数:enabled - true to enable, false to disable.
返回:true if the operation succeeds (or if the existing state
         is the same as the requested state).

得到IP地址的函数

public int getIpAddress()

得到连接速度的函数

public int getLinkSpeed()

得到mac地址的函数

public String getMacAddress()

得到wifi名字的函数

public String getSSID()
Returns the service set identifier (SSID) of the current 802.11 network. If the SSID is an ASCII string, it will be returned surrounded by double quotation marks.Otherwise, it is returned as a string of hex digits. The SSID may be null if there is no network currently connected.

得到BSSID的函数

public String getBSSID()
Return the basic service set identifier (BSSID) of the current access point. The BSSID may be null if there is no network currently connected.

得到信号强度的函数

public int getRssi()
Returns the received signal strength indicator of the current 802.11 network. 
This is not normalized, but should be!