基於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地址傳送給另一臺裝置,兩臺裝置之間即可自由通訊。