1. 程式人生 > >Android 藍芽通訊及WiFi開發

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
<uses-feature android:name="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<WifiConfiguration> mWifiConfiguration; //無線網路配置資訊類集合(網路連線列表)
    private List<ScanResult> 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<WifiConfiguration> 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<ScanResult> 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();  
        }  
    }