Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android API Guides---Wi-Fi Peer-to-Peer

Android API Guides---Wi-Fi Peer-to-Peer

編輯:關於Android編程

Wi-Fi Peer-to-Peer

Wi-Fi對等網絡(P2P),讓Android 4.0(API級別14)或相應的硬件更高版本的設備直接連接到通過Wi-Fi對方沒有中間接入點(Android的無線網絡連接的P2P架構符合在Wi-Fi聯盟的Wi-Fi直?認證計劃)。使用這些API,你可以發現並連接到其他設備時,每個設備支持Wi-Fi P2P,然後在溝通跨越距離迅速連接比藍牙連接更長的時間。這是為使用戶之間共享數據的應用,如一個多人游戲或相片共享應用是有用的。


在Wi-Fi P2P的API包括以下主要部分:


方法,使您可以發現,請求,並連接到同齡人在WifiP2pManager類中定義。
監聽器,讓您得到通知的WifiP2pManager方法調用的成功或失敗。當調用WifiP2pManager方法,每個方法可接收通過作為參數的特定監聽器。
通知您通過了Wi-Fi的P2P架構,檢測的特定事件,如丟棄連接或新發現的同行意圖。
你經常使用這些API的這三個主要組件在一起。例如,你可以提供一個WifiP2pManager.ActionListener來調用discoverPeers(),這樣就可以用ActionListener.onSuccess()和ActionListener.onFailure()方法來通知。如果discoverPeers()方法,發現同行名單已經改變了WIFI_P2P_PEERS_CHANGED_ACTION意圖還播出。


API概述


該WifiP2pManager類提供了一些方法,讓你的Wi-Fi硬件設備上做事情喜歡發現並連接到同齡人交流。以下操作可用:


表1.Wi網絡P2P方法
方法說明
初始化()注冊與Wi-Fi無線架構應用。這必須調用任何其它Wi-Fi點對點方法之前被調用。
連接()啟動與指定配置的設備對等網絡連接。
cancelConnect()取消任何正在進行的對等網絡組協商。
requestConnectInfo()請求的設備的連接信息。
createGroup()創建一個對等網絡組與當前設備為組擁有者。
removeGroup()刪除當前對等網絡組。
requestGroupInfo()請求的對等體組的信息。
discoverPeers()發起對端發現
requestPeers()請求發現同行的當前列表。
WifiP2pManager方法,讓你在聽眾傳遞,從而使無線網絡的P2P架構可以通知您的呼叫狀態的活動。使用該聽眾的可用偵聽器接口和相應的WifiP2pManager方法調用在下表中描述:


表2的Wi-Fi點對點監聽器
監聽器接口相關行動
WifiP2pManager.ActionListener連接(),cancelConnect(),createGroup(),removeGroup(),和discoverPeers()
WifiP2pManager.ChannelListener初始化()
WifiP2pManager.ConnectionInfoListener requestConnectInfo()
WifiP2pManager.GroupInfoListener requestGroupInfo()
WifiP2pManager.PeerListListener requestPeers()
在Wi-Fi點對點API定義的意圖時,某些無線網絡連接P2P的事件發生,廣播,當一個新的對等發現或當設備的Wi-Fi狀態的變化,如。您可以注冊通過創建一個處理這些意圖的廣播接收器來接收應用程序中的這些意圖:


表3.無線網絡連接的P2P意圖
意向描述
WIFI_P2P_CONNECTION_CHANGED_ACTION廣播當設備的Wi-Fi連接的狀態發生改變。
WIFI_P2P_PEERS_CHANGED_ACTION廣播當你調用discoverPeers()。通常你想打電話requestPeers(),如果你處理這個意圖在應用程序中得到同行的更新列表。
WIFI_P2P_STATE_CHANGED_ACTION廣播時的Wi-Fi P2P啟用或設備上禁用。
WIFI_P2P_THIS_DEVICE_CHANGED_ACTION廣播當設備的細節有變化,如設備的名稱。
創建一個廣播接收器Wi-Fi的P2P意圖


廣播接收器,您可以接收由意圖Android系統播放,讓您的應用程序能夠對你有興趣在響應事件是創建一個廣播接收器處理的Wi-Fi點對點意圖的基本步驟如下:


創建一個擴展的BroadcastReceiver類的類。對於類的構造函數,您很可能希望擁有的WifiP2pManager,WifiP2pManager.Channel,而這個廣播接收器將在登記的活動性參數,這使得廣播接收器發送更新到活動以及訪問如果需要的無線網絡連接的硬件和通信信道。
在廣播接收器,檢查你有興趣的onReceive()的意圖。執行取決於所接收到的意圖的任何必要的行動。例如,如果廣播接收器接收到WIFI_P2P_PEERS_CHANGED_ACTION意圖,你可以調用requestPeers()方法來獲得當前發現的對等的名單。
下面的代碼演示如何創建一個典型的廣播接收機。廣播接收機需要一個WifiP2pManager對象作為參數的活動,並使用這兩個類當廣播接收機接收的意圖,適當開展所需采取的行動:

 

/**
* A BroadcastReceiver that notifies of important Wi-Fi p2p events.
*/
public class WiFiDirectBroadcastReceiver extends BroadcastReceiver {

  private WifiP2pManager mManager;
  private Channel mChannel;
  private MyWiFiActivity mActivity;

  public WiFiDirectBroadcastReceiver(WifiP2pManager manager, Channel channel,
      MyWifiActivity activity) {
    super();
    this.mManager = manager;
    this.mChannel = channel;
    this.mActivity = activity;
  }

  @Override
  public void onReceive(Context context, Intent intent) {
    String action = intent.getAction();

    if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
      // Check to see if Wi-Fi is enabled and notify appropriate activity
    } else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
      // Call WifiP2pManager.requestPeers() to get a list of current peers
    } else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
      // Respond to new connection or disconnections
    } else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
      // Respond to this device's wifi state changing
    }
  }
}
創建一個Wi-Fi的P2P應用


創建一個Wi-Fi的P2P應用程序包括創建和注冊的廣播接收器為您的應用程序,發現同行,連接到一個同行,和傳輸數據到對等。下面的章節描述了如何做到這一點。


初始設置


使用的Wi-Fi P2P的API之前,必須確保您的應用程序可以訪問硬件和設備支持的Wi-Fi P2P協議。如果支持的Wi-Fi P2P,您可以獲得WifiP2pManager的一個實例,創建並注冊您的廣播接收器,並開始使用的Wi-Fi P2P的API。


請求許可使用設備上的Wi-Fi硬件,也宣告您的應用程序在Android清單正確的最低SDK版本:

 

 






請檢查是否無線網絡連接P2P是在和支持。一個好地方,檢查這是你的廣播接收器,當它接收到WIFI_STATE_CHANGED_ACTION意圖。通知您的了Wi-Fi的P2P狀態的活動,並作出相應的反應:

 

 

@Override
public void onReceive(Context context, Intent intent) {
  ...
  String action = intent.getAction();
  if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
    int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
    if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
      // Wifi P2P is enabled
    } else {
      // Wi-Fi P2P is not enabled
    }
  }
  ...
}
在活動的onCreate()方法,獲得WifiP2pManager的一個實例,並通過調用初始化寄存器與Wi-Fi無線P2P架構您的應用程序()。該方法返回一個WifiP2pManager.Channel,用於連接您的應用程序在Wi-Fi的P2P架構。您還應該創建一個WifiP2pManager你的廣播接收器的實例,並與WifiP2pManager.Channel你活動的參考對象一起。這使您的廣播接收器來通知你感興趣的事件的活動,並相應更新。它還允許在必要時操縱設備的Wi-Fi狀態:

 

 

WifiP2pManager mManager;
Channel mChannel;
BroadcastReceiver mReceiver;
...
@Override
protected void onCreate(Bundle savedInstanceState){
  ...
  mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
  mChannel = mManager.initialize(this, getMainLooper(), null);
  mReceiver = new WiFiDirectBroadcastReceiver(mManager, mChannel, this);
  ...
}
創建一個意圖過濾器,並添加相同的意圖為您廣播接收機檢查:

 

 

IntentFilter mIntentFilter;
...
@Override
protected void onCreate(Bundle savedInstanceState){
  ...
  mIntentFilter = new IntentFilter();
  mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
  mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
  mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
  mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
  ...
}
注冊廣播接收器在您的活動的onResume()方法,並在活動的onPause()方法取消注冊:

 

 

/* register the broadcast receiver with the intent values to be matched */
@Override
protected void onResume() {
  super.onResume();
  registerReceiver(mReceiver, mIntentFilter);
}
/* unregister the broadcast receiver */
@Override
protected void onPause() {
  super.onPause();
  unregisterReceiver(mReceiver);
}
當你獲得了WifiP2pManager.Channel並成立了廣播接收器,應用程序可以讓無線網絡的P2P方式撥打和接收的Wi-Fi點對點意圖。
現在,您可以實現您的應用程序,並通過調用WifiP2pManager的方法使用的Wi-Fi功能的P2P。接下來的部分描述了怎麼辦共同行動,如發現和連接同行。


發現同行


要發現同行可用來連接,調用discoverPeers()來檢測在范圍內可用的同行。這個函數的調用是異步的,一個成功或失敗傳遞給您的應用程序的onSuccess()和onFailure處(),如果你創建了一個WifiP2pManager.ActionListener。該的onSuccess()方法只通知您發現過程成功,不提供有關實際同齡人的任何信息,它發現,如果有的話:

 

 

mManager.discoverPeers(channel, new WifiP2pManager.ActionListener() {
  @Override
  public void onSuccess() {
    ...
  }

  @Override
  public void onFailure(int reasonCode) {
    ...
  }
});
如果發現過程成功並檢測對等體,則系統廣播WIFI_P2P_PEERS_CHANGED_ACTION意圖,而可以在一個廣播接收機監聽,以獲得對等體的列表。當你的應用程序收到WIFI_P2P_PEERS_CHANGED_ACTION意圖,您可以要求發現的對等與requestPeers列表()。下面的代碼演示了如何設置此:

 

 

PeerListListener myPeerListListener;
...
if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {

  // request available peers from the wifi p2p manager. This is an
  // asynchronous call and the calling activity is notified with a
  // callback on PeerListListener.onPeersAvailable()
  if (mManager != null) {
    mManager.requestPeers(mChannel, myPeerListListener);
  }
}
該requestPeers()方法也是異步的,可以通知你的活動時,同齡人的名單可與現有的對等(),這是在WifiP2pManager.PeerListListener接口中定義。該onPeersAvailable()方法提供了一個WifiP2pDeviceList,您可以遍歷找到您想要連接到同級。
連接到同行
當你想通了,你想獲得可能的同齡人名單後,連接到設備,調用connect()方法連接到該設備。此方法調用需要包含該裝置的信息來連接到一個WifiP2pConfig對象。你可以通知通過WifiP2pManager.ActionListener連接成功或失敗。下面的代碼演示如何創建到所需設備的連接:

 

 

//obtain a peer from the WifiP2pDeviceList
WifiP2pDevice device;
WifiP2pConfig config = new WifiP2pConfig();
config.deviceAddress = device.deviceAddress;
mManager.connect(mChannel, config, new ActionListener() {

  @Override
  public void onSuccess() {
    //success logic
  }

  @Override
  public void onFailure(int reason) {
    //failure logic
  }
});
傳輸數據


一旦建立了連接,你可以用插座的設備之間傳輸數據。是傳送數據的基本步驟如下:


創建一個ServerSocket。此插座等待來自客戶端的指定端口和塊上的連接,直到它發生,所以在後台線程做到這一點。
創建一個客戶端的Socket。客戶端使用服務器套接字的IP地址和端口,以連接到服務器設備。
從客戶機向服務器發送數據。當客戶端套接字成功地連接到服務器插口,可以從客戶端發送的數據與字節流服務器。
服務器套接字等待客戶端連接(使用accept()方法)。這個調用塊,直到客戶端連接,所以稱這是另一個線程。當連接發生時,服務器設備可以從客戶端接收數據。執行與該數據的任何動作,如將其保存到文件或它呈現給用戶。
下面的例子,從Wi-Fi無線P2P演示樣品修改,向您展示如何創建這個客戶端 - 服務器socket通訊和從客戶端與服務傳送JPEG圖像傳輸到服務器。對於一個完整的工作示例,編譯和運行的Wi-Fi點對點演示樣本。

 

 

public static class FileServerAsyncTask extends AsyncTask {

  private Context context;
  private TextView statusText;

  public FileServerAsyncTask(Context context, View statusText) {
    this.context = context;
    this.statusText = (TextView) statusText;
  }

  @Override
  protected String doInBackground(Void... params) {
    try {

      /**
      * Create a server socket and wait for client connections. This
      * call blocks until a connection is accepted from a client
      */
      ServerSocket serverSocket = new ServerSocket(8888);
      Socket client = serverSocket.accept();

      /**
      * If this code is reached, a client has connected and transferred data
      * Save the input stream from the client as a JPEG file
      */
      final File f = new File(Environment.getExternalStorageDirectory() + "/"
          + context.getPackageName() + "/wifip2pshared-" + System.currentTimeMillis()
          + ".jpg");

      File dirs = new File(f.getParent());
      if (!dirs.exists())
        dirs.mkdirs();
      f.createNewFile();
      InputStream inputstream = client.getInputStream();
      copyFile(inputstream, new FileOutputStream(f));
      serverSocket.close();
      return f.getAbsolutePath();
    } catch (IOException e) {
      Log.e(WiFiDirectActivity.TAG, e.getMessage());
      return null;
    }
  }

  /**
  * Start activity that can handle the JPEG image
  */
  @Override
  protected void onPostExecute(String result) {
    if (result != null) {
      statusText.setText("File copied - " + result);
      Intent intent = new Intent();
      intent.setAction(android.content.Intent.ACTION_VIEW);
      intent.setDataAndType(Uri.parse("file://" + result), "image/*");
      context.startActivity(intent);
    }
  }
}
在客戶端,連接到與客戶端套接字和傳輸數據的服務器套接字。這個例子傳輸客戶端設備的文件系統上的JPEG文件。

 

 

Context context = this.getApplicationContext();
String host;
int port;
int len;
Socket socket = new Socket();
byte buf[] = new byte[1024];
...
try {
  /**
  * Create a client socket with the host,
  * port, and timeout information.
  */
  socket.bind(null);
  socket.connect((new InetSocketAddress(host, port)), 500);

  /**
  * Create a byte stream from a JPEG file and pipe it to the output stream
  * of the socket. This data will be retrieved by the server device.
  */
  OutputStream outputStream = socket.getOutputStream();
  ContentResolver cr = context.getContentResolver();
  InputStream inputStream = null;
  inputStream = cr.openInputStream(Uri.parse("path/to/picture.jpg"));
  while ((len = inputStream.read(buf)) != -1) {
    outputStream.write(buf, 0, len);
  }
  outputStream.close();
  inputStream.close();
} catch (FileNotFoundException e) {
  //catch logic
} catch (IOException e) {
  //catch logic
}

/**
* Clean up any open sockets when done
* transferring or if an exception occurred.
*/
finally {
  if (socket != null) {
    if (socket.isConnected()) {
      try {
        socket.close();
      } catch (IOException e) {
        //catch logic
      }
    }
  }
}
 
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved