Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android---用Wi-Fi來建立對等連接

Android---用Wi-Fi來建立對等連接

編輯:關於Android編程

WiFi對等API(P2P)不需要連接到網絡或熱點(Android的WiFi P2P框架符合WiFi編程指導規范),就允許應用程序連接到附近的設備。WiFiP2P允許應用程序快速的查找附近的設備,並與其交互。在連接范圍上超過了藍牙的能力。 本文介紹如何使用WiFi P2P來查找和連接附近的設備。 建立應用程序權限 為了使用WiFi P2P,要在應用程序的清單文件中添加CHANGE_WIFI_STATE、ACCESS_WIFI_STATE和INTERNET權限。WiFi P2P不要求互聯網連接,但是它使用標准的Java套接字,它要求INTERNET權限。因此使用WiFi P2P需要下例權限。 <manifestxmlns:android="http://schemas.android.com/apk/res/android"     package="com.example.android.nsdchat"     ...       <uses-permission         android: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"/>     ... 建立廣播接收器和對等管理器 要使用WiFi P2P,就要監聽廣播意圖,在確定事件發生時,告訴你的應用程序。在你的應用程序中,要實例化一個IntentFilter對象,並設置它來監聽以下動作: WIFI_P2P_STATE_CHANGED_ACTION 指示是否啟用WiFi P2P。 WIFI_P2P_PEERS_CHANGED_ACTION 指示可用的對等列表已經發生了改變。 WIFI_P2P_CONNECTION_CHANGED_ACTION 指示WiFi P2P連接的狀態已經發生改變。 WIFI_P2P_THIS_DEVICE_CHANGED_ACTION 指示設備的配置明細已經發生改變。 privatefinalIntentFilterintentFilter =newIntentFilter(); ... @Override public void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     setContentView(R.layout.main);       //  Indicates achange in the Wi-Fi P2P status.     intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);       // Indicates a change inthe list of available peers.     intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);       // Indicates the state ofWi-Fi P2P connectivity has changed.     intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);       // Indicates this device'sdetails have changed.     intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);       ... } 在onCreate()方法中,獲取一個WifiP2pManager對象的實例,並調用它的initialize()方法。這個方法會返回一個WifiP2pManager.Channel對象,它會用於後續對WiFi P2P框架的連接。 @Override   Channel mChannel;   public void onCreate(Bundle savedInstanceState) {     ....     mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);     mChannel = mManager.initialize(this, getMainLooper(), null); }   現在創建一個新的BroadcastReceiver類,用於監聽系統的WiFi P2P狀態的改變。在onReceive()方法中,添加處理上述每個P2P狀態改變的條件。 @Override     public void onReceive(Context context, Intent intent) {         String action = intent.getAction();         if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {             // Determine if Wifi P2P mode is enabled or not, alert             // the Activity.             int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);             if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {                activity.setIsWifiP2pEnabled(true);             } else {                activity.setIsWifiP2pEnabled(false);             }         } else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {               // The peer list has changed!  We should probably do somethingabout             // that.           } else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {               // Connection state changed!  We should probably do somethingabout             // that.           } else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {             DeviceListFragment fragment = (DeviceListFragment)activity.getFragmentManager()                    .findFragmentById(R.id.frag_list);             fragment.updateThisDevice((WifiP2pDevice) intent.getParcelableExtra(                    WifiP2pManager.EXTRA_WIFI_P2P_DEVICE));           }     } 最後,在你的主Activity激活時,添加注冊Intent過濾器和廣播接收器的代碼,並在Activity被掛起時,解除注冊。做這件事的最好的地方是onResume()和onPause()方法 /** register the BroadcastReceiverwith the intent values to be matched */     @Override     public void onResume() {         super.onResume();         receiver = new WiFiDirectBroadcastReceiver(mManager, mChannel, this);         registerReceiver(receiver, intentFilter);     }       @Override     public void onPause() {         super.onPause();         unregisterReceiver(receiver);     } 啟動對等點發現功能 要使用Wi-Fi P2P來搜索附近的設備,就要調用discoverPeers()方法,這個方法需要以下參數: WifiP2pManager.Channel:這個參數是在初始化對等管理器時獲取,用於把應用程序連接到Wi-Fi的P2P框架中; WifiP2pManager.ActionListener接口實現:系統會在處理成功或失敗時調用該接口中對應的方法。 mManager.discoverPeers(mChannel,newWifiP2pManager.ActionListener(){           @Override         public void onSuccess() {             // Code for when the discovery initiation is successful goes here.             // No services have actually been discovered yet, so this method             // can often be left blank.  Code for peer discovery goes in the             // onReceive method, detailed below.         }           @Override         public void onFailure(int reasonCode) {             // Code for when the discovery initiation fails goes here.             // Alert the user that something went wrong.         } }); 記住,這只是啟動對等點發現功能。DiscoverPeers()方法啟動發現處理,然後立即返回。系統會通過調用你傳入的第二參數中的對應的接口方法,通知你對等點發現處理是否啟動成功。此外,發現處理會一直保持到連接被啟動或P2P組被組建。 獲取對等點的列表 現在要編寫獲取和處理對等點列表的代碼。首先實現WifiP2pManager.PeerListener接口,這個接口會提供有關已經發現的Wi-Fi的P2P對等點的信息。下列代碼演示這個處理: privateList peers =newArrayList();     ...       private PeerListListenerpeerListListener = new PeerListListener() {         @Override         public void onPeersAvailable(WifiP2pDeviceListpeerList) {               // Out with the old, in with the new.             peers.clear();             peers.addAll(peerList.getDeviceList());               // If an AdapterView is backed by this data, notify it             // of the change.  For instance, if you have a ListView ofavailable             // peers, trigger an update.             ((WiFiPeerListAdapter) getListAdapter()).notifyDataSetChanged();             if (peers.size() == 0) {                 Log.d(WiFiDirectActivity.TAG, "No devices found");                 return;             }         }     } 現在,修改你的廣播接收器的onReceive()方法,當接收到帶有WIFI_P2P_PEERS_CHANGED_ACTION操作的Intent時,調用requestPeers()方法,並把上面實現的監聽器傳遞給requestPeers()方法。你可以把這個監聽器作為廣播接收器的構造器的參數來傳遞。 publicvoid onReceive(Context context,Intent intent){     ...     else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {           // Requestavailable peers from the wifi p2p manager. This is an         //asynchronous call and the calling activity is notified with a         // callbackon PeerListListener.onPeersAvailable()         if (mManager != null) {             mManager.requestPeers(mChannel,peerListListener);         }         Log.d(WiFiDirectActivity.TAG, "P2P peerschanged");     }... } 這樣,帶有WIFI-P2P_PEERS_CHANGED_ACTION的Intent操作就會觸發更新對等點列表的請求。 連接到對等點 為了連接到對等點,要創建一個新的WifiP2pConfig對象,並從代表你要連接的設備的WifiP2pDevice對象中復制數據到這個WifiP2pConfig對象中。然後調用connect()方法。 @Override     public void connect() {         // Pickingthe first device found on the network.         WifiP2pDevice device = peers.get(0);           WifiP2pConfig config = new WifiP2pConfig();         config.deviceAddress = device.deviceAddress;         config.wps.setup = WpsInfo.PBC;           mManager.connect(mChannel, config, new ActionListener() {               @Override             public void onSuccess() {                 // WiFiDirectBroadcastReceiver will notify us. Ignore for now.             }               @Override             public void onFailure(int reason) {                 Toast.makeText(WiFiDirectActivity.this, "Connect failed. Retry.",                        Toast.LENGTH_SHORT).show();             }         });     } 上述實現的WifiP2pManager.ActionListener接口只會通知你連接成功還是失敗。要監聽連接狀態的變化,就好實現WifiP2pManager.ConnectionInfoListener()接口,這個接口中的onConnectionInfoAvailable()回調方法在連接狀態變化時通知你。當有多個設備連接一個設備時,其中一個設備將會被指定為“組管理者”。 @Override     public voidonConnectionInfoAvailable(final WifiP2pInfo info) {           //InetAddress from WifiP2pInfo struct.         InetAddress groupOwnerAddress =info.groupOwnerAddress.getHostAddress());           // After thegroup negotiation, we can determine the group owner.         if (info.groupFormed && info.isGroupOwner) {             // Do whatever tasks are specific to the group owner.             // One common case is creating a server thread and accepting             // incoming connections.         } else if (info.groupFormed) {             // The other device acts as the client. In this case,             // you'll want to create a client thread that connects to the group             // owner.         }     } 現在,返回到廣播接收器的onReceive()方法,修改對WIFI_P2P_CONNECTION_CHANGED_ACTION的Intent操作的監聽。當收到這個Intent時,調用requestConnectionInfo()方法。這是一個異步調用,因此,結果會被你提供的連接信息監聽器接收到。 ...         } else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {               if (mManager == null) {                 return;             }               NetworkInfo networkInfo = (NetworkInfo) intent                    .getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);               if (networkInfo.isConnected()) {                   // We are connected with the other device, request connection                 // info to find group owner IP                  mManager.requestConnectionInfo(mChannel, connectionListener);             }             ...
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved