編輯:關於Android編程
wifi相關的文件位置:
WIFI Settings應用程序位於
packages/apps/Settings/src/com/android/settings/wifi/
JAVA部分:
frameworks/base/services/java/com/android/server/
frameworks/base/wifi/java/android/net/wifi/
JNI部分:
frameworks/base/core/jni/android_net_wifi_Wifi.cpp
wifi管理庫。
hardware/libhardware_legary/wifi/
wifi用戶空間的程序和庫:
external/wpa_supplicant/
生成庫libwpaclient.so和守護進程wpa_supplicant。
調用流程:
wifi模塊的初始化:
(frameworks/base/services/java/com/android/server/SystemServer.Java)
在 SystemServer 啟動的時候,會生成一個ConnectivityService 的實例,
classServerThread extends Thread {
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
try { Slog.i(TAG,"Connectivity Service"); connectivity= ConnectivityService.getInstance(context); ServiceManager.addService(Context.CONNECTIVITY_SERVICE,connectivity); } catch(Throwable e) { Slog.e(TAG,"Failure starting Connectivity Service", e); } 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。 }
其中 ,ConnectivityService.getInstance(context); 對應於(frameworks/base/services/java/com/android/server/ ConnectivityService.Java)ConnectivityService.Java。
下面看下ConnectivityService.Java中的
public static ConnectivityServicegetInstance(Context context) { return ConnectivityThread.getServiceInstance(context); }函數, 繼續往下看: public static ConnectivityService getServiceInstance(Context context) { ConnectivityThread thread = newConnectivityThread(context); thread.start(); synchronized (thread) { while (sServiceInstance == null) { try { // Wait until sServiceInstance has beeninitialized. thread.wait(); } catch (InterruptedExceptionignore) { Slog.e(TAG, "UnexpectedInterruptedException while waiting"+ " forConnectivityService thread"); } } } return sServiceInstance; } }
繼續往下跟:
private static class ConnectivityThread extends Thread { private Context mContext; private ConnectivityThread(Context context) { super("ConnectivityThread"); mContext = context; } @Override public void run() { Looper.prepare(); synchronized (this) { sServiceInstance = newConnectivityService(mContext); notifyAll(); } Looper.loop(); } public static ConnectivityService getServiceInstance(Context context) { ConnectivityThread thread = new ConnectivityThread(context); thread.start(); synchronized (thread) { while (sServiceInstance == null) { try { // Wait untilsServiceInstance has been initialized. thread.wait(); } catch(InterruptedException ignore) { Slog.e(TAG, "UnexpectedInterruptedException while waiting"+ " forConnectivityService thread"); } } } return sServiceInstance; } }
繼續newConnectivityService(mContext)
private ConnectivityService(Context context) { 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。 for(int netType : mPriorityList) { switch (mNetAttributes[netType].mRadio) { case ConnectivityManager.TYPE_WIFI: Slog.v(TAG, "Starting Wifi Service."); WifiStateTracker wst = newWifiStateTracker(context, mHandler); WifiService wifiService = newWifiService(context, wst); ServiceManager.addService(Context.WIFI_SERVICE,wifiService); wifiService.startWifi();//啟動wifiservice mNetTrackers[ConnectivityManager.TYPE_WIFI] = wst; wst.startMonitoring();//啟動Monitoring break; 。。。。。 }//endfor 。。。。。。。。。。。。。。。。。。。。。。。。。。 }
到這裡模塊初始化的工作完成,具體流程圖如下:
WifiStateTracker 會創建 WifiMonitor 接收來自底層的事件, WifiService 和 WifiMonitor 是整個模塊的核心。WifiService 負責啟動關閉 wpa_supplicant、啟動關閉 WifiMonitor 監視線程和把命令下發給 wpa_supplicant,而 WifiMonitor 則負責從 wpa_supplicant 接收事件通知。
也就是說WifiService負責wifi整個流程的控制,而WifiMonitor負責監視底層的事件。
此時WifiService starting up withWi-Fi disabled,
Wifi模塊的啟動(Enable):
(packages/apps/Settings/src/com/android/settings/wifi/ WirelessSettings.java)
WirelessSettings 在初始化的時候配置了由WifiEnabler 來處理Wifi 按鈕,
protected void onCreate(BundlesavedInstanceState) { super.onCreate(savedInstanceState); mWifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE); if (getIntent().getBooleanExtra("only_access_points",false)) { addPreferencesFromResource(R.xml.wifi_access_points); } else { addPreferencesFromResource(R.xml.wifi_settings); mWifiEnabler = new WifiEnabler(this, (CheckBoxPreference)findPreference("enable_wifi")); mNotifyOpenNetworks = (CheckBoxPreference)findPreference("notify_open_networks"); mNotifyOpenNetworks.setChecked(Secure.getInt(getContentResolver(), Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,0) == 1); } mAccessPoints = (ProgressCategory)findPreference("access_points"); mAccessPoints.setOrderingAsAdded(false); mAddNetwork =findPreference("add_network"); registerForContextMenu(getListView()); }
2012-03-26 jemeen 摘自 csdn博客 閱 4092 轉 39 轉藏到我的圖書館 微信 分享: 在網上找的一篇好文章,分析的很詳細,自己再加了些東西,圖片有點大,不能完全顯示,點擊圖像拖動鼠標直接查看圖像。 wifi相關的文件位置: WIFI Settings應用程序位於 packages/apps/Settings/src/com/android/settings/wifi/ JAVA部分: frameworks/base/services/java/com/android/server/ frameworks/base/wifi/java/android/net/wifi/ JNI部分: frameworks/base/core/jni/android_net_wifi_Wifi.cpp wifi管理庫。 hardware/libhardware_legary/wifi/ wifi用戶空間的程序和庫: external/wpa_supplicant/ 生成庫libwpaclient.so和守護進程wpa_supplicant。 調用流程: wifi模塊的初始化: (frameworks/base/services/java/com/android/server/SystemServer.Java) 在 SystemServer 啟動的時候,會生成一個ConnectivityService 的實例, classServerThread extends Thread { 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。 try { Slog.i(TAG,"Connectivity Service"); connectivity= ConnectivityService.getInstance(context); ServiceManager.addService(Context.CONNECTIVITY_SERVICE,connectivity); } catch(Throwable e) { Slog.e(TAG,"Failure starting Connectivity Service", e); } 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。 } 其中 ,ConnectivityService.getInstance(context); 對應於(frameworks/base/services/java/com/android/server/ ConnectivityService.Java)ConnectivityService.Java。 下面看下ConnectivityService.Java中的 public static ConnectivityServicegetInstance(Context context) { return ConnectivityThread.getServiceInstance(context); }函數, 繼續往下看: public static ConnectivityService getServiceInstance(Context context) { ConnectivityThread thread = newConnectivityThread(context); thread.start(); synchronized (thread) { while (sServiceInstance == null) { try { // Wait until sServiceInstance has beeninitialized. thread.wait(); } catch (InterruptedExceptionignore) { Slog.e(TAG, "UnexpectedInterruptedException while waiting"+ " forConnectivityService thread"); } } } return sServiceInstance; } } 繼續往下跟: private static class ConnectivityThread extends Thread { private Context mContext; private ConnectivityThread(Context context) { super("ConnectivityThread"); mContext = context; } @Override public void run() { Looper.prepare(); synchronized (this) { sServiceInstance = newConnectivityService(mContext); notifyAll(); } Looper.loop(); } public static ConnectivityService getServiceInstance(Context context) { ConnectivityThread thread = new ConnectivityThread(context); thread.start(); synchronized (thread) { while (sServiceInstance == null) { try { // Wait untilsServiceInstance has been initialized. thread.wait(); } catch(InterruptedException ignore) { Slog.e(TAG, "UnexpectedInterruptedException while waiting"+ " forConnectivityService thread"); } } } return sServiceInstance; } } 繼續newConnectivityService(mContext) private ConnectivityService(Context context) { 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。 for(int netType : mPriorityList) { switch (mNetAttributes[netType].mRadio) { case ConnectivityManager.TYPE_WIFI: Slog.v(TAG, "Starting Wifi Service."); WifiStateTracker wst = newWifiStateTracker(context, mHandler); WifiService wifiService = newWifiService(context, wst); ServiceManager.addService(Context.WIFI_SERVICE,wifiService); wifiService.startWifi();//啟動wifiservice mNetTrackers[ConnectivityManager.TYPE_WIFI] = wst; wst.startMonitoring();//啟動Monitoring break; 。。。。。 }//endfor 。。。。。。。。。。。。。。。。。。。。。。。。。。 } 到這裡模塊初始化的工作完成,具體流程圖如下: WifiStateTracker 會創建 WifiMonitor 接收來自底層的事件, WifiService 和 WifiMonitor 是整個模塊的核心。WifiService 負責啟動關閉 wpa_supplicant、啟動關閉 WifiMonitor 監視線程和把命令下發給 wpa_supplicant,而 WifiMonitor 則負責從 wpa_supplicant 接收事件通知。 也就是說WifiService負責wifi整個流程的控制,而WifiMonitor負責監視底層的事件。 此時WifiService starting up withWi-Fi disabled, Wifi模塊的啟動(Enable): (packages/apps/Settings/src/com/android/settings/wifi/ WirelessSettings.java) WirelessSettings 在初始化的時候配置了由WifiEnabler 來處理Wifi 按鈕, protected void onCreate(BundlesavedInstanceState) { super.onCreate(savedInstanceState); mWifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE); if (getIntent().getBooleanExtra("only_access_points",false)) { addPreferencesFromResource(R.xml.wifi_access_points); } else { addPreferencesFromResource(R.xml.wifi_settings); mWifiEnabler = new WifiEnabler(this, (CheckBoxPreference)findPreference("enable_wifi")); mNotifyOpenNetworks = (CheckBoxPreference)findPreference("notify_open_networks"); mNotifyOpenNetworks.setChecked(Secure.getInt(getContentResolver(), Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,0) == 1); } mAccessPoints = (ProgressCategory)findPreference("access_points"); mAccessPoints.setOrderingAsAdded(false); mAddNetwork =findPreference("add_network"); registerForContextMenu(getListView()); } 然後調用:(packages/apps/Settings/src/com/android/settings/wifi/ WifiEnabler.java) publicclass WifiEnabler implements Preference.OnPreferenceChangeListener { 。。。。。。。。。。。。。。。。。。。。。。 public boolean onPreferenceChange(Preferencepreference, Object value) { 。。。。。。。。。。。。。。。。。。。。。。。。。。。 if (mWifiManager.setWifiEnabled(enable)){ mCheckBox.setEnabled(false); } else { mCheckBox.setSummary(R.string.wifi_error); } 。。。。。。。。。。。。。。。。。。。。。。 } 。。。。。。。。。。。。。。。。。。。。。 }
調用:
(packages/apps/Settings/src/com/android/settings/wifi/ WifiManager.java)
public boolean setWifiEnabled(booleanenabled) { try { returnmService.setWifiEnabled(enabled); } catch(RemoteException e) { returnfalse; } }
當用戶按下 Wifi 按鈕後,Android 會調用 WifiEnabler 的onPreferenceChange,再由 WifiEnabler調用 WifiManager 的 setWifiEnabled 接口函數,通過 AIDL,實際調用的是 WifiService 的setWifiEnabled 函數,WifiService 接著向自身發送一條 MESSAGE_ENABLE_WIFI 消息,在處理該消息的代碼中做真正的使能工作:首先裝載 WIFI 內核模塊(該模塊的位置硬編碼為"/system/lib/modules/wlan.ko" ), 然 後 啟 動 wpa_supplicant ( 配 置 文 件 硬 編 碼 為"/data/misc/wifi/wpa_supplicant.conf")再通過 WifiStateTracker 來啟動 WifiMonitor 中的監視線程。
WifiService(WifiService.java) 收到MESSAGE_ENABLE_WIFI 消息後的操作如下:
AIDL:
Android Interface Definition Language,即Android接口描述語言。Android系統中的進程之間不能共享內存,因此,需要提供一些機制在不同進程之間進行數據通信。
為了使其他的應用程序也可以訪問本應用程序提供的服務,Android系統采用了遠程過程調用(Remote Procedure Call,RPC)方式來實現。與很多其他的基於RPC的解決方案一樣,Android使用一種接口定義語言(InterfaceDefinition Language,IDL)來公開服務的接口。因此,可以將這種可以跨進程訪問的服務稱為AIDL(Android Interface Definition Language)服務。
接下來繼續道wifiService.Java
(frameworks/base/services/java/com/android/server/ wifiService.Java)
public boolean setWifiEnabled(boolean enable) { enforceChangePermission(); if (mWifiHandler == null) return false; synchronized (mWifiHandler) { // caller may not have WAKE_LOCKpermission - it's not required here long ident =Binder.clearCallingIdentity(); sWakeLock.acquire(); Binder.restoreCallingIdentity(ident); mLastEnableUid =Binder.getCallingUid(); // set a flag if the user isenabling Wifi while in airplane mode mAirplaneModeOverwridden = (enable&& isAirplaneModeOn() && isAirplaneToggleable()); sendEnableMessage(enable, true,Binder.getCallingUid()); // here send a mesage to himself } return true; } 繼續往下: private void sendEnableMessage(boolean enable,boolean persist, int uid) { Message msg= Message.obtain(mWifiHandler, (enable ?MESSAGE_ENABLE_WIFI : MESSAGE_DISABLE_WIFI), (persist ? 1 : 0), uid); msg.sendToTarget(); } WifiHandler會收到消息: private class WifiHandlerextends Handler { 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。 public voidhandleMessage(Message msg) { switch (msg.what) { case MESSAGE_ENABLE_WIFI: setWifiEnabledBlocking(true, msg.arg1 == 1,msg.arg2); if (mWifiWatchdogService ==null) { mWifiWatchdogService = newWifiWatchdogService(mContext, mWifiStateTracker); } sWakeLock.release(); break; 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。 } 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。 } privateboolean setWifiEnabledBlocking(booleanenable, boolean persist, int uid) { 。。。。。。。。。。。。 setWifiEnabledState(enable ?WIFI_STATE_ENABLING : WIFI_STATE_DISABLING, uid); if (enable) { if (!mWifiStateTracker.loadDriver()){ Slog.e(TAG, "Failed toload Wi-Fi driver."); setWifiEnabledState(WIFI_STATE_UNKNOWN, uid); return false; } if (!mWifiStateTracker.startSupplicant()){ mWifiStateTracker.unloadDriver(); Slog.e(TAG, "Failed tostart supplicant daemon."); setWifiEnabledState(WIFI_STATE_UNKNOWN, uid); return false; } registerForBroadcasts(); mWifiStateTracker.startEventLoop(); } else { mContext.unregisterReceiver(mReceiver); // Remove notification (it willno-op if it isn't visible) mWifiStateTracker.setNotificationVisible(false,0, false, 0); booleanfailedToStopSupplicantOrUnloadDriver = false; if (!mWifiStateTracker.stopSupplicant()){ Slog.e(TAG, "Failed tostop supplicant daemon."); setWifiEnabledState(WIFI_STATE_UNKNOWN,uid); failedToStopSupplicantOrUnloadDriver = true; } /** * Reset connections and disableinterface * before we unload the driver */ mWifiStateTracker.resetConnections(true); if (!mWifiStateTracker.unloadDriver()){ Slog.e(TAG, "Failed tounload Wi-Fi driver."); if(!failedToStopSupplicantOrUnloadDriver) { setWifiEnabledState(WIFI_STATE_UNKNOWN, uid); failedToStopSupplicantOrUnloadDriver = true; } } if(failedToStopSupplicantOrUnloadDriver) { return false; } } 。。。。。。。。。。。。。。。。。。。。。。 }
掃描查找熱點(AP)
上一節中講到Wifi模塊開啟後會對外發送WIFI_STATE_CHANGED_ACTION。WifiLayer中注冊了Action的Receiver。
當WifiLayer收到此Action後開始scan的流程,具體如下:
當wpa_supplicant 處理完SCAN 命令後,它會向控制通道發送事件通知掃描完成,從wifi_wait_for_event函數會接收到該事件,由此WifiMonitor 中的MonitorThread會被執行來出來這個事件:
配置 AP 參數
當用戶在WifiSettings 界面上選擇了一個AP 後,會顯示配置AP 參數的一個對話框:
Wifi連接
具體流程參見以下流程圖:
IP地址的配置
流程如圖:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ end ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
有時候,看到一些界面上的色彩,心情可能會很舒暢,有時候,看到一些其他色彩,就覺得很討厭,不爽,看到android L Palette 從圖片中提取篩選出來的顏色,覺得都挺
今天分享的是用系統自帶的相機實現一鍵拍照功能。public class MainActivity extends AppCompatActivity {private s
引言在android開發過程中,我們不可避免的會使用廣播,比如,偵聽開機,偵聽短信。而對於廣播,我想很多人都知道他有兩種類型,動態廣播,通過代碼在runtime進行reg
(1)首先實現AutoCompleteTextView功能所需要的適配器數據源共有兩種方法,一種結果是手工配置的,另一匯總是通過xml文件制定的數據(當然也