(Android)Wifi-Direct直連


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

wifi直連也叫做wifi設備點對點連接(peer-peer),不需要連接熱點或者網絡,需要打開wifi,就可以查找到附近的設備。大概可以分為以下步驟:1.設置以下權限,並且注意最小sdk=14

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

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

 

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

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

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

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()監聽服務內容。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM