Android中的WiFi P2P(二)
Android中的WiFi P2P能夠允許一定範圍內的裝置通過Wifi直接互連而不必通過熱點或網際網路。
使用WiFi P2P需要Android API Level >= 14才可以,而且不要忘記在Manifest檔案中加入下面5個許可權:
● android.permission.ACCESS_WIFI_STATE
● android.permission.CHANGE_WIFI_STATE
● android.permission.ACCESS_NETWORK_STATE
● android.permission.CHANGE_NETWORK_STATE
● android.permission.INTERNET (WiFi P2P並不需要連線網際網路,但是因為要用到
關於WiFi P2P的操作幾乎都靠WifiP2pManager來進行,所以如果你的程式要用到WiFi P2P功能,可以設定一個全域性變數wifiP2pManager,然後在onCreate()生命函式中獲取系統WifiP2pManager物件:
?1 |
<span style= "font-family:Microsoft YaHei;" >wifiP2pManager = (WifiP2pManager) getApplicationContext().getSystemService(Context.WIFI_P2P_SERVICE);</span> |
WifiP2pManager有如下方法可以很方便的進行P2P操作:
方法 | 功能 |
---|---|
initialize() |
在使用WiFi P2P功能時必須先呼叫這個方法,用來通過WiFi P2P框架註冊我們的應用 |
connect() |
根據配置(WifiP2pConfig物件)與指定裝置(WifiP2pDevice物件)進行P2P連線 |
cancelConnect() |
關閉某個P2P連線 |
requestConnectInfo() |
獲取裝置的連線資訊 |
createGroup() |
以當前的裝置為組長建立P2P小組 |
removeGroup() |
移除當前的P2P小組 |
requestGroupInfo() |
獲取P2P小組的資訊 |
discoverPeers() |
初始化peers發現操作 |
requestPeers() |
獲取當前的peers列表(通過discoverPeers發現來的) |
監聽器 | 關聯的行為 |
---|---|
WifiP2pManager.ActionListener |
connect() , cancelConnect() ,
createGroup() , removeGroup() 和discoverPeers() |
WifiP2pManager.ChannelListener |
initialize() |
WifiP2pManager.ConnectionInfoListener |
requestConnectInfo() |
WifiP2pManager.GroupInfoListener |
requestGroupInfo() |
WifiP2pManager.PeerListListener |
requestPeers() |
那麼接下來就可以講解如何使用WiFi P2P了。
一. 準備工作
準備階段需要讓我們的應用可以接受P2P訊號,這就需要一個意圖廣播接收器,要建立一個符合我們要求的廣播接收器需要準備下面3個要素:
(1) 一個意圖廣播接收器,用來接受意圖廣播。
(2) 通過WifiP2pManager的initialize()初始化操作來獲取一個Channel物件,用於以後和WiFi P2P框架保持通訊。
(3) 自己包裝BroadcastReceiver類,實現一個接收器。
意圖過濾器使用如下方法建立:
?1 2 3 4 5 6 |
// 設定intent過濾器
intentFilter =
new IntentFilter();
//一個全域性的intentFilter物件
intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
// WiFi P2P是否可用
intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
// peers列表發生變化
intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
// WiFi P2P連線發生變化
intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
// WiFi P2P裝置資訊發生變化(比如更改了裝置名)
|
Channel的獲取方法: ?
1 |
channel = wifiP2pManager.initialize(getApplicationContext(), getMainLooper(),
null ); // channel是一個全域性的Channel物件
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
class
MyBroadcastReceiver extends
BroadcastReceiver {
// 使用WiFi P2P時,自己定義的BroadcastReceiver的建構函式一定要包含下面這三個要素
private
WifiP2pManager wifiP2pManager;
private
Channel channel;
private
Activity activity;
public
MyBroadcastReceiver(WifiP2pManager wifiP2pManager, Channel channel, Activity activity) {
this .wifiP2pManager = wifiP2pManager;
this .channel = channel;
this .activity = activity;
}
// onReceiver對相應的intent進行處理
@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 可以使用
}
else {
// WiFi P2P 不可以使用
}
}
else if
(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
}
else if
(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
}
else if
(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
}
}
}
|
定義完了之後就可以再需要的地方例項化一個意圖廣播接收器物件了:
?1 |
broadcastReceiver =
new MyBroadcastReceiver(wifiP2pManager, channel,
this );
|
1 |
registerReceiver(broadcastReceiver, intentFilter);
|
二. 啟動peers發現
?1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
public
void discoverPeers(View view) {
peerListListener =
new WifiP2pManager.PeerListListener() {
@Override
public
void onPeersAvailable(WifiP2pDeviceList peerList) {
peers.clear();
// peers是一個全域性ArrayList物件,用於儲存發現的peers的資訊
peers.addAll(peerList.getDeviceList());
// 如果你有一個控制元件用來顯示這些peers的資訊,就可以再這裡更新了
}
};
wifiP2pManager.discoverPeers(channel,
new WifiP2pManager.ActionListener() {
@Override
public
void onSuccess() {
Toast.makeText(getApplicationContext(),
"discover peers!" , Toast.LENGTH_SHORT);
}
@Override
public
void onFailure( int
arg0) {
}
});
// discoverPeers是非同步執行的,呼叫了之後會立刻返回,但是發現的過程一直在進行,
// 直到發現了某個裝置時就會通知你
}
|
1 2 3 4 5 |
else
if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
if
(wifiP2pManager != null ) {
wifiP2pManager.requestPeers(channel, peerListListener);
}
}
|
三. 與peers建立連線
?1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public
void connect() {
final
WifiP2pDevice device = (WifiP2pDevice) peers.get( 0 );
//從peers列表中獲取發現來的第一個裝置
WifiP2pConfig config =
new WifiP2pConfig();
config.deviceAddress = device.deviceAddress;
config.wps.setup = WpsInfo.PBC;
wifiP2pManager.connect(channel, config,
new WifiP2pManager.ActionListener() {
@Override
public
void onSuccess() {
// 連線成功
Toast.makeText(getApplicationContext(),
"與裝置" + device.deviceName +
"連線成功" , Toast.LENGTH_LONG).show();
}
@Override
public
void onFailure( int
arg0) {
// 連線失敗
Toast.makeText(getApplicationContext(),
"與裝置" + device.deviceName +
"連線失敗" , Toast.LENGTH_LONG).show();
}
});
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
else
if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
if
(wifiP2pManager == null )
return ;
NetworkInfo networkInfo = (NetworkInfo) intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
<span style= "white-space:pre" > </span> if
(networkInfo.isConnected()) {
// We are connected with the other device, request
// connection
// info to find group owner IP
wifiP2pManager.requestConnectionInfo(channel,
new WifiP2pManager.ConnectionInfoListener() {
@Override
public
void onConnectionInfoAvailable(WifiP2pInfo info) {
// 這裡可以檢視變化後的網路資訊
// 通過傳遞進來的WifiP2pInfo引數獲取變化後的地址資訊
InetAddress groupOwnerAddress = info.groupOwnerAddress;
// 通過協商,決定一個小組的組長
if
(info.groupFormed && info.isGroupOwner) {
// 這裡執行P2P小組組長的任務。
// 通常是建立一個服務執行緒來監聽客戶端的請求
}
else if
(info.groupFormed) {
// 這裡執行普通組員的任務
// 通常是建立一個客戶端向組長的伺服器傳送請求
}
}
});
}
}
|