1. 程式人生 > >基於Android WiFi直連的P2P聊天程式

基於Android WiFi直連的P2P聊天程式

要實現點對點通訊,過程其實很簡單,首先要建立連線,接著取得對方節點的ip地址,最後通過socket通訊即可實現。
通過Android提供的WiFi直連技術,可獲得同一WiFi下的裝置列表,選擇其中一臺即可實現連線。
首先要在AndroidManifest.xml檔案中新增許可權,如下所示:
 <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"/>
之後在activity中建立相應的廣播接收器和點對點管理器
        private final IntentFilter intentFilter=new IntentFilter();
        WifiP2pManager.Channel mChannel;
        private WifiP2pManager mManager;
        private p2pReceiver receiverP2p;
       .........
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
        intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
        intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
        intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
        mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
        mChannel = mManager.initialize(this, getMainLooper(), null);
}
在onResume中註冊此intentfilter和receiverP2p:
@Override
protected void onResume() {
    super.onResume();
    receiverP2p=new p2pReceiver(mManager,mChannel,SecondActivity.this);
    registerReceiver(receiverP2p,intentFilter);
}
記得在onDestroy中解除廣播:
@Override
protected void onDestroy() {
    super.onDestroy();
    unregisterReceiver(receiverP2p);
}
發現周圍裝置:
mManager.discoverPeers(mChannel,new WifiP2pManager.ActionListener(){
    @Override
    public void onSuccess() {


    }
    @Override
    public void onFailure(int reason) {


    }
});
監聽狀態變化:
@Override
 public void onReceive(final Context context, Intent intent) {
       String action=intent.getAction();
     //P2P功能是否開啟
     if(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)){
        
     }
     //可連線peer改變
     else if(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)){
         if(mManager!=null){
             mManager.requestPeers(mChannel,peerListListener);
         }
     }
     //P2P連線狀態改變
     else if(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)){
        
     }
     裝置設定改變
     }else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
     }
     peerListListener=new WifiP2pManager.PeerListListener() {
         @Override
         public void onPeersAvailable(WifiP2pDeviceList peerlist) {
          //在這裡可選擇裝置進行連線
         }
     };


 }
裝置連線方法如下:
private void connectPeer(WifiP2pDevice device) {
    final WifiP2pConfig config = new WifiP2pConfig();
    config.deviceAddress = device.deviceAddress;
    mManager.connect(mChannel, config, new WifiP2pManager.ActionListener() {
        @Override
        public void onSuccess() {
           //連線成功
        }


        @Override
        public void onFailure(int reason) {
            // 連線失敗
        }
    });
}
通過以上步驟便可在兩臺Android裝置之間建立連線,若要取得GroupOwner地址,在receiverP2p中的onReceive方法中,當intent.getAction()等於WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION時,代表P2P連線狀態發生改變,此時可獲得IP地址,方法如下:
NetworkInfo info=intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
  if(info.isConnected()){
    mManager.requestConnectionInfo(mChannel, new WifiP2pManager.ConnectionInfoListener() {
        @Override
        public void onConnectionInfoAvailable(WifiP2pInfo info) {
            String address=null;
            if(info.groupFormed&&info.isGroupOwner){
                address=info.groupOwnerAddress.getHostAddress().toString();
            }else if(info.groupFormed){
                address=info.groupOwnerAddress.getHostAddress();
            }else {


            }
        }
    });
}else {
    
}
注意:這裡取得的ip地址永遠是192.168.49.1,檢視原始碼後發現這是info.groupOwnerAddress的預設值,但是這並不影響。在初次傳送訊息時,非GroupOwner裝置將自己的實際ip地址及訊息傳送到192.168.49.1,GroupOwner裝置即可獲得另一臺裝置的ip地址,之後再將自己的ip地址傳送給另一臺裝置,兩臺裝置之間即可自由通訊。