Android4.4 Bluetooth source code analysis
Recently, GOOGLE released Android4.4 and looked at the source code. There are still some changes in the Bluetooth activation process of 4.4. From the interface, the Bluetooth switch is set to the switch in settings, the widget switch can also be used. The subsequent processes are the same from different start points. Let's take a look at the systemServer. java code, where the Bluetooth service is enabled. In the case of a real machine, we are concerned about the last else branch.
If (SystemProperties. get ("ro. kernel. qemu"). equals ("1 ")){
Slog. I (TAG, "No such h Service (emulator )");
} Else if (factoryTest = SystemServer. FACTORY_TEST_LOW_LEVEL ){
Slog. I (TAG, "No Bluetooth Service (factory test )");
} Else if (! Context. getPackageManager (). hasSystemFeature
(PackageManager. FEATURE_BLUETOOTH )){
Slog. I (TAG, "No Bluetooth Service (Bluetooth Hardware Not Present )");
} Else if (disableBluetooth ){
Slog. I (TAG, "Bluetooth Service disabled by config ");
} Else {
Slog. I (TAG, "Bluetooth Manager Service ");
Bluetooth = new descrithmanagerservice (context );
ServiceManager. addService (descrithadapter. descrith_manager_service, bluetooth );
}
Let's take a look at the construction method of javasthmanagerservice. In three places, loadStoredNameAndAddress () is the place where the default name is opened for reading Bluetooth, and isw.thpersistedstateon () is used to determine whether Bluetooth is enabled. If yes, follow these steps to enable Bluetooth
Descrithmanagerservice (Context context ){
MHandler = new javasthhandler (IoThread. get (). getLooper ());
MContext = context;
MBluetooth = null;
MQBluetooth = null;
MBinding = false;
MUnbinding = false;
MEnable = false;
MState = descrithadapter. STATE_OFF;
MQuietEnableExternal = false;
MEnableExternal = false;
MAddress = null;
MName = null;
MErrorRecoveryRetryCounter = 0;
MContentResolver = context. getContentResolver ();
MCallbacks = new RemoteCallbackList ();
MQCallbacks = new RemoteCallbackList ();
MStateChangeCallbacks = new RemoteCallbackList ();
IntentFilter filter = new IntentFilter (Intent. ACTION_BOOT_COMPLETED );
Filter. addAction (fig. ACTION_LOCAL_NAME_CHANGED );
Filter. addAction (Intent. ACTION_USER_SWITCHED );
RegisterForAirplaneMode (filter );
MContext. registerReceiver (mReceiver, filter );
LoadStoredNameAndAddress ();
If (isw.thpersistedstateon ()){
MEnableExternal = true;
}
}
The registerForAirplaneMode method is as follows:
Private void registerForAirplaneMode (IntentFilter filter ){
Final ContentResolver resolver = mContext. getContentResolver ();
Final String airplaneModeRadios = Settings. Global. getString (resolver,
Settings. Global. AIRPLANE_MODE_RADIOS );
Final String toggleableRadios = Settings. Global. getString (resolver,
Settings. Global. AIRPLANE_MODE_TOGGLEABLE_RADIOS );
Boolean mIsAirplaneSensitive = airplaneModeRadios = null? True:
AirplaneModeRadios. contains (Settings. Global. RADIO_BLUETOOTH );
If (mIsAirplaneSensitive ){
Filter. addAction (Intent. ACTION_AIRPLANE_MODE_CHANGED );
}
}
Where
Settings. Global. getString (resolver,
Settings. Global. AIRPLANE_MODE_TOGGLEABLE_RADIOS)
The obtained value is defined in the String file, for example:
Cell, bluetooth, wifi, nfc, wimax
Indicates which services will be disabled if the flight mode is enabled. Therefore, the registerForAirplaneMode method means that if Bluetooth is also affected by the flight mode, the changes in the flight mode will also enable the Bluetooth service to receive the corresponding broadcast.
The switch on the interface is the BluetoothEnabler. java class, while setmediathenabled () is the specific switch action. There is a switch callback function. The Code is as follows:
Public void onCheckedChanged (CompoundButton buttonView, boolean isChecked ){
// Show toast message if Bluetooth is not allowed in airplane mode
If (isChecked
& (WifiSettings. needPrompt (mContext) |! WirelessSettings. isRadioAllowed (
MContext, Settings. Global. RADIO_BLUETOOTH ))){
Toast. makeText (mContext, R. string. wifi_in_airplane_mode,
Toast. LENGTH_SHORT). show ();
// Reset switch to off
ButtonView. setChecked (false );
}
// Shouldn't setincluthenabled (true) in airplane mode.
If (mLocalAdapter! = Null ){
If (isChecked & WifiSettings. needPrompt (mContext )){
Return;
}
MLocalAdapter. setincluthenabled (isChecked );
}
MSwitch. setEnabled (false );
}