Turn: http://blog.csdn.net/liuying_0408/article/details/7446631
As mentioned above, the WiFi startup process, of course, will then scan the hotspot (AP), then display the scanned AP, configure the AP (fill in the IP address and other information) connect to the AP, obtain the IP address, and finally connect to the Internet!
I. Scanning Hotspots (AP)
After WiFi is successfully started above: // success!
Setwifienabledstate (eventualwifistate, UID );
Private void setwifienabledstate (INT wifistate, int UID ){
// Broadcast
Final intent = new intent (wifimanager. wifi_state_changed_action );
}
After successful enabling, it will broadcast and sendWifi_state_changed_actionThis intent notifies the outside world that WiFi has been successfully enabled. When wifilayer is created, it will register with Android to receive wifi_state_changed_action, so it will receive the intent and start scanning.
Wifisetting. Java:
Protected void oncreate (bundle savedinstancestate ){
Mwifilayer.Oncreate();
}
Certificate -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Wifilayer. Java:
Public voidOncreate(){
Mwifimanager = (wifimanager) mcontext. getsystemservice (context. wifi_service );
Mintentfilter = new intentfilter ();
Mintentfilter. addaction (wifimanager. network_state_changed_action );
Mintentfilter. addaction (wifimanager. scan_results_available_action );
Mintentfilter. addaction (wifimanager.Wifi_state_changed_action);
}
Public void onresume (){
Mcontext. registerreceiver (mreceiver, mintentfilter );
If (iswifienabled ()){
// Kick start the continual Scan
Queuecontinuousscan ();
}
}
The above is part of the event received by wifilayer. Java registration. Some events are processed as follows:
Private broadcastreceiver mreceiver = new broadcastreceiver (){
Private broadcastreceiver mreceiver = new broadcastreceiver (){
Public voidOnreceive(Context, intent ){
Final string action = intent. getaction ();
If (action. Equals (wifimanager. network_state_changed_action )){
Handlenetworkstatechanged (
(Networkinfo) intent. getparcelableextra (wifimanager. extra_network_info ),
Intent. getstringextra (wifimanager. extra_bssid ));
} Else if (action. Equals (wifimanager. scan_results_available_action )){
Handlescanresultsavailable ();
}......
Else if (action. Equals (wifimanager.Wifi_state_changed_action)){
Handlewifistatechanged(Intent. getintextra (wifimanager. extra_wifi_state,
Wifimanager. wifi_state_unknown ));
}
}
};
From an acceptable event, when wifi_state_changed_action, the corresponding processing functions include:
Handlewifistatechanged(Intent. getintextra (wifimanager. extra_wifi_state,
Wifimanager. wifi_state_unknown ));
Private void handlewifistatechanged (INT wifistate ){
Attemptscan();
............
}
Public void attemptscan (){
If (! Mwifimanager.Startscanactive()){
Postattemptscan ();
}
}
Wifimanager. Java:
Public Boolean startscanactive (){
Return mservice. startscan (true );
}
-------AidlCertificate -------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Wifiservice. Java:
Public Boolean startscan (Boolean forceactive ){
............
Return wifinative.Scancommand(Forceactive );
}
---------JNICertificate ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Android_net_wifi_wifi.cpp:
{"Scancommand", "(z) Z", (void *)Android_net_wifi_scancommand},
Static jboolean android_net_wifi_scancommand (jnienv * ENV, jobject clazz, jboolean forceactive)
{
............
Result = dobooleancommand ("scan", "OK ");
}
Static jboolean dobooleancommand (const char * cmd, const char * expect CT)
{
If (Docommand(CMD, reply, sizeof (reply ))! = 0 ){
Return (jboolean) jni_false;
}
}
Static int docommand (const char * cmd, char * replybuf, int replybuflen)
{
If (::Wifi_command(CMD, replybuf, & reply_len )! = 0)
Return-1;
............
}
-------HalCertificate ------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Wifi. C:
Int wifi_command (const char * command, char * reply, size_t * reply_len)
{
ReturnWifi_send_command(Ctrl_conn, command, reply, reply_len );
}
Int wifi_send_command (struct wpa_ctrl * Ctrl, const char * cmd, char * reply, size_t * reply_len)
{
Ret =Wpa_ctrl_request(CTRL, CMD, strlen (CMD), reply, reply_len, null );
............
}
Wpa_ctrl.c:
Int wpa_ctrl_request () inWpa_ctrl.cIs to execute the scan command.
Ii. display the scanned AP
After the scan is completed, the monitorthread in the wifimonitor will be executed for this event:
Void handleevent (INT event, string remainder ){
Switch (event ){
Case scan_results:
Mwifistatetracker. yyscanresultsavailable ();
-> Sendemptymessage (event_scan_results_available );
Break;
}
Wifistatetracker. Java
Public void handlemessage (Message MSG ){
Switch (msg. What ){
Case event_scan_results_available:
If (activitymanagernative. issystemready ()){
Mcontext. sendbroadcast (new intent (wifimanager. scan_results_available_action ));
}
}
Wifilayer registration receives the intent scan_results_available_action:
Private broadcastreceiver mreceiver = new broadcastreceiver (){
@ Override
Public void onreceive (context, intent ){
Else if (action. Equals (wifimanager.Scan_results_available_action))
{
Handlescanresultsavailable();
}
Handlescanresultsavailable();
-> List = mwifimanager. getscanresults ();
-> Mcallback. onaccesspointsetchanged (AP, true );
In handlescanresultsavailable (), the scan result is obtained first (the scan_result command is finally sent to wpa_supplicant and the return value is read, wifilayer calls back the onaccesspointsetchanged function of wifisetting and adds the AP to the GUI display list.
3. Configure the AP
After you select an AP on the wifisettings interface, a dialog box for configuring the AP parameters is displayed:
Public BooleanOnpreferencetreeclick()
-> Showaccesspointdialog (State, accesspointdialog. mode_info );
-> Accesspointdialog dialog =
New accesspointdialog (this, mwifilayer );
Showdialog(DIALOG );
After you select the encryption method and enter the key in accesspointdialog, and then click the connect button, Android will connect to the AP.
4. Connect to the AP
Click Connect in accesspointdialog. Java and the following code is executed:
Public voidOnclick(Dialoginterface dialog, int which ){
Handleconnect ();
-> Mwifilayer. connecttonetwork (mstate );
-> // Need wificonfiguration for the AP
Wificonfiguration Config = findconfigurednetwork (State );
Config = addconfiguration (State, 0 );
Managerenablenetwork (State, false)
-> Mwifimanager. eNablenetwork()
-> Mservice. enalbenetwork ()
->Wifinative. enablenetworkcommand()
Next we will go to JNI {"Enablenetworkcommand"," (IZ) Z ", (void *)Android_net_wifi_enablenetworkcommand}. Finally, the connection command is sent to wpa_supplicant.
5. Obtain the IP address
After wpa_supplicant successfully connects to the AP, it will send an event notification to the control channel to connect to the AP, so that the wifi_wait_for_event function will receive the event, therefore, monitorthread in the wifimonitor will be executed for this event:
Void handleevent (INT event, string remainder ){
Switch (event ){
Case connected:
Handlenetworkstatechange ();
-> Mwifistatetracker. policystatechange (newstate, bssid, networkid );
-> Msg. sendtotarget ();
Break;
}
Wifistatetracker. Java
Public void handlemessage (Message MSG ){
Switch (msg. What ){
Case event_network_state_changed:
Sendnetworkstatechangebroadcast (mwifiinfo. getbssid ());
}
}
If (changed), the observer for the WiFi-related database registered in wifistatetracker starts:
Private void configureinterface ()
-> Mdhcptarget. sendemptymessage ();
Private class dhcphandler extends Handler
Handlemessage()
-> Switch (msg. What ){
CaseEvent_dhcp_start:
Target. sendemptymessage (event );
Dhcphandler sends the event_dhcp_start message to start DHCP to obtain the IP address. After DHCP receives the IP address, it sends the event_interface_configuration_succeeded message, and then the handlemessage in wifistatetacker processes the message.
CaseEvent_interface_configuration_succeeded:
Sendnetworkstatechangebroadcast (mwifiinfo. getbssid ());
-> Intent = new intent (wifimanager. network_state_changed_action );
-> Mcontext.Sendstickybroadcast(Intent );
Complete IP address information is provided this time. If the receiver of the intent is registered in wifilayer, handlenetworkstatechanged is called for processing. Finally, you can freely access the internet.