由于是Android TV,界面经过修改,不是手机原生态。
构造函数:
public WifiP2pSettings(NetworkSettingsActivity activity) {
super(activity);
//初始化一些空间和成员变量
this.mActivity = activity;
mWifiP2pSettingsHolder = new WifiP2pSettingsHolder(activity);
mCheckBox = mWifiP2pSettingsHolder.getWifiP2pCheckBox();
mDeviceListView = mWifiP2pSettingsHolder.getWifiP2pDeviceListView();
mIsDirectEnable = false;
// 初始化WifiP2pManager 的对象mWifiP2pManager,和WiFiP2pService进行交互。
mWifiP2pManager = (WifiP2pManager) activity.getSystemService(Context.WIFI_P2P_SERVICE);
if (mWifiP2pManager != null) {
// A channel that connects the application to the Wifi p2p framework.
// Most p2p operations require a Channel as an argument
mChannel = mWifiP2pManager.initialize(activity, activity.getMainLooper(), null);
if (mChannel == null) {
mCheckBox.setEnabled(false);
}
}
// 注册广播接收器
registerReceiver();
// 设置空间的监听
setListeners();
}
注册广播:
private void registerReceiver() {
// add action
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);
mActivity.registerReceiver(mReceiver, mIntentFilter);
// wifi hw changed
IntentFilter wifiFilter = new IntentFilter();
wifiFilter.addAction(MWifiManager.WIFI_DEVICE_ADDED_ACTION);
wifiFilter.addAction(MWifiManager.WIFI_DEVICE_REMOVED_ACTION);
mActivity.registerReceiver(mWifiHWReceiver, wifiFilter);
}
其中:
WIFI_P2P_STATE_CHANGED_ACTION:P2P的启动情况,是enable还是disable
WIFI_P2P_PEERS_CHANGED_ACTION:系统内部保存搜索到的P2P设备,如果这些信息有变化,则系统发送该广播。
WIFI_P2P_CONNECTION_CHANGED_ACTION:通知P2P连接情况。可以携带WifiP2pInfo和NetworkInfo两个对象。
WIFI_P2P_THIS_DEVICE_CHANGED_ACTION:本机P2P设备信息发生变化。
广播接收器:
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
//从WIFI_P2P_STATE_CHANGED_ACTION广播中获取相关状态信息,判断是否能够打开WiFi Direct
handleP2pStateChanged(intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE,
WifiP2pManager.WIFI_P2P_STATE_DISABLED));
} else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
if (mWifiP2pManager != null) {
//获取P2P Device信息列表。
mWifiP2pManager.requestPeers(mChannel, WifiP2pSettings.this);
}
} else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
} else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
//更新本设备的信息
mThisDevice = (WifiP2pDevice) intent
.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE);
mWifiP2pSettingsHolder.refreshDeviceInfo(mThisDevice);
}
}
};
private BroadcastReceiver mWifiHWReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (MWifiManager.WIFI_DEVICE_REMOVED_ACTION.equals(action)) {
//WiFi被移除
onWifiHWChanged(false);
} else if (MWifiManager.WIFI_DEVICE_ADDED_ACTION.equals(action)) {
//有WiFi
onWifiHWChanged(true);
}
}
};
其中:
private void handleP2pStateChanged(int state) {
mCheckBox.setEnabled(true);
switch (state) {
case WifiP2pManager.WIFI_P2P_STATE_ENABLED:
mIsDirectEnable = true;
break;
case WifiP2pManager.WIFI_P2P_STATE_DISABLED:
mWifiP2pSettingsHolder.refreshNotice("");
mIsDirectEnable = false;
mThisDevice = null;
break;
default:
mIsDirectEnable = true;
break;
}
}
mWifiP2pManager.requestPeers(mChannel, WifiP2pSettings.this);
是获取P2P Device的信息列表。用WifiP2pDeviceList数据类型来存储。第二个参数类型是PeerListener,是一个接口,WifiP2pSettings实现了这个接口。
WifiP2pDeviceList信息是通过这个接口类的onPeersAvailable函数返回给requestPeers的调用者。
@Override
public void onPeersAvailable(WifiP2pDeviceList peers) {
mPeers = peers;
mDeviceAdater = new WifiP2pListAdapter(mActivity, mPeers.getDeviceList());
mDeviceListView.setAdapter(mDeviceAdater);
}
后面的WifiHWChanged主要是用来设置CheckBox以及更新信息
public void onWifiHWChanged(boolean isOn) {
Log.d(TAG, "isOn, " + isOn);
if (!isOn) {
mCheckBox.setChecked(false);
// refresh device info
mWifiP2pSettingsHolder.refreshDeviceInfo(null);
mWifiP2pSettingsHolder.refreshNotice("");
}
}
设置控件监听事件:
private void setListeners() {
//打开Wifi Direct。系统中做成和WiFi关联。即WiFi打开后Wifi Direct打开。WiFi关闭,Wifi Direct关闭。
mCheckBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Log.d(TAG, "isChecked, " + isChecked);
}
});
mCheckBox.setOnClickListener(new android.view.View.OnClickListener() {
@Override
public void onClick(View view) {
if (view instanceof CheckBox) {
CheckBox checkBox = (CheckBox) view;
showToast(R.string.wifi_direct_toggle_hint);
checkBox.setChecked(!checkBox.isChecked());
}
}
});
//点击搜索到的P2P设备,若是没有连接则显示连接,若是已经连接,则显示断开连接。
mDeviceListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mIndex = position;
showDialog();
}
});
//搜索按钮,点击的时候搜索P2P设备
mWifiP2pSettingsHolder.getWifiSearchButton().setOnClickListener(
new android.view.View.OnClickListener() {
@Override
public void onClick(View view) {
discoverDevice();
}
});
}
public void discoverDevice() {
//判断当前WiFi Direct是都已经打开
if (!mIsDirectEnable) {
showToast(R.string.please_open_direct);
return;
}
if (mWifiP2pManager != null) {
//正在搜索,设置控件的显示状态。
discoverNotice(0);
mWifiP2pManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() {
public void onSuccess() {
Log.d(TAG, "discover success");
//搜索成功
discoverNotice(1);
}
public void onFailure(int reason) {
Log.e(TAG, "discover fail " + reason);
//搜索失败
discoverNotice(2);
}
});
}
}
private void discoverNotice(int status) {
String str = "";
//0:正在搜索 ;1:搜索成功 ;2:搜索失败。
switch (status) {
case 0:
str = mActivity.getResources().getString(R.string.wifi_direct_search);
break;
case 1:
str = mActivity.getResources().getString(R.string.device_search_success);
break;
case 2:
str = mActivity.getResources().getString(R.string.device_search_failed);
break;
default:
break;
}
String txt = null;
if (mIsDirectEnable) {
txt = mActivity.getResources().getString(R.string.device_list) + " " + str;
} else {
txt = mActivity.getResources().getString(R.string.device_list);
}
}
discoverpeers结束后,WIFI_P2P_PEERS_CHANGED_ACTION广播被发出。
连接或是断开Dialog:
/*
* 显示连接或是断开连接窗口
*/
private void showDialog() {
AlertDialog.Builder builder = new Builder(mActivity);
builder.setMessage(R.string.wifi_direct_cancel);
builder.setTitle(R.string.wifi_direct);
//得到指定的P2P设备
WifiP2pDevice device = (WifiP2pDevice) (mPeers.getDeviceList().toArray()[mIndex]);
//判断设备的连接状态
if (WifiP2pDevice.CONNECTED == device.status) {
builder.setPositiveButton(R.string.wifi_direct_disconnect, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//断开
disconnectDirect();
dialog.dismiss();
}
});
} else {
builder.setPositiveButton(R.string.wifi_direct_connect, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
WifiP2pDevice device = (WifiP2pDevice) (mPeers.getDeviceList().toArray()[mIndex]);
WifiP2pConfig config = getConfig(device);
//连接
connectDirect(config);
dialog.dismiss();
}
});
}
// show dialog
builder.create().show();
}
其中,断开连接:
public void disconnectDirect() {
if (null == mChannel) {
Log.e(TAG, "mChannel==null");
return;
}
mWifiP2pManager.removeGroup(mChannel, new ActionListener() {
@Override
public void onFailure(int reasonCode) {
Log.e(TAG, "disconnect failed. Reason :" + reasonCode);
}
@Override
public void onSuccess() {
Log.d(TAG, "disconnect success ");
}
});
}
连接:
public void connectDirect(WifiP2pConfig config) {
if (null == config) {
return;
}
mWifiP2pManager.connect(mChannel, config, new ActionListener() {
@Override
public void onSuccess() {
Log.d(TAG, "connect success ");
}
@Override
public void onFailure(int reason) {
Toast.makeText(mActivity, "connect failed. Retry.", Toast.LENGTH_SHORT).show();
}
});
}
public WifiP2pConfig getConfig(WifiP2pDevice device) {
WifiP2pConfig config = new WifiP2pConfig();
config.deviceAddress = device.deviceAddress;
config.wps = new WpsInfo();
switch (mWpsSetupIndex) {
case WPS_PBC:
config.wps.setup = WpsInfo.PBC;
break;
case WPS_KEYPAD:
config.wps.setup = WpsInfo.KEYPAD;
break;
case WPS_DISPLAY:
config.wps.setup = WpsInfo.DISPLAY;
break;
default:
config.wps.setup = WpsInfo.PBC;
break;
}
return config;
}