WifiP2pSettings工作流程
生活随笔
收集整理的這篇文章主要介紹了
WifiP2pSettings工作流程
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
本文為《深入理解Android Wi-Fi、NFC和GPS卷》讀書筆記,Android源碼為Android 5.1
Android平臺中,P2P操作用戶只需執(zhí)行如下三個(gè)步驟:
1)進(jìn)入WifiP2pSettings界面;
2)搜索周圍的P2P設(shè)備。搜索到的設(shè)備將顯示在WifiP2pSettings中。
3)用戶選擇其中的某個(gè)設(shè)備以發(fā)起連接。
首先來看WifiP2pSettings的onActivityCreate函數(shù)。
1.WifiP2pSettings創(chuàng)建
2.WifiP2pSettings工作流程
1)WIFI_P2P_STATE_CHANGED_ACTION處理流程
打開WifiP2pSettings后,首先要等待 WIFI_P2P_STATE_CHANGED_ACTION廣播以判斷P2P功能是否正常啟動(dòng)。相應(yīng)的處理函數(shù)如下所示:
android-5.1/packages/apps/Settings/src/com/android/settings/wifi/p2p/WifiP2pSettings.java
當(dāng)P2P功能正常啟用后(即上述代碼中的mWifiP2pEnabled為true時(shí)),這兩個(gè)按鈕將被使能。此后,用戶就可單擊SEARCH按鈕以搜索周圍的P2P設(shè)備。該按鈕對應(yīng)的函數(shù)是startSearch。
當(dāng)系統(tǒng)搜索到新的P2P設(shè)備后,WIFI_P2P_PEERS_CHANGED_ACTION廣播將被發(fā)送,而WifiP2pSettings對于該廣播的處理就是調(diào)用WifiP2pManager的requestPeers來獲取系統(tǒng)保存的P2P設(shè)備信息列表
系統(tǒng)中所有的P2P設(shè)備信息將通過PeerListener接口類的onPeersAvailable函數(shù)返回給WifiP2pSettings:
接下來用戶就可在界面中選擇某個(gè)P2P設(shè)備并與之連接,這個(gè)步驟由onPreferenceTreeClick函數(shù)來完成。
當(dāng)系統(tǒng)完成和P2P設(shè)備的連接后,WifiP2pSettings將收到 WIFI_P2P_CONNECTION_CHANGED_ACTION 廣播,對應(yīng)的代碼見onReceive
Android平臺中,P2P操作用戶只需執(zhí)行如下三個(gè)步驟:
1)進(jìn)入WifiP2pSettings界面;
2)搜索周圍的P2P設(shè)備。搜索到的設(shè)備將顯示在WifiP2pSettings中。
3)用戶選擇其中的某個(gè)設(shè)備以發(fā)起連接。
首先來看WifiP2pSettings的onActivityCreate函數(shù)。
1.WifiP2pSettings創(chuàng)建
android-5.1/packages/apps/Settings/src/com/android/settings/wifi/p2p/WifiP2pSettings.java
public void onActivityCreated(Bundle savedInstanceState) {addPreferencesFromResource(R.xml.wifi_p2p_settings);//加載界面元素/*WifiP2pSettings也是通過監(jiān)聽廣播的方式來了解系統(tǒng)中Wi-Fi P2P相關(guān)的信息及變化情況。下面這幾個(gè)廣播屬于P2P特有的,其作用如下:WIFI_P2P_STATE_CHANGED_ACTION:用于通知系統(tǒng)中P2P功能的啟用情況,如該功能是enable還是disable。WIFI_P2P_PEERS_CHANGED_ACTION:系統(tǒng)內(nèi)部將保存搜索到的其他P2P設(shè)備信息,如果這些信息有變化,則系統(tǒng)將發(fā)送該廣播。接收者需要通過WifiP2PManager的requestPeers函數(shù)重新獲取這些P2P設(shè)備的信息。WIFI_P2P_CONNECTION_CHANGED_ACTION:用于通知P2P連接情況,該廣播可攜帶WifiP2pInfo和NetworkInfo兩個(gè)對象。相關(guān)信息可從這兩個(gè)對象中獲取。WIFI_P2P_THIS_DEVICE_CHANGED_ACTION:用于通知本機(jī)P2P設(shè)備信息發(fā)生了變化。WIFI_P2P_DISCOVERY_CHANGED_ACTION:用于通知P2P Device Discovery的工作狀態(tài),如啟動(dòng)或停止。WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION:用于通知persistent group信息發(fā)生了變化。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);mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION);mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION);final Activity activity = getActivity();//創(chuàng)建WifiP2pManager對象,它將和WifiP2pService交互mWifiP2pManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);if (mWifiP2pManager != null) {//初始化WifiManager并建立和WiFiService的聯(lián)系mChannel = mWifiP2pManager.initialize(activity, getActivity().getMainLooper(), null);if (mChannel == null) {//Failure to set up connectionLog.e(TAG, "Failed to set up connection with wifi p2p service");mWifiP2pManager = null;}} else {Log.e(TAG, "mWifiP2pManager is null !");}if (savedInstanceState != null && savedInstanceState.containsKey(SAVE_DIALOG_PEER)) {WifiP2pDevice device = savedInstanceState.getParcelable(SAVE_DIALOG_PEER);mSelectedWifiPeer = new WifiP2pPeer(getActivity(), device);}if (savedInstanceState != null && savedInstanceState.containsKey(SAVE_DEVICE_NAME)) {mSavedDeviceName = savedInstanceState.getString(SAVE_DEVICE_NAME);}if (savedInstanceState != null && savedInstanceState.containsKey(SAVE_SELECTED_GROUP)) {mSelectedGroupName = savedInstanceState.getString(SAVE_SELECTED_GROUP);}//創(chuàng)建UI中按鈕對應(yīng)的onClickListenermRenameListener = new OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {if (which == DialogInterface.BUTTON_POSITIVE) {if (mWifiP2pManager != null) {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();}});}}}};//disconnect dialog listenermDisconnectListener = new OnClickListener() {@Overridepublic 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 listenermCancelConnectListener = new OnClickListener() {@Overridepublic 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);}});}}}};//delete persistent group dialog listenermDeleteGroupListener = new OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {if (which == DialogInterface.BUTTON_POSITIVE) {if (mWifiP2pManager != null) {if (mSelectedGroup != null) {if (DBG) Log.d(TAG, " deleting group " + mSelectedGroup.getGroupName());mWifiP2pManager.deletePersistentGroup(mChannel,mSelectedGroup.getNetworkId(),new WifiP2pManager.ActionListener() {public void onSuccess() {if (DBG) Log.d(TAG, " delete group success");}public void onFailure(int reason) {if (DBG) Log.d(TAG, " delete group fail " + reason);}});mSelectedGroup = null;} else {if (DBG) Log.w(TAG, " No selected group to delete!" );}}} else if (which == DialogInterface.BUTTON_NEGATIVE) {if (DBG) {Log.d(TAG, " forgetting selected group " + mSelectedGroup.getGroupName());}mSelectedGroup = null;}}};setHasOptionsMenu(true);final PreferenceScreen preferenceScreen = getPreferenceScreen();preferenceScreen.removeAll();preferenceScreen.setOrderingAsAdded(true);mThisDevicePref = new Preference(getActivity());mThisDevicePref.setPersistent(false);mThisDevicePref.setSelectable(false);preferenceScreen.addPreference(mThisDevicePref);mPeersGroup = new PreferenceCategory(getActivity());mPeersGroup.setTitle(R.string.wifi_p2p_peer_devices);preferenceScreen.addPreference(mPeersGroup);mPersistentGroup = new PreferenceCategory(getActivity());mPersistentGroup.setTitle(R.string.wifi_p2p_remembered_groups);preferenceScreen.addPreference(mPersistentGroup);super.onActivityCreated(savedInstanceState);}
2.WifiP2pSettings工作流程
1)WIFI_P2P_STATE_CHANGED_ACTION處理流程
打開WifiP2pSettings后,首先要等待 WIFI_P2P_STATE_CHANGED_ACTION廣播以判斷P2P功能是否正常啟動(dòng)。相應(yīng)的處理函數(shù)如下所示:
android-5.1/packages/apps/Settings/src/com/android/settings/wifi/p2p/WifiP2pSettings.java
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {//從 WIFI_P2P_STATE_CHANGED_ACTION廣播中獲取相關(guān)狀態(tài)信息以判斷P2P功能是否打開mWifiP2pEnabled = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE,WifiP2pManager.WIFI_P2P_STATE_DISABLED) == WifiP2pManager.WIFI_P2P_STATE_ENABLED;handleP2pStateChanged();//如果搜索到新的P2P設(shè)備,則WIFI_P2P_PEERS_CHANGED_ACTION將被發(fā)送} else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {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 eventstartSearch(); //如果沒有加入某個(gè)P2P組,則重新發(fā)起設(shè)備掃描}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);//更新SEARCH按鈕顯示的名稱} else {updateSearchMenu(false);}} else if (WifiP2pManager.WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION.equals(action)) {if (mWifiP2pManager != null) {mWifiP2pManager.requestPersistentGroupInfo(mChannel, WifiP2pSettings.this);}}}};
private void handleP2pStateChanged() {updateSearchMenu(false);//該函數(shù)將觸發(fā)WifiP2pSettings的onCreateOptionsMenu被調(diào)用mThisDevicePref.setEnabled(mWifiP2pEnabled);mPeersGroup.setEnabled(mWifiP2pEnabled);mPersistentGroup.setEnabled(mWifiP2pEnabled);}用戶下一步要做的事情就是主動(dòng)搜索周圍的P2P設(shè)備。Android原生代碼中的WifiP2pSettings界面下方有兩個(gè)按鈕,分別是SEARCH和RENAME,分別用于搜索周圍的P2P Device和更改本機(jī)的P2P設(shè)備名。
當(dāng)P2P功能正常啟用后(即上述代碼中的mWifiP2pEnabled為true時(shí)),這兩個(gè)按鈕將被使能。此后,用戶就可單擊SEARCH按鈕以搜索周圍的P2P設(shè)備。該按鈕對應(yīng)的函數(shù)是startSearch。
private void startSearch() {if (mWifiP2pManager != null && !mWifiP2pSearching) {//discoverPeers將搜索周圍的P2P設(shè)備mWifiP2pManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() {public void onSuccess() {}public void onFailure(int reason) {if (DBG) Log.d(TAG, " discover fail " + reason);}});}}當(dāng)WPAS完成搜索后, WIFI_P2P_PEERS_CHANGED_ACTION廣播將被發(fā)送。對該廣播的處理參考o(jì)nReceive函數(shù)。startSearch還將觸發(fā)系統(tǒng)發(fā)送 WIFI_P2P_DISCOVERY_CHANGED_ACTION廣播,WifiP2pSettings將根據(jù)該廣播攜帶的信息來更新SEARCH按鈕的界面:如果P2P Discovery啟動(dòng)成功(即狀態(tài)變?yōu)?WIFI_P2P_DISCOVERY_STARTED),則SEARCH按鈕名稱顯示為Searching,否則該按鈕顯示為Search For Devices。
當(dāng)系統(tǒng)搜索到新的P2P設(shè)備后,WIFI_P2P_PEERS_CHANGED_ACTION廣播將被發(fā)送,而WifiP2pSettings對于該廣播的處理就是調(diào)用WifiP2pManager的requestPeers來獲取系統(tǒng)保存的P2P設(shè)備信息列表
系統(tǒng)中所有的P2P設(shè)備信息將通過PeerListener接口類的onPeersAvailable函數(shù)返回給WifiP2pSettings:
public void onPeersAvailable(WifiP2pDeviceList peers) {if (DBG) Log.d(TAG, "Requested peers are available");//系統(tǒng)中所有的P2P設(shè)備信息都保存在這個(gè)類型為WifiP2pDeviceList的peers對象中mPeers = peers;handlePeersChanged();}
private void handlePeersChanged() {mPeersGroup.removeAll();//mPeersGroup類型為PreferenceGroup,屬于UI相關(guān)的類mConnectedDevices = 0;if (DBG) Log.d(TAG, "List of available peers");for (WifiP2pDevice peer: mPeers.getDeviceList()) {if (DBG) Log.d(TAG, "-> " + peer);//WifiP2pPeer是Preference的子類,它和UI相關(guān)mPeersGroup.addPreference(new WifiP2pPeer(getActivity(), peer));if (peer.status == WifiP2pDevice.CONNECTED) mConnectedDevices++;}if (DBG) Log.d(TAG, " mConnectedDevices " + mConnectedDevices);}在該函數(shù)中,WifiP2pDeviceList中保存的每一個(gè)WifiP2pDevice信息將作為一個(gè)Preference項(xiàng)添加到mPeersGroup中并顯示在UI界面上。
接下來用戶就可在界面中選擇某個(gè)P2P設(shè)備并與之連接,這個(gè)步驟由onPreferenceTreeClick函數(shù)來完成。
public boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) {if (preference instanceof WifiP2pPeer) {mSelectedWifiPeer = (WifiP2pPeer) preference;//獲取用戶指定的那一個(gè)WifiP2pPeer項(xiàng)if (mSelectedWifiPeer.device.status == WifiP2pDevice.CONNECTED) {showDialog(DIALOG_DISCONNECT);//如果已經(jīng)和該設(shè)備連接,則判斷是否需要與之?dāng)嚅_連接} else if (mSelectedWifiPeer.device.status == WifiP2pDevice.INVITED) {showDialog(DIALOG_CANCEL_CONNECT);} else {//向?qū)Χ薖2P設(shè)備發(fā)起連接WifiP2pConfig config = new WifiP2pConfig();config.deviceAddress = mSelectedWifiPeer.device.deviceAddress;//判斷系統(tǒng)是否強(qiáng)制使用了某種WSC配置方法int forceWps = SystemProperties.getInt("wifidirect.wps", -1);if (forceWps != -1) {config.wps.setup = forceWps;} else {//獲取對端P2P設(shè)備支持的WSC配置方法,優(yōu)先考慮PBCif (mSelectedWifiPeer.device.wpsPbcSupported()) {config.wps.setup = WpsInfo.PBC;} else if (mSelectedWifiPeer.device.wpsKeypadSupported()) {config.wps.setup = WpsInfo.KEYPAD;} else {config.wps.setup = WpsInfo.DISPLAY;}}//通過WifiP2pManager的connect函數(shù)向?qū)Χ薖2P設(shè)備發(fā)起連接。注意,目標(biāo)設(shè)備信息保存在config對象中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();}});}} else if (preference instanceof WifiP2pPersistentGroup) {mSelectedGroup = (WifiP2pPersistentGroup) preference;showDialog(DIALOG_DELETE_GROUP);}return super.onPreferenceTreeClick(screen, preference);}
當(dāng)系統(tǒng)完成和P2P設(shè)備的連接后,WifiP2pSettings將收到 WIFI_P2P_CONNECTION_CHANGED_ACTION 廣播,對應(yīng)的代碼見onReceive
總結(jié)
以上是生活随笔為你收集整理的WifiP2pSettings工作流程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《深入理解Android:Wi-Fi,N
- 下一篇: WifiP2pService工作流程