(Android)Wifi-Direct直連

因項目須要Pad端和手機端交互,採用wifi直連。查閱資料,大概寫下一些資料和收穫吧。注:大公司的代碼帶不出來,我也比較懶不想再認真去寫一遍了,因此大概這個意思哦。api

wifi直連也叫作wifi設備點對點鏈接(peer-peer),不須要鏈接熱點或者網絡,須要打開wifi,就能夠查找到附近的設備。大概能夠分爲如下步驟:1.設置如下權限,而且注意最小sdk=14網絡

2.建立一個廣播接收器,經過建立IntentFilter來addAction獲得各個特定事件的發生來進行回調.app

建立一個新的 BroadcastReceiver 類,用來監聽系統的Wi-Fi P2P狀態的改變(在 onReceive方法中,添加一個條件來處理上面列出的各類P2P狀態的變動。)異步

 

最後,在主活動激活時,註冊意圖過濾器(Intent Filter)和廣播接收器;在主活動暫停時把它們註銷。最好在onResume()和onPause()方法中完成該操做。函數

3.初始化獲得WifiP2pManager和Channel實例,在onCreate()方法中初始化,若是是在Fragment中,initialize參數用Looper.getMainLooper(),oop

4.初始化搜索,只初始化了對等點的搜索。discoverPeers()方法啓動了搜索線程,並馬上返回。系統經過調用給定的動做監聽器的方法來進行初始化,並會在成功初始化對等點進程時通知你。同時,搜索也會持續進行,直到一個鏈接被初始化,或者一個P2P組造成。spa

5.獲取搜索到設備列表, 獲取對等點的列表並進行處理,首先實現 WifiP2pManager.PeerListListener 接口,它提供了Wi-Fi Direct檢測到的對等點信息。注:在公司當時我是在這個方法裏實現自動鏈接,保存到sharedPreference,而後若是有搜索到相同的設備名和地址,代碼就不寫出來了,有更好的想法的能夠說下。線程

 

在廣播onReceive()方法中以便在收到一個帶有 WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION 動做的意圖(Intent)時調用 requestPeers方法。把實現PeerListListener的類做爲方法參數傳進去進行監聽器回調。設計

6.鏈接(後面具體說)這個是重點哦對象

爲了鏈接一個對等點,須要先建立一個新的 WifiP2pConfig 對象,而後從表明你想鏈接的設備的 WifiP2pDevice 中拷貝數據進去。再調用 connect 方法。而後項目需求是Pad端必定要做爲group owner,這時候config.groupOwnerIntent = 15,增長這句話並不能必定做爲group owner,只是一個建議。

 

         WifiP2pConfig config = new WifiP2pConfig();
                        config.deviceAddress = device.deviceAddress;
                        config.wps.setup = WpsInfo.PBC;

 爲了兼容傳統的Wifi設備,Wifi_Direct其實還存在另外一種使用方 式,暫且稱爲兼容模式。兼容模式的特色在於,只須要擔任GroupOwner的設備支持Wifi_Direct,而其餘設備只須要支持傳統的Wifi就能夠了(我的以爲其實這種使用模式很像Android的便攜熱點功能)。

         操做流程爲:
         1. 支持Wifi_Direct的設備建立group,WifiP2pManager.createGroup(),成爲GroupOwner
         2.  其餘設備掃描Wifi_Direct設備建立group後產生的Wifi熱點並鏈接便可。
  
         兼容模式存在的一個問題是:由於做爲group member的設備是使用Wifi硬件接入到group中,因此會致使member進行wifi 熱點切換以及網絡中斷,可能對正在進行的網絡操做形成影響,而group owner則不存在這個問題。另外,而WifiP2p配對的使用方式,WifiP2p和Wifi能夠獨立運做,相互不受影響。
          可是,兼容模式由於省去了掃描和配對的過程,因此創建鏈接的成功率明顯提高,而且創建鏈接的速度要快很多(具體時間比較隨機)。
          從我的的使用感受來說,這WifiP2p這套API接口高度的異步化,API都須要以回調的方式獲取操做結果(包內interface比較多的緣由就在於 此)。更加麻煩的是,幾個關鍵API(例如WifiP2pManager.connect)的回調獲取到的結果僅僅是執行是否開始,真正的結果還得註冊 broadcast receiver,經過監聽廣播來得到,才能進行下一步操做。異步的設計提升了代碼的邏輯複雜度。

 

7.鏈接信息獲取要監聽鏈接狀態的變動,須要實現 WifiP2pManager.ConnectionInfoListener 接口,回調函數 onConnectionInfoAvailable將會在鏈接狀態改變時通知。

 

回到廣播接收器的onReceive方法中,修改監聽WIFI_P2P_CONNECTION_CHANGED_ACTION的部分。收到該意圖(Intent)時,調用 requestConnectionInfo。這是一個異步的調用,因此結果會傳給做爲參數的鏈接信息監聽器。

8.斷連

removeGroup是移除羣組,斷連全部設備。

 

cancelConnect是取消鏈接狀態爲Invited的設備

一些問題:

如何得到WifiP2pGroupInfo,它有什麼用?

WifiP2pManager.requestGroupInfo()函數,能夠獲取GroupInfo,較爲有用的api有:
1. GroupInfo.getClientList()能夠得到鏈接到group的member列表
2. GroupInfo.getNetWorkName()能夠得到group的wifi熱點名稱(SSID)
3. GroupInfo.getPassphrase() 能夠得到鏈接到wifi 熱點的密碼
 
如何防止配對產生的提示框?
在不修改framework的狀況下,本人暫時爲找到可行的方案。
這個提示狂是由系統提供的,具體表現視設備而定。nexus只在第一次配對的時候彈出,而A80每一次配對都會彈出。
可是,使用兼容模式使用Wifi_Direct是沒有提示框的。
 
7. WifiP2pManager.discovePeers 僅僅返回附近有哪些設備開啓了wifi p2p,而app的實際使用場景,每每但願尋找能夠提供某些特定服務的設備。例如同一房間內,有A,B,C,D四臺設備開啓了wifi p2p,而A設備和B設備都安裝了app1,C設備和D設備都安裝了app2,使用者但願A設備能和B設備配對鏈接,而C設備與D設備鏈接,運行在A設備 上的app1如何識別它應該鏈接的是B設備,而非C、D設備呢?

爲了支持更加個性化的設備發現,WifiP2pManager支持UPNP和DNS兩種方式的設備(服務?)發現。
App能夠經過WifiP2pManager.addLocalService來向周邊的設備廣播本身支持哪些服務。
也能夠經過以下步驟實現發現這些服務:
1. 經過WifiP2pManager.addServiceRequest()添加服務請求
2. 經過WifiP2pManager.discoverService()開始服務發現
3. 經過WifiP2pManager.setDnsSdResponseListener()或者WifiP2pManager.setUpnpServiceResponseListener()監聽服務內容。
相關文章
相關標籤/搜索