Android官方开发文档Training系列课程中文版:连接无线设备之通过P2P搜索网络服务
原文地址:http://android.xsoftlab.net/training/connect-devices-wirelessly/nsd-wifi-direct.html
本階段的第一節(jié)課 Using Network Service Discovery 展示了如何搜索本地網(wǎng)絡(luò)服務(wù)。然而,使用WI-FI P2P搜索服務(wù)可以直接搜索附近的設(shè)備,而不需要專門通過本地網(wǎng)絡(luò)。這項特性使得在沒有本地網(wǎng)絡(luò)或者熱點的情況下還可以在不同的設(shè)備間進行通信。
雖然這里的API與NSD的API的目的很相似,但是實現(xiàn)的過程卻完全不同。這節(jié)課展示了如何通過WI-FI P2P網(wǎng)絡(luò)來搜索附近的可用服務(wù)。這節(jié)課建立在已經(jīng)對Wi-Fi P2P API熟悉的基礎(chǔ)之上。
設(shè)置清單文件
如果要使用WI-FI P2P技術(shù),需要在程序的清單文件中添加CHANGE_WIFI_STATE, ACCESS_WIFI_STATE, INTERNET三項權(quán)限。雖然Wi-Fi P2P并不需要互聯(lián)網(wǎng)連接,但是它需要使用標準的Java Socket通訊技術(shù),所以需要使用INTERNET權(quán)限:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.android.nsdchat"...<uses-permissionandroid:required="true"android:name="android.permission.ACCESS_WIFI_STATE"/><uses-permission android:required="true"android:name="android.permission.CHANGE_WIFI_STATE"/><uses-permission android:required="true"android:name="android.permission.INTERNET"/>...添加本地服務(wù)
如果程序提供了本地服務(wù),還需要將該服務(wù)注冊到搜索服務(wù)中。一旦本地服務(wù)完成注冊,那么框架會自動的響應(yīng)另一端點的搜索服務(wù)請求。
創(chuàng)建本地網(wǎng)絡(luò)有以下過程:
- 1.創(chuàng)建一個WifiP2pServiceInfo對象。
- 2.將服務(wù)的相關(guān)信息填入其中。
- 3.調(diào)用addLocalService()方法完成本地服務(wù)注冊。
搜索附近的服務(wù)
Android會使用回調(diào)方法來通知應(yīng)用程序有可用的服務(wù),所以首先要做的就是設(shè)置該回調(diào)。創(chuàng)建一個WifiP2pManager.DnsSdTxtRecordListener來監(jiān)聽傳入的記錄。這個記錄由其它設(shè)備隨意廣播。當其中一條記錄到達時,會將該設(shè)備的地址及其它相關(guān)的信息拷貝到一個外部的數(shù)據(jù)結(jié)構(gòu)中,這樣的話就可以晚一些訪問。下面的代碼假設(shè)這個記錄包含一條”buddyname”的屬性,用于識別用戶的身份。
final HashMap<String, String> buddies = new HashMap<String, String>(); ... private void discoverService() {DnsSdTxtRecordListener txtListener = new DnsSdTxtRecordListener() {@Override/* Callback includes:* fullDomain: full domain name: e.g "printer._ipp._tcp.local."* record: TXT record dta as a map of key/value pairs.* device: The device running the advertised service.*/public void onDnsSdTxtRecordAvailable(String fullDomain, Map record, WifiP2pDevice device) {Log.d(TAG, "DnsSdTxtRecord available -" + record.toString());buddies.put(device.deviceAddress, record.get("buddyname"));}};... }如要獲取服務(wù)的相關(guān)信息,需要創(chuàng)建一個WifiP2pManager.DnsSdServiceResponseListener接口。 這個接口會接收實際的連接信息。上面代碼段中的Map對象將設(shè)備的地址與”buddy name”組成了鍵值對。服務(wù)響應(yīng)監(jiān)聽器利用這項特性與DNS記錄建立連接。一旦兩個監(jiān)聽器都已經(jīng)實現(xiàn),那么將它們添加到WifiP2pManager的setDnsSdResponseListeners()方法中即可。
private void discoverService() { ...DnsSdServiceResponseListener servListener = new DnsSdServiceResponseListener() {@Overridepublic void onDnsSdServiceAvailable(String instanceName, String registrationType,WifiP2pDevice resourceType) {// Update the device name with the human-friendly version from// the DnsTxtRecord, assuming one arrived.resourceType.deviceName = buddies.containsKey(resourceType.deviceAddress) ? buddies.get(resourceType.deviceAddress) : resourceType.deviceName;// Add to the custom adapter defined specifically for showing// wifi devices.WiFiDirectServicesList fragment = (WiFiDirectServicesList) getFragmentManager().findFragmentById(R.id.frag_peerlist);WiFiDevicesAdapter adapter = ((WiFiDevicesAdapter) fragment.getListAdapter());adapter.add(resourceType);adapter.notifyDataSetChanged();Log.d(TAG, "onBonjourServiceAvailable " + instanceName);}};mManager.setDnsSdResponseListeners(channel, servListener, txtListener);... }接下來需要創(chuàng)建一個新的服務(wù)請求,然后將其作為參數(shù)調(diào)用addServiceRequest()方法,這個方法同樣需要一個監(jiān)聽器來反應(yīng)成功還是失敗。
serviceRequest = WifiP2pDnsSdServiceRequest.newInstance();mManager.addServiceRequest(channel,serviceRequest,new ActionListener() {@Overridepublic void onSuccess() {// Success!}@Overridepublic void onFailure(int code) {// Command failed. Check for P2P_UNSUPPORTED, ERROR, or BUSY}});最后,調(diào)用discoverServices()方法開始搜索服務(wù)。
mManager.discoverServices(channel, new ActionListener() {@Overridepublic void onSuccess() {// Success!}@Overridepublic void onFailure(int code) {// Command failed. Check for P2P_UNSUPPORTED, ERROR, or BUSYif (code == WifiP2pManager.P2P_UNSUPPORTED) {Log.d(TAG, "P2P isn't supported on this device.");else if(...)...}});如果上面的都已經(jīng)完成,那么可以喊一聲哈利路亞了,已經(jīng)完成了所有的步驟。如果遇到了問題,尋找那個將WifiP2pManager.ActionListener作為參數(shù)的方法,這個回調(diào)方法會告知程序是成功還是失敗。如果要解決這個問題,請將調(diào)試代碼放入onFailure()方法中。方法所提供的錯誤代碼會告知問題所在。下面是可能出現(xiàn)的錯誤代碼以及它們的解釋:
P2P_UNSUPPORTED
當前設(shè)備不支持Wi-Fi P2PBUSY
系統(tǒng)處于繁忙處理狀態(tài)ERROR
由于內(nèi)部錯誤造成操作失敗總結(jié)
以上是生活随笔為你收集整理的Android官方开发文档Training系列课程中文版:连接无线设备之通过P2P搜索网络服务的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android官方开发文档Trainin
- 下一篇: android sina oauth2.