android wifip2p怎么用

2025年02月23日 13:34
有1个网友回答
网友(1):

  为了使用Wi-Fi P2P,要在你的清单文件中添加 CHANGE_WIFI_STATE 、 ACCESS_WIFI_STATE 、和 INTERNET 权限。即使Wi-FiP2P不要求互联网连接,但它要使用标准的Java套接字,并且Android在使用这些套接字时要求申请这些权限,因此要在清单中申请INTERNET权限。

    ...

    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.INTERNET"/>
  ...

  添加本地服务

  如果你要提供一个本地服务,那么就需要把这个服务注册为可发现的。本地服务被注册后,框架就会自动的响应来自对等点的服务发现请求。

  以下是创建本地服务的步骤:

  1. 创建一个 WifiP2pServiceInfo 对象;

  2. 填入你的服务相关的信息;

  3. 调用addLocalService()方法来注册本地服务,让其可发现。

  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");

  // Serviceinformation. 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 thelocal service, sending the service info, network channel,
  // andlistener that will be used to indicate success or failure of
  // therequest.
  mManager.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使用回调方法来通知你的应用程序可用的服务,因此首先要做的就是要建立回调方法。创建一个 WifiP2pManager.DnsSdTxtRecordListener 对象来监听传入的记录。这个记录可以是其他设备的任意广播。当一个记录进入时,你可以把设备地址和其他你想要的其他相关信息复制到当前方法外部的数据结构中,以便后续可以访问它。下面的例子假设记录中包含一个“buddyname”字段,它带有用户的标识。

  final HashMap < String , String > buddies = new HashMap < String , String >(); ...
  private void discoverService() {
  DnsSdTxtRecordListener txtListener = new DnsSdTxtRecordListener() {
  @Override
  /* Callbackincludes:
  * fullDomain: full domainname: e.g "printer._ipp._tcp.local."
  * record: TXT record dta as amap of key/value pairs.
  * device: The device runningthe advertised service.
  */

  public voidonDnsSdTxtRecordAvailable(
  String fullDomain, Map record, WifiP2pDevice device) {
  Log.d(TAG, "DnsSdTxtRecord available -" + record.toString());
  buddies.put(device.deviceAddress, record.get("buddyname"));
  }
  };
  ...
  }
  实现一个 WifiP2pManager.DnsSdServiceResponseListener 接口,来获取服务信息。这个接口会接收实际的描述和连接信息。上面的代码中使用了 Map 对象把设备地址和用户标识组成一对。服务响应监听器使用这个接口把DNS记录和对应的服务信息连接到一起。实现上述两个监听器后,使用 setDnsSdResponseListener() 方法把它们添加给 WifiP2pManager 对象。

  private void discoverService () { ...
  DnsSdServiceResponseListener servListener = new DnsSdServiceResponseListener() {
  @Override
  public voidonDnsSdServiceAvailable(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);
  ...
  }

  现在创建一个服务请求并调用 addServiceRequest() 方法,这个方法也需要一个监听器来包括成功或失败。

  serviceRequest = WifiP2pDnsSdServiceRequest . newInstance (); mManager .addServiceRequest(channel,
  serviceRequest,
  new ActionListener() {
  @Override
  public void onSuccess() {
  // Success!
  }

  @Override
  public void onFailure(int code) {
  // Command failed. Check forP2P_UNSUPPORTED, ERROR, or BUSY
  }
  });

  最后,调用的 discoverServices() 方法。

  mManager . 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'tsupported on this device.");
  else if(...)
  ...
  }
  });

  如果一切顺利,恭喜你大功告成。如果遇到问题,记住前面异步调用的参数 WifiP2pManager.ActionListener 参数,它提供了指示成功或失败的回调方法。把调试断点设置在 onFailure() 方法中来诊断问题。这个方法提供了错误代码,以下是可能发生的错误:

  P2P_UNSUPPORTED

  运行 app 的设备上不支持 Wi-Fi P2P

  BUSY

  系统忙于处理请求

  ERROR

  由于内部错误导致操作失败