android 点对点 通信,将 WLAN 直连(点对点)用于服务发现
本課程的第一課“使用網絡服務發現”向您介紹了如何發現連接到本地網絡的服務。然而,使用 WLAN 點對點 (P2P) 服務發現可讓您在未連接到網絡的情況下直接發現附近設備的服務。您還可以廣播您的設備上運行的服務。使用這些功能,即使沒有可用的本地網絡或熱點,也可以在應用之間進行通信。
雖然這組 API 在用途方面與上一課程中介紹的網絡服務發現 API 相似,但在代碼中實現它們的方式卻截然不同。本課程向您介紹了如何使用 WLAN 點對點發現其他設備提供的服務,并假定您已熟悉 WLAN 點對點 API。
設置清單
如需使用 WLAN 點對點,請在清單中添加
package="com.example.android.nsdchat"
...
android:required="true"
android:name="android.permission.ACCESS_WIFI_STATE"/>
android:required="true"
android:name="android.permission.CHANGE_WIFI_STATE"/>
android:required="true"
android:name="android.permission.ACCESS_FINE_LOCATION"/>
android:required="true"
android:name="android.permission.INTERNET"/>
...
除了上面的權限外,以下 API 還需要啟用位置信息模式:
添加本地服務
如果您要提供本地服務,則需要注冊它以支持服務發現。注冊本地服務后,框架會自動響應來自對等設備的服務發現請求。
如需創建本地服務,請執行以下步驟:
用您的服務相關信息填充該對象。
調用
Kotlin
private fun startRegistration() {
// Create a string map containing information about your service.
val record: Map = mapOf(
"listenport" to SERVER_PORT.toString(),
"buddyname" to "John Doe${(Math.random() * 1000).toInt()}",
"available" to "visible"
)
// Service information. Pass it an instance name, service type
// _protocol._transportlayer , and the map containing
// information other devices will want once they connect to this one.
val serviceInfo =
WifiP2pDnsSdServiceInfo.newInstance("_test", "_presence._tcp", record)
// Add the local service, sending the service info, network channel,
// and listener that will be used to indicate success or failure of
// the request.
manager.addLocalService(channel, serviceInfo, object : WifiP2pManager.ActionListener {
override fun onSuccess() {
// Command successful! Code isn't necessarily needed here,
// Unless you want to update the UI or add logging statements.
}
override fun onFailure(arg0: Int) {
// Command failed. Check for P2P_UNSUPPORTED, ERROR, or BUSY
}
})
}Java
private void startRegistration() {
// Create a string map containing information about your service.
Map record = new HashMap();
record.put("listenport", String.valueOf(SERVER_PORT));
record.put("buddyname", "John Doe" + (int) (Math.random() * 1000));
record.put("available", "visible");
// Service information. Pass it an instance name, service type
// _protocol._transportlayer , and the map containing
// information other devices will want once they connect to this one.
WifiP2pDnsSdServiceInfo serviceInfo =
WifiP2pDnsSdServiceInfo.newInstance("_test", "_presence._tcp", record);
// Add the local service, sending the service info, network channel,
// and listener that will be used to indicate success or failure of
// the request.
manager.addLocalService(channel, serviceInfo, new ActionListener() {
@Override
public void onSuccess() {
// Command successful! Code isn't necessarily needed here,
// Unless you want to update the UI or add logging statements.
}
@Override
public void onFailure(int arg0) {
// Command failed. Check for P2P_UNSUPPORTED, ERROR, or BUSY
}
});
}
發現附近的服務
Android 使用回調方法向應用通知可用服務,因此首先要設置這些方法。創建
Kotlin
private val buddies = mutableMapOf()
...
private fun discoverService() {
/* 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.
*/
val txtListener = DnsSdTxtRecordListener { fullDomain, record, device ->
Log.d(TAG, "DnsSdTxtRecord available -$record")
record["buddyname"]?.also {
buddies[device.deviceAddress] = it
}
}
}Java
final HashMap buddies = new HashMap();
...
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"));
}
};
}
如需獲取服務信息,請創建一個
Kotlin
private fun discoverService() {
...
val servListener = DnsSdServiceResponseListener { instanceName, registrationType, resourceType ->
// Update the device name with the human-friendly version from
// the DnsTxtRecord, assuming one arrived.
resourceType.deviceName = buddies[resourceType.deviceAddress] ?: resourceType.deviceName
// Add to the custom adapter defined specifically for showing
// wifi devices.
val fragment = fragmentManager
.findFragmentById(R.id.frag_peerlist) as WiFiDirectServicesList
(fragment.listAdapter as WiFiDevicesAdapter).apply {
add(resourceType)
notifyDataSetChanged()
}
Log.d(TAG, "onBonjourServiceAvailable $instanceName")
}
manager.setDnsSdResponseListeners(channel, servListener, txtListener)
...
}Java
private void discoverService() {
...
DnsSdServiceResponseListener servListener = new DnsSdServiceResponseListener() {
@Override
public 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);
}
};
manager.setDnsSdResponseListeners(channel, servListener, txtListener);
...
}
現在,創建一個服務請求并調用
Kotlin
serviceRequest = WifiP2pDnsSdServiceRequest.newInstance()
manager.addServiceRequest(
channel,
serviceRequest,
object : WifiP2pManager.ActionListener {
override fun onSuccess() {
// Success!
}
override fun onFailure(code: Int) {
// Command failed. Check for P2P_UNSUPPORTED, ERROR, or BUSY
}
}
)Java
serviceRequest = WifiP2pDnsSdServiceRequest.newInstance();
manager.addServiceRequest(channel,
serviceRequest,
new ActionListener() {
@Override
public void onSuccess() {
// Success!
}
@Override
public void onFailure(int code) {
// Command failed. Check for P2P_UNSUPPORTED, ERROR, or BUSY
}
});
Kotlin
manager.discoverServices(
channel,
object : WifiP2pManager.ActionListener {
override fun onSuccess() {
// Success!
}
override fun onFailure(code: Int) {
// Command failed. Check for P2P_UNSUPPORTED, ERROR, or BUSY
when (code) {
WifiP2pManager.P2P_UNSUPPORTED -> {
Log.d(TAG, "P2P isn't supported on this device.")
}
}
}
}
)Java
manager.discoverServices(channel, new ActionListener() {
@Override
public void onSuccess() {
// Success!
}
@Override
public void onFailure(int code) {
// Command failed. Check for P2P_UNSUPPORTED, ERROR, or BUSY
if (code == WifiP2pManager.P2P_UNSUPPORTED) {
Log.d(TAG, "P2P isn't supported on this device.");
else if(...)
...
}
});
如果一切進展順利,您就大功告成了!如果遇到問題,請記住,您所進行的異步調用采用
運行該應用的設備不支持 WLAN 點對點。
系統太忙,無法處理請求。
由于出現內部錯誤,操作失敗。
總結
以上是生活随笔為你收集整理的android 点对点 通信,将 WLAN 直连(点对点)用于服务发现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux下的I2c 和展锐8310下的
- 下一篇: win7原版镜像_淘汰固态变U盘,不用工