Android 蓝牙通信及WiFi开发

在我们正常的Android蓝牙功能开发步骤中,一般要经过系统权限和蓝牙开关状态监测、设备扫描、设备连接、蓝牙数据通信这几个过程。
在Android 4.3系统之后,我们可以使用蓝牙4.0(低功耗蓝牙),它最主要的特点是低功耗,普及率高。现在所说的蓝牙设备,大部分都是在说4.0设备,ble也特指4.0设备。 在4.0之前重要的版本有2.1版本-基本速率/增强数据率(BR/EDR)和3.0 高速蓝牙版本,这些统称为经典蓝牙。

如果想让支持低功耗蓝牙的设备使用蓝牙4.0,我们可以通过如下代码去监测

// AndroidManifest.xml
"android.hardware.bluetooth_le" android:required="false"/>

if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
    Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
    finish();
}

权限监测

首先我们必须要给予应用相应的蓝牙权限。

    //需要此权限来执行任何蓝牙通信,如请求一个连接、接受一个连接和传输数据。
    <uses-permission android:name="android.permission.BLUETOOTH"/>
    //如果你想让你的应用启动设备发现或操纵蓝牙设置,必须申报bluetooth_admin许可
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

然后在程序启动时监测当前设备是否已经打开蓝牙,若没打开则跳转到系统蓝牙功能开关界面选择开启蓝牙

 // If BT is not on, request that it be enabled.
        // setupChat() will then be called during onActivityResult
        if (!mBluetoothAdapter.isEnabled()) {
            Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
            // Otherwise, setup the chat session
        } else if (mChatService == null) {
            setupChat();
        }

在onActivityResult中捕获

public void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            case REQUEST_ENABLE_BT:
                // When the request to enable Bluetooth returns
                if (resultCode == Activity.RESULT_OK) {
                    // Bluetooth is now enabled, so set up a chat session
                    setupChat();
                } else {
                    // User did not enable Bluetooth or an error occurred
                    Log.d(TAG, "BT not enabled");
                    Toast.makeText(getActivity(), R.string.bt_not_enabled_leaving,
                            Toast.LENGTH_SHORT).show();
                    getActivity().finish();
                }
        }
    }

设备扫描

我们只需要调用BluetoothAdapter的startDiscovery()方法,便开始搜索附近的其他蓝牙设备,

 /**
     * Start device discover with the BluetoothAdapter
     */
    private void doDiscovery() {
        // If we're already discovering, stop it
        if (mBtAdapter.isDiscovering()) {
            mBtAdapter.cancelDiscovery();
        }

        // Request discover from BluetoothAdapter
        mBtAdapter.startDiscovery();
    }

之后,如果搜索到一个蓝牙设备,系统就是发出一个广播,我们可以对它进行接收并且进行相应的处理:

 // Register for broadcasts when a device is discovered
        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        this.registerReceiver(mReceiver, filter);

        // Register for broadcasts when discovery has finished
        filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        this.registerReceiver(mReceiver, filter);
/**
     * The BroadcastReceiver that listens for discovered devices and changes the title when
     * discovery is finished
     */
    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            // When discovery finds a device
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                // Get the BluetoothDevice object from the Intent
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                // If it's already paired, skip it, because it's been listed already
                if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
                    mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
                }
                // When discovery is finished, change the Activity title
            } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                setProgressBarIndeterminateVisibility(false);
                setTitle(R.string.select_device);
                if (mNewDevicesArrayAdapter.getCount() == 0) {
                    //do something here after finished discovery
                }
            }
        }
    };

连接

在搜索到的其它设备里选择一个需要连接通信的设备,传入设备的地址,调用getRemoteDevice方法去获得一个BluetoothDevice 实例,然后开辟一个子线程用于建立连接,

private void connectDevice(Intent data, boolean secure) {
        // Get the device MAC address
        String address = data.getExtras()
                .getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
        // Get the BluetoothDevice object
        BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
        // Attempt to connect to the device
        mChatService.connect(device, secure);
    }
/**
     * Start the ConnectThread to initiate a connection to a remote device.
     *
     * @param device The BluetoothDevice to connect
     * @param secure Socket Security type - Secure (true) , Insecure (false)
     */
    public synchronized void connect(BluetoothDevice device, boolean secure) {
        Log.d(TAG, "connect to: " + device);

        // Cancel any thread attempting to make a connection
        if (mState == STATE_CONNECTING) {
            if (mConnectThread != null) {
                mConnectThread.cancel();
                mConnectThread = null;
            }
        }

        // Cancel any thread currently running a connection
        if (mConnectedThread != null) {
            mConnectedThread.cancel();
            mConnectedThread = null;
        }

        // Start the thread to connect with the given device
        mConnectThread = new ConnectThread(device, secure);
        mConnectThread.start();
        // Update UI 
    }

连接线程:此处调用了device.createRfcommSocketToServiceRecord方法去创建一个用于通信的socket,参数是UUID,是一个通用标识符。

private class ConnectThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final BluetoothDevice mmDevice;
        private String mSocketType;

        public ConnectThread(BluetoothDevice device, boolean secure) {
            mmDevice = device;
            BluetoothSocket tmp = null;
            mSocketType = secure ? "Secure" : "Insecure";

            // Get a BluetoothSocket for a connection with the
            // given BluetoothDevice
            try {
                if (secure) {
                    tmp = device.createRfcommSocketToServiceRecord(
                            MY_UUID_SECURE);
                } else {
                    tmp = device.createInsecureRfcommSocketToServiceRecord(
                            MY_UUID_INSECURE);
                }
            } catch (IOException e) {
                Log.e(TAG, "Socket Type: " + mSocketType + "create() failed", e);
            }
            mmSocket = tmp;
            mState = STATE_CONNECTING;
        }

        public void run() {
            Log.i(TAG, "BEGIN mConnectThread SocketType:" + mSocketType);
            setName("ConnectThread" + mSocketType);

            // Always cancel discovery because it will slow down a connection
            mAdapter.cancelDiscovery();

            // Make a connection to the BluetoothSocket
            try {
                // This is a blocking call and will only return on a
                // successful connection or an exception
                mmSocket.connect();
            } catch (IOException e) {
                // Close the socket
                try {
                    mmSocket.close();
                } catch (IOException e2) {
                    Log.e(TAG, "unable to close() " + mSocketType +
                            " socket during connection failure", e2);
                }
                connectionFailed();
                return;
            }

            // Reset the ConnectThread because we're done
            synchronized (BluetoothChatService.this) {
                mConnectThread = null;
            }

            // Start the connected thread
            connected(mmSocket, mmDevice, mSocketType);
        }

        public void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) {
                Log.e(TAG, "close() of connect " + mSocketType + " socket failed", e);
            }
        }
    }

设备连接完成后,要取消连接线程,防止造成资源的浪费,然后创建通信线程,维持输入输出流的接收和发送。

public synchronized void connected(BluetoothSocket socket, BluetoothDevice
            device, final String socketType) {
        Log.d(TAG, "connected, Socket Type:" + socketType);

        // Cancel the thread that completed the connection
        if (mConnectThread != null) {
            mConnectThread.cancel();
            mConnectThread = null;
        }


        // Start the thread to manage the connection and perform transmissions
        mConnectedThread = new ConnectedThread(socket, socketType);
        mConnectedThread.start();

        // Send the name of the connected device back to the UI Activity
        Message msg = mHandler.obtainMessage(Constants.MESSAGE_DEVICE_NAME);
        Bundle bundle = new Bundle();
        bundle.putString(Constants.DEVICE_NAME, device.getName());
        msg.setData(bundle);
        mHandler.sendMessage(msg);
        // Update UI title
        updateUserInterfaceTitle();
    }

消息传输线程:run方法是一个while循环,当处于连接状态时,会一直从输入流中获取数据,并将获取到的字节数据通过handle机制传输到主线程并显示。在需要发送数据时,只要调用write方法即可。

/**
     * This thread runs during a connection with a remote device.
     * It handles all incoming and outgoing transmissions.
     */
    private class ConnectedThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final InputStream mmInStream;
        private final OutputStream mmOutStream;

        public ConnectedThread(BluetoothSocket socket, String socketType) {
            Log.d(TAG, "create ConnectedThread: " + socketType);
            mmSocket = socket;
            InputStream tmpIn = null;
            OutputStream tmpOut = null;

            // Get the BluetoothSocket input and output streams
            try {
                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();
            } catch (IOException e) {
                Log.e(TAG, "temp sockets not created", e);
            }

            mmInStream = tmpIn;
            mmOutStream = tmpOut;
            mState = STATE_CONNECTED;
        }

        public void run() {
            Log.i(TAG, "BEGIN mConnectedThread");
            byte[] buffer = new byte[1024];
            int bytes;

            // Keep listening to the InputStream while connected
            while (mState == STATE_CONNECTED) {
                try {
                    // Read from the InputStream
                    bytes = mmInStream.read(buffer);

                    // Send the obtained bytes to the UI Activity
                    mHandler.obtainMessage(Constants.MESSAGE_READ, bytes, -1, buffer)
                            .sendToTarget();
                } catch (IOException e) {
                    Log.e(TAG, "disconnected", e);
                    connectionLost();
                    break;
                }
            }
        }

        /**
         * Write to the connected OutStream.
         *
         * @param buffer The bytes to write
         */
        public void write(byte[] buffer) {
            try {
                mmOutStream.write(buffer);

                // Share the sent message back to the UI Activity
                mHandler.obtainMessage(Constants.MESSAGE_WRITE, -1, -1, buffer)
                        .sendToTarget();
            } catch (IOException e) {
                Log.e(TAG, "Exception during write", e);
            }
        }

        public void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) {
                Log.e(TAG, "close() of connect socket failed", e);
            }
        }
    }

至此,通过蓝牙实现数据传输的过程基本建立完毕。此处是针对普通蓝牙的通信方式,若使用低功耗蓝牙,可详见Google的官方sample:
android-BuletoothLeGatt

AndroidWiFi学习

一、WiFi相关知识

Android WiFi开发需掌握基本的操作,包括扫描附近WiFi、控制WiFi的开闭、发射WiFi热点等。
在Android的sdk中, WiFi相关的操作类都在Android.net.wifi包里面。接下来就跟随官方Guide来学习Android中WiFi的基本操作。
Google开发者中国网站api

其中主要的类有ScanResult ,wifiConfiguration, WifiInfo ,WifiManager。

ScanResult

主要用来描述已经检测出的接入点,包括接入点的地址,接入点的名称,身份认证,频率,信号强度等信息。
打开这个类,我们可以看到以下几个信息

  • BSSID 接入点的地址,这里主要是指小范围几个无线设备相连接所获取的地址,比如说两台笔记本通过无线网卡进行连接,双方的无线网卡分配的地址。
  • SSID 网络的名字,当我们搜索一个网络时,就是靠这个来区分每个不同的网络接入点。
  • Capabilities 网络接入的性能,这里主要是来判断网络的加密方式等。
  • Frequency 频率,每一个频道交互的MHz 数。
  • Level 等级,主要来判断网络连接的优先数。

wifiConfiguration

包括以下六个子类:

  • WifiConfiguration.AuthAlgorthm 用来判断加密方法。
  • WifiConfiguration.GroupCipher 获取使用GroupCipher 的方法来进行加密。
  • WifiConfiguration.KeyMgmt 获取使用KeyMgmt 进行。
  • WifiConfiguration.PairwiseCipher 获取使用WPA 方式的加密。
  • WifiConfiguration.Protocol 获取使用哪一种协议进行加密。
  • wifiConfiguration.Status 获取当前网络的状态。

WifiInfo

在我们的wifi 已经连通了以后,可以通过这个类获得一些已经连通的wifi 连接的信息获取当前链接的信息.

  • getBSSID(): 获取BSSID
  • getDetailedStateOf() : 获取客户端的连通性
  • getHiddenSSID() : 获得SSID 是否被隐藏
  • getIpAddress() : 获取IP 地址
  • getLinkSpeed() : 获得连接的速度
  • getMacAddress() : 获得Mac 地址
  • getRssi() 获得802.11n : 网络的信号
  • getSSID() : 获得SSID
  • getSupplicanState() : 返回具体客户端状态的信息

wifiManager

这个类提供了WiFi连接的管理功能,我们可以调用Context.getSystemService(Context.WIFI_SERVICE)来获取,常用方法如下:

  • addNetwork(WifiConfiguration config) 通过获取到的网络的链接状态信息,来添加网络
  • calculateSignalLevel(int rssi , int numLevels) 计算信号的等级
  • compareSignalLevel(int rssiA, int rssiB) 对比连接A 和连接B
  • createWifiLock(int lockType, String tag) 创建一个wifi 锁,锁定当前的wifi 连接
  • disableNetwork(int netId) 让一个网络连接失效
  • disconnect() 断开连接
  • enableNetwork(int netId, Boolean disableOthers) 连接一个连接
  • getConfiguredNetworks() 获取网络连接的状态
  • getConnectionInfo() 获取当前连接的信息
  • getDhcpInfo() 获取DHCP 的信息
  • getScanResulats() 获取扫描测试的结果
  • getWifiState() 获取一个wifi 接入点是否有效
  • isWifiEnabled() 判断一个wifi 连接是否有效
  • pingSupplicant() ping 一个连接,判断是否能连通
  • ressociate() 即便连接没有准备好,也要连通
  • reconnect() 如果连接准备好了,连通
  • removeNetwork() 移除某一个网络
  • saveConfiguration() 保留一个配置信息
  • setWifiEnabled() 让一个连接有效
  • startScan() 开始扫描
  • updateNetwork(WifiConfiguration config) 更新一个网络连接的信息
    详细api见官方api

二、WiFi功能使用

配置WiFi权限

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>

WiFi管理类

这是从网上整理的一个WiFi相关的工具类,WiFi开发的很多场景需要用到的方法都在里面实现了。

/**
 * WIFI管理类
 * @author ZHF
 *
 */
public class WifiAdmin {
    private static  WifiAdmin wifiAdmin = null;

    private List mWifiConfiguration; //无线网络配置信息类集合(网络连接列表)
    private List mWifiList; //检测到接入点信息类 集合

    //描述任何Wifi连接状态
    private WifiInfo mWifiInfo;

    WifiManager.WifiLock mWifilock; //能够阻止wifi进入睡眠状态,使wifi一直处于活跃状态
    public WifiManager mWifiManager;

    /**
     * 获取该类的实例(懒汉)
     * @param context
     * @return
     */
    public static WifiAdmin getInstance(Context context) {
        if(wifiAdmin == null) {
            wifiAdmin = new WifiAdmin(context);
            return wifiAdmin;
        }
        return null;
    }
    private WifiAdmin(Context context) {
        //获取系统Wifi服务   WIFI_SERVICE
        this.mWifiManager = (WifiManager) context.getSystemService("wifi");
        //获取连接信息
        this.mWifiInfo = this.mWifiManager.getConnectionInfo();
    }

    /**
     * 是否存在网络信息
     * @param str  热点名称
     * @return
     */
    private WifiConfiguration isExsits(String str) {
        Iterator localIterator = this.mWifiManager.getConfiguredNetworks().iterator();
        WifiConfiguration localWifiConfiguration;
        do {
            if(!localIterator.hasNext()) return null;
            localWifiConfiguration = (WifiConfiguration) localIterator.next();
        }while(!localWifiConfiguration.SSID.equals("\"" + str + "\""));
        return localWifiConfiguration;
    }

    /**锁定WifiLock,当下载大文件时需要锁定 **/
    public void AcquireWifiLock() {
        this.mWifilock.acquire();
    }
    /**创建一个WifiLock**/
    public void CreateWifiLock() {
        this.mWifilock = this.mWifiManager.createWifiLock("Test");
    }
    /**解锁WifiLock**/
    public void ReleaseWifilock() {
        if(mWifilock.isHeld()) { //判断时候锁定
            mWifilock.acquire();
        }
    }


    /**打开Wifi**/
    public void OpenWifi() {
        if(!this.mWifiManager.isWifiEnabled()){ //当前wifi不可用
            this.mWifiManager.setWifiEnabled(true);
        }
    }
    /**关闭Wifi**/
    public void closeWifi() {
        if(mWifiManager.isWifiEnabled()) {
            mWifiManager.setWifiEnabled(false);
        }
    }
    /**端口指定id的wifi**/
    public void disconnectWifi(int paramInt) {
        this.mWifiManager.disableNetwork(paramInt);
    }

    /**添加指定网络**/
    public void addNetwork(WifiConfiguration paramWifiConfiguration) {
        int i = mWifiManager.addNetwork(paramWifiConfiguration);
        mWifiManager.enableNetwork(i, true);
    }

    /**
     * 连接指定配置好的网络
     * @param index 配置好网络的ID
     */
    public void connectConfiguration(int index) { 
        // 索引大于配置好的网络索引返回  
        if (index > mWifiConfiguration.size()) { 
            return; 
        } 
        //连接配置好的指定ID的网络  
        mWifiManager.enableNetwork(mWifiConfiguration.get(index).networkId, true); 
    }

    /**
     * 根据wifi信息创建或关闭一个热点
     * @param paramWifiConfiguration
     * @param paramBoolean 关闭标志
     */
    public void createWifiAP(WifiConfiguration paramWifiConfiguration,boolean paramBoolean) {
        try {
            Class localClass = this.mWifiManager.getClass();
            Class[] arrayOfClass = new Class[2];
            arrayOfClass[0] = WifiConfiguration.class;
            arrayOfClass[1] = Boolean.TYPE;
            Method localMethod = localClass.getMethod("setWifiApEnabled",arrayOfClass);
            WifiManager localWifiManager = this.mWifiManager;
            Object[] arrayOfObject = new Object[2];
            arrayOfObject[0] = paramWifiConfiguration;
            arrayOfObject[1] = Boolean.valueOf(paramBoolean);
            localMethod.invoke(localWifiManager, arrayOfObject);
            return;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 创建一个wifi信息
     * @param ssid 名称
     * @param passawrd 密码
     * @param paramInt 有3个参数,1是无密码,2是简单密码,3是wap加密
     * @param type 是"ap"还是"wifi"
     * @return
     */
    public WifiConfiguration createWifiInfo(String ssid, String passawrd,int paramInt, String type) {
        //配置网络信息类
        WifiConfiguration localWifiConfiguration1 = new WifiConfiguration();
        //设置配置网络属性
        localWifiConfiguration1.allowedAuthAlgorithms.clear();
        localWifiConfiguration1.allowedGroupCiphers.clear();
        localWifiConfiguration1.allowedKeyManagement.clear();
        localWifiConfiguration1.allowedPairwiseCiphers.clear();
        localWifiConfiguration1.allowedProtocols.clear();

        if(type.equals("wt")) { //wifi连接
            localWifiConfiguration1.SSID = ("\"" + ssid + "\"");
            WifiConfiguration localWifiConfiguration2 = isExsits(ssid);
            if(localWifiConfiguration2 != null) {
                mWifiManager.removeNetwork(localWifiConfiguration2.networkId); //从列表中删除指定的网络配置网络
            }
            if(paramInt == 1) { //没有密码
                localWifiConfiguration1.wepKeys[0] = "";
                localWifiConfiguration1.allowedKeyManagement.set(0);
                localWifiConfiguration1.wepTxKeyIndex = 0;
            } else if(paramInt == 2) { //简单密码
                localWifiConfiguration1.hiddenSSID = true;
                localWifiConfiguration1.wepKeys[0] = ("\"" + passawrd + "\"");
            } else { //wap加密
                localWifiConfiguration1.preSharedKey = ("\"" + passawrd + "\"");
                localWifiConfiguration1.hiddenSSID = true;
                localWifiConfiguration1.allowedAuthAlgorithms.set(0);
                localWifiConfiguration1.allowedGroupCiphers.set(2);
                localWifiConfiguration1.allowedKeyManagement.set(1);
                localWifiConfiguration1.allowedPairwiseCiphers.set(1);
                localWifiConfiguration1.allowedGroupCiphers.set(3);
                localWifiConfiguration1.allowedPairwiseCiphers.set(2);
            }
        }else {//"ap" wifi热点
            localWifiConfiguration1.SSID = ssid;
            localWifiConfiguration1.allowedAuthAlgorithms.set(1);
            localWifiConfiguration1.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
            localWifiConfiguration1.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
            localWifiConfiguration1.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
            localWifiConfiguration1.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
            localWifiConfiguration1.allowedKeyManagement.set(0);
            localWifiConfiguration1.wepTxKeyIndex = 0;
            if (paramInt == 1) {  //没有密码
                localWifiConfiguration1.wepKeys[0] = "";
                localWifiConfiguration1.allowedKeyManagement.set(0);
                localWifiConfiguration1.wepTxKeyIndex = 0;
            } else if (paramInt == 2) { //简单密码
                localWifiConfiguration1.hiddenSSID = true;//网络上不广播ssid
                localWifiConfiguration1.wepKeys[0] = passawrd;
            } else if (paramInt == 3) {//wap加密
                localWifiConfiguration1.preSharedKey = passawrd;
                localWifiConfiguration1.allowedAuthAlgorithms.set(0);
                localWifiConfiguration1.allowedProtocols.set(1);
                localWifiConfiguration1.allowedProtocols.set(0);
                localWifiConfiguration1.allowedKeyManagement.set(1);
                localWifiConfiguration1.allowedPairwiseCiphers.set(2);
                localWifiConfiguration1.allowedPairwiseCiphers.set(1);
            }
        }
        return localWifiConfiguration1;
    }

    /**获取热点名**/
    public String getApSSID() {
        try {
            Method localMethod = this.mWifiManager.getClass().getDeclaredMethod("getWifiApConfiguration", new Class[0]);
            if (localMethod == null) return null;
            Object localObject1 = localMethod.invoke(this.mWifiManager,new Object[0]);
            if (localObject1 == null) return null;
            WifiConfiguration localWifiConfiguration = (WifiConfiguration) localObject1;
            if (localWifiConfiguration.SSID != null) return localWifiConfiguration.SSID;
            Field localField1 = WifiConfiguration.class .getDeclaredField("mWifiApProfile");
            if (localField1 == null) return null;
            localField1.setAccessible(true);
            Object localObject2 = localField1.get(localWifiConfiguration);
            localField1.setAccessible(false);
            if (localObject2 == null)  return null;
            Field localField2 = localObject2.getClass().getDeclaredField("SSID");
            localField2.setAccessible(true);
            Object localObject3 = localField2.get(localObject2);
            if (localObject3 == null) return null;
            localField2.setAccessible(false);
            String str = (String) localObject3;
            return str;
        } catch (Exception localException) {
        }
        return null;
    }

    /**获取wifi名**/
    public String getBSSID() {
        if (this.mWifiInfo == null)
            return "NULL";
        return this.mWifiInfo.getBSSID();
    }

   /**得到配置好的网络 **/
    public List getConfiguration() {
        return this.mWifiConfiguration;
    }

    /**获取ip地址**/
    public int getIPAddress() {
        return (mWifiInfo == null) ? 0 : mWifiInfo.getIpAddress();
    }
    /**获取物理地址(Mac)**/
    public String getMacAddress() {
         return (mWifiInfo == null) ? "NULL" : mWifiInfo.getMacAddress();
    }   

    /**获取网络id**/
    public int getNetworkId() {
         return (mWifiInfo == null) ? 0 : mWifiInfo.getNetworkId();
    }
    /**获取热点创建状态**/
    public int getWifiApState() {
        try {
            int i = ((Integer) this.mWifiManager.getClass()
                    .getMethod("getWifiApState", new Class[0])
                    .invoke(this.mWifiManager, new Object[0])).intValue();
            return i;
        } catch (Exception localException) {
        }
        return 4;   //未知wifi网卡状态
    }
    /**获取wifi连接信息**/
    public WifiInfo getWifiInfo() {
        return this.mWifiManager.getConnectionInfo();
    }
    /** 得到网络列表**/
    public List getWifiList() {
        return this.mWifiList;
    }

    /**查看扫描结果**/
    public StringBuilder lookUpScan() {
        StringBuilder localStringBuilder = new StringBuilder();
        for (int i = 0; i < mWifiList.size(); i++)
        {
            localStringBuilder.append("Index_"+new Integer(i + 1).toString() + ":");
            //将ScanResult信息转换成一个字符串包
            //其中把包括:BSSID、SSID、capabilities、frequency、level
            localStringBuilder.append((mWifiList.get(i)).toString());
            localStringBuilder.append("\n");
        }
        return localStringBuilder;
    }

    /** 设置wifi搜索结果 **/
    public void setWifiList() {
        this.mWifiList = this.mWifiManager.getScanResults();
    }
    /**开始搜索wifi**/
    public void startScan() {
        this.mWifiManager.startScan();
    }
    /**得到接入点的BSSID**/
    public String GetBSSID() {
        return (mWifiInfo == null) ? "NULL" : mWifiInfo.getBSSID();
    }
}

WiFi热点的创建

创建WiFi热点需要先获取到wifi的服务,再配置热点名称、密码等等,然后再通过反射调用setWifiApEnabled方法来创建热点。因为wifi和热点不能同时打开,所以打开热点的时候需要调用wifiManager.setWifiEnabled(false); 关闭wifi

 public void stratWifiAp() {  
        Method method1 = null;  
        try {  
            method1 = mWifiManager.getClass().getMethod("setWifiApEnabled",  
                    WifiConfiguration.class, boolean.class);  
            WifiConfiguration netConfig = new WifiConfiguration();  

            netConfig.SSID = mSSID;  
            netConfig.preSharedKey = mPasswd;  

            netConfig.allowedAuthAlgorithms  
                    .set(WifiConfiguration.AuthAlgorithm.OPEN);  
            netConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN);  
            netConfig.allowedProtocols.set(WifiConfiguration.Protocol.WPA);  
            netConfig.allowedKeyManagement  
                    .set(WifiConfiguration.KeyMgmt.WPA_PSK);  
            netConfig.allowedPairwiseCiphers  
                    .set(WifiConfiguration.PairwiseCipher.CCMP);  
            netConfig.allowedPairwiseCiphers  
                    .set(WifiConfiguration.PairwiseCipher.TKIP);  
            netConfig.allowedGroupCiphers  
                    .set(WifiConfiguration.GroupCipher.CCMP);  
            netConfig.allowedGroupCiphers  
                    .set(WifiConfiguration.GroupCipher.TKIP);  

            method1.invoke(mWifiManager, netConfig, true);  

        } catch (IllegalArgumentException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (IllegalAccessException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (InvocationTargetException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (SecurityException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (NoSuchMethodException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
    }  

参考文章:
Android开发之蓝牙通信
Android BulutoothChat
Android中WiFi开发总结

你可能感兴趣的:(Android开发)