在Android的设置->网络与互联网->WLAN->WLAN偏好设置->高级->WLAN直连
中可以找到关于Wi-Fi直连的设置,如下:
在参考其它博客时,写出来的代码并不能搜索到Wi-Fi中的其他设备,但是在这设置里面却可以。因此,找来其Android8.0的源代码作为参考,并成功解决问题。
源代码位置:
/packages/apps/Settings/src/com/android/settings/wifi/p2p/WifiP2pSettings.java
- 在线Android8.0 WiFi直连相关源代码
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/> <uses-permission android:name="android.permission.INTERNET"/>
在onResume()
中注册广播接收,在onPause()
中取消广播接收。
/** * Broadcast intent action to indicate whether Wi-Fi p2p is enabled or disabled. An * extra {@link #EXTRA_WIFI_STATE} provides the state information as int. * * @see #EXTRA_WIFI_STATE */ mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION); /** * Broadcast intent action indicating that the available peer list has changed. This * can be sent as a result of peers being found, lost or updated. * * <p> An extra {@link #EXTRA_P2P_DEVICE_LIST} provides the full list of * current peers. The full list of peers can also be obtained any time with * {@link #requestPeers}. * * @see #EXTRA_P2P_DEVICE_LIST */ mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION); /** * Broadcast intent action indicating that the state of Wi-Fi p2p connectivity * has changed. One extra {@link #EXTRA_WIFI_P2P_INFO} provides the p2p connection info in * the form of a {@link WifiP2pInfo} object. Another extra {@link #EXTRA_NETWORK_INFO} provides * the network info in the form of a {@link android.net.NetworkInfo}. A third extra provides * the details of the group. * * @see #EXTRA_WIFI_P2P_INFO * @see #EXTRA_NETWORK_INFO * @see #EXTRA_WIFI_P2P_GROUP */ mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); /** * Broadcast intent action indicating that this device details have changed. */ mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION); /** * Broadcast intent action indicating that peer discovery has either started or stopped. * One extra {@link #EXTRA_DISCOVERY_STATE} indicates whether discovery has started * or stopped. * * <p>Note that discovery will be stopped during a connection setup. If the application tries * to re-initiate discovery during this time, it can fail. */ mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION); /** * Broadcast intent action indicating that remembered persistent groups have changed. * @hide */ mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION);
对上面广播的处理(需要留意的是,这些数据都是从Intent
中取出来的):
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)) { mWifiP2pEnabled = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, WifiP2pManager.WIFI_P2P_STATE_DISABLED) == WifiP2pManager.WIFI_P2P_STATE_ENABLED; handleP2pStateChanged(); } else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) { // 这里是直接从Intent中取出了列表数据 mPeers = (WifiP2pDeviceList) intent.getParcelableExtra( WifiP2pManager.EXTRA_P2P_DEVICE_LIST); handlePeersChanged(); } else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) { if (mWifiP2pManager == null) return; NetworkInfo networkInfo = (NetworkInfo) intent.getParcelableExtra( WifiP2pManager.EXTRA_NETWORK_INFO); WifiP2pInfo wifip2pinfo = (WifiP2pInfo) intent.getParcelableExtra( WifiP2pManager.EXTRA_WIFI_P2P_INFO); if (networkInfo.isConnected()) { if (DBG) Log.d(TAG, "Connected"); } else if (mLastGroupFormed != true) { //start a search when we are disconnected //but not on group removed broadcast event startSearch(); } mLastGroupFormed = wifip2pinfo.groupFormed; } else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) { mThisDevice = (WifiP2pDevice) intent.getParcelableExtra( WifiP2pManager.EXTRA_WIFI_P2P_DEVICE); if (DBG) Log.d(TAG, "Update device info: " + mThisDevice); updateDevicePref(); } else if (WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION.equals(action)) { int discoveryState = intent.getIntExtra(WifiP2pManager.EXTRA_DISCOVERY_STATE, WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED); if (DBG) Log.d(TAG, "Discovery state changed: " + discoveryState); if (discoveryState == WifiP2pManager.WIFI_P2P_DISCOVERY_STARTED) { updateSearchMenu(true); } else { updateSearchMenu(false); } } else if (WifiP2pManager.WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION.equals(action)) { if (mWifiP2pManager != null) { mWifiP2pManager.requestPersistentGroupInfo(mChannel, WifiP2pSettings.this); } } } };
点击菜单栏上的搜索后,会进行如下操作。然后会接收到相应的广播,刷新是在对相应广播的处理中进行的。
private void startSearch() { if (mWifiP2pManager != null && !mWifiP2pSearching) { mWifiP2pManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() { public void onSuccess() { } public void onFailure(int reason) { if (DBG) Log.d(TAG, " discover fail " + reason); } }); } }
在对广播的处理中,设备变化的处理主要是靠handlePeersChanged()
:
private void handlePeersChanged() { mPeersGroup.removeAll(); mConnectedDevices = 0; if (DBG) Log.d(TAG, "List of available peers"); for (WifiP2pDevice peer: mPeers.getDeviceList()) { if (DBG) Log.d(TAG, "-> " + peer); mPeersGroup.addPreference(new WifiP2pPeer(getActivity(), peer)); if (peer.status == WifiP2pDevice.CONNECTED) mConnectedDevices++; } if (DBG) Log.d(TAG, " mConnectedDevices " + mConnectedDevices); }
- 连接设备
WifiP2pConfig config = new WifiP2pConfig(); config.deviceAddress = mSelectedWifiPeer.device.deviceAddress; int forceWps = SystemProperties.getInt("wifidirect.wps", -1); if (forceWps != -1) { config.wps.setup = forceWps; } else { if (mSelectedWifiPeer.device.wpsPbcSupported()) { config.wps.setup = WpsInfo.PBC; } else if (mSelectedWifiPeer.device.wpsKeypadSupported()) { config.wps.setup = WpsInfo.KEYPAD; } else { config.wps.setup = WpsInfo.DISPLAY; } } mWifiP2pManager.connect(mChannel, config, new WifiP2pManager.ActionListener() { public void onSuccess() { if (DBG) Log.d(TAG, " connect success"); } public void onFailure(int reason) { Log.e(TAG, " connect fail " + reason); Toast.makeText(getActivity(), R.string.wifi_p2p_failed_connect_message, Toast.LENGTH_SHORT).show(); } });
- 断开连接
//disconnect dialog listener mDisconnectListener = new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if (which == DialogInterface.BUTTON_POSITIVE) { if (mWifiP2pManager != null) { mWifiP2pManager.removeGroup(mChannel, new WifiP2pManager.ActionListener() { public void onSuccess() { if (DBG) Log.d(TAG, " remove group success"); } public void onFailure(int reason) { if (DBG) Log.d(TAG, " remove group fail " + reason); } }); } } } };
- 取消已发送的邀请
//cancel connect dialog listener mCancelConnectListener = new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if (which == DialogInterface.BUTTON_POSITIVE) { if (mWifiP2pManager != null) { mWifiP2pManager.cancelConnect(mChannel, new WifiP2pManager.ActionListener() { public void onSuccess() { if (DBG) Log.d(TAG, " cancel connect success"); } public void onFailure(int reason) { if (DBG) Log.d(TAG, " cancel connect fail " + reason); } }); } } } };
mRenameListener = new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if (which == DialogInterface.BUTTON_POSITIVE) { if (mWifiP2pManager != null) { String name = mDeviceNameText.getText().toString(); if (name != null) { for (int i = 0; i < name.length(); i++) { char cur = name.charAt(i); if(!Character.isDigit(cur) && !Character.isLetter(cur) && cur != '-' && cur != '_' && cur != ' ') { Toast.makeText(getActivity(), R.string.wifi_p2p_failed_rename_message, Toast.LENGTH_LONG).show(); return; } } } mWifiP2pManager.setDeviceName(mChannel, mDeviceNameText.getText().toString(), new WifiP2pManager.ActionListener() { public void onSuccess() { if (DBG) Log.d(TAG, " device rename success"); } public void onFailure(int reason) { Toast.makeText(getActivity(), R.string.wifi_p2p_failed_rename_message, Toast.LENGTH_LONG).show(); } }); } } } };
文章来源: 从Android源代码来看WiFi直连