編輯:關於Android編程
轉載請標明出處:Android 4.2 Bluetooth 分析總結(二) 藍牙enable 的整個過程
現在開始我們分析 Android4.2 Bluetooth 打開的整個過程,由於是新手,難免有很多錯誤,記錄只是為了以後方便查找,如發錯誤敬請指出。
我們整個分析過程有可能有點繁瑣,但請仔細閱讀,讀完之後必然發現還是會有一點點收獲的,雖然寫的不好。搜先我們上一份enable 打開藍牙整個過程的打印:然後我們跟蹤打印來窺探 Android4.2Bluetooth 工作的流程。
D/BluetoothManagerService( 1646): enable(): mBluetooth =null mBinding = false D/BluetoothManagerService( 1646): Message: 1 D/BluetoothManagerService( 1646): MESSAGE_ENABLE: mBluetooth = null D/BluetoothManagerService( 1646): handleEnable quietMode = false D/BluetoothManagerService( 1646): starting bind timeout and bind D/BluetoothAdapterService( 2281): REFCOUNT: CREATED. INSTANCE_COUNT2 D/BluetoothAdapterState( 2281): make I/bluedroid( 2281): init I/bte_conf( 2281): Attempt to load stack conf from /etc/bluetooth/bt_stack.conf I/bluedroid( 2281): get_profile_interface socket I/GKI_LINUX( 2281): gki_task_entry: gki_task_entry task_id=1 [BTIF] starting I/BluetoothAdapterProperties( 2281): adapterPropertyChangedCallback with type:2 len:6 D/BluetoothManagerService( 1646): BluetoothServiceConnection: connected to AdapterService D/BluetoothManagerService( 1646): Message: 40 D/BluetoothManagerService( 1646): MESSAGE_BLUETOOTH_SERVICE_CONNECTED D/BluetoothManagerService( 1646): Calling onBluetoothServiceUp callbacks D/BluetoothManagerService( 1646): Broadcasting onBluetoothServiceUp() to 5 receivers. D/BluetoothAdapter( 1849): onBluetoothServiceUp: android.bluetooth.IBluetooth$Stub$Proxy@422dc8a8 D/BluetoothAdapter( 2281): onBluetoothServiceUp: com.android.bluetooth.btservice.AdapterService$AdapterServiceBinder@423091e0 D/BluetoothAdapter( 1646): onBluetoothServiceUp: android.bluetooth.IBluetooth$Stub$Proxy@425040e0 D/BluetoothAdapter( 1982): onBluetoothServiceUp: android.bluetooth.IBluetooth$Stub$Proxy@42c8f358 D/BluetoothAdapter( 1756): onBluetoothServiceUp: android.bluetooth.IBluetooth$Stub$Proxy@4409f528 I/BluetoothAdapterProperties( 2281): adapterPropertyChangedCallback with type:1 len:16 D/BluetoothManagerService( 1646): Bluetooth Adapter name changed to Bluedroid TV 1.0 D/BluetoothManagerService( 1646): Stored Bluetooth name: Bluedroid TV 1.0 D/BluetoothAdapterService( 2281): Broadcasting updateAdapterState() to 1 receivers. D/BluetoothManagerService( 1646): Message: 60 D/BluetoothBondStateMachine( 2281): make D/BluetoothManagerService( 1646): MESSAGE_BLUETOOTH_STATE_CHANGE: prevState = 10, newState=11 D/BluetoothManagerService( 1646): Bluetooth State Change Intent: 10 -> 11 D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: com.android.bluetooth.btservice.AdapterProperties@42309228 I/BluetoothBondStateMachine( 2281): StableState(): Entering Off State D/HeadsetService( 2281): onCreate D/HeadsetService( 2281): onStartCo[ 74.984550] #######bt_usb0: Open called count 2######### mmand() D/HeadsetService( 2281)[ 74.993399] bt_usb0: open complete : Received start request. Starting profile... D/HeadsetService( 2281): start() D/HeadsetStateMachine( 2281): make I/bluedroid( 2281): get_profile_interface handsfree E/bt-btif ( 2281): btif_enable_service: current services:0x100040 D/A2dpService( 2281): onCreate D/A2dpService( 2281): onStartCommand() D/A2dpService( 2281): Received start request. Starting profile... D/A2dpService( 2281): start() D/A2dpStateMachine( 2281): make I/bluedroid( 2281): get_profile_interface a2dp I/GKI_LINUX( 2281): gki_task_entry: gki_task_entry task_id=2 [A2DP-MEDIA] starting E/bt-btif ( 2281): btif_enable_service: current services:0x140040 D/HidService( 2281): onCreate D/A2dpStateMachine( 2281): Enter Disconnected: -2 D/HidService( 2281): onStartCommand() D/HidService( 2281): Received start request. Starting profile... D/HidService( 2281): start() I/bluedroid( 2281): get_profile_interface hidhost E/bt-btif ( 2281): btif_enable_service: current services:0x140040 D/HealthService( 2281): onCreate D/HealthService( 2281): onStartCommand() D/HealthService( 2281): Received start request. Starting profile... D/HealthService( 2281): start() I/bluedroid( 2281): get_profile_interface health D/PanService( 2281): onCreate D/PanService( 2281): onStartCommand() D/PanService( 2281): Received start request. Starting profile... D/PanService( 2281): start() D/BluetoothPanServiceJni( 2281): initializeNative(L110): pan I/bluedroid( 2281): get_profile_interface pan D/BluetoothAdapterService( 2281): Profile still not running:com.android.bluetooth.hdp.HealthService D/BluetoothAdapterService( 2281): Profile still not running:com.android.bluetooth.hdp.HealthService D/BluetoothAdapterService( 2281): Profile still not running:com.android.bluetooth.hdp.HealthService D/BluetoothAdapterService( 2281): Profile still not running:com.android.bluetooth.pan.PanService I/bluedroid( 2281): enable I/bt_hci_bdroid( 2281): init I/GKI_LINUX( 2281): gki_task_entry: gki_task_entry task_id=0 [BTU] starting V/BluetoothEventManager( 1982): Received android.bluetooth.adapter.action.STATE_CHANGED I/bt_hci_bdroid( 2281): bt_hc_worker_thread started D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: com.android.bluetooth.btservice.AdapterProperties@42309228 W/SocketClient( 937): jscese display in SocketClient send mSocket =28 , date ==222 W/SocketClient( 937): jscese display in SocketClient send mSocket =28 , date == W/SocketClient( 937): jscese display in SocketClient send mSocket =28 , date == W/SocketClient( 937): jscese display in SocketClient send mSocket =28 , date == W/SocketClient( 937): jscese display in SocketClient send mSocket =28 , date == W/SocketClient( 937): jscese display in SocketClient send mSocket =28 , date == W/SocketClient( 937): jscese display in SocketClient send mSocket =28 , date == I/bt_vendor( 2281): *********usb vendor open: opening /dev/bt_usb0 I/ ( 2281): BTE_InitTraceLevels -- TRC_HCI I/ ( 2281): BTE_InitTraceLevels -- TRC_L2CAP I/ ( 2281): BTE_InitTraceLevels -- TRC_RFCOMM I/ ( 2281): BTE_InitTraceLevels -- TRC_AVDT I/ ( 2281): BTE_InitTraceLevels -- TRC_AVRC I/ ( 2281): BTE_InitTraceLevels -- TRC_A2D I/ ( 2281): BTE_InitTraceLevels -- TRC_BNEP I/ ( 2281): BTE_InitTraceLevels -- TRC_BTM I/ ( 2281): BTE_InitTraceLevels -- TRC_PAN I/ ( 2281): BTE_InitTraceLevels -- TRC_SDP I/ ( 2281): BTE_InitTraceLevels -- TRC_GATT I/ ( 2281): BTE_InitTraceLevels -- TRC_SMP I/ ( 2281): BTE_InitTraceLevels -- TRC_BTAPP I/ ( 2281): BTE_InitTraceLevels -- TRC_BTIF E/bt-btif ( 2281): ################################## E/bt-btif ( 2281): bta_dm_co_ble_load_local_keys: TBD Load local keys if any are persisted E/bt-btif ( 2281): ################################## E/bt-btm ( 2281): BTM_SecRegister:p_cb_info->p_le_callback == 0x5f72e6ed E/bt-btm ( 2281): BTM_SecRegister: btm_cb.api.p_le_callback = 0x5f72e6ed E/bt-btif ( 2281): Calling BTA_HhEnable E/bt-btif ( 2281): lehid_enable E/bt-btif ( 2281): ## btif_config_get assert section && *section && key && *key && name && *name && bytes && type failed at line:182 ## E/bt-btif ( 2281): ## btif_config_get assert section && *section && key && *key && name && *name && bytes && type failed at line:182 ## E/bt-btif ( 2281): btif_storage_get_adapter_property service_mask:0x140040 I/BluetoothAdapterProperties( 2281): adapterPropertyChangedCallback with type:2 len:6 I/BluetoothAdapterProperties( 2281): adapterPropertyChangedCallback with type:1 len:16 W/bt-smp ( 2281): Key(LSB ~ MSB) = 2f 15 17 1d 64 e9 09 88 e1 5a cc d6 89 06 1c 8f W/bt-smp ( 2281): Plain text(LSB ~ MSB) = 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 W/bt-smp ( 2281): Encrypted text(LSB ~ MSB) = da f7 3d 81 37 58 7e 20 c2 e6 c6 45 cf 10 45 c7 W/bt-smp ( 2281): Key(LSB ~ MSB) = 2f 15 17 1d 64 e9 09 88 e1 5a cc d6 89 06 1c 8f W/bt-smp ( 2281): Plain text(LSB ~ MSB) = 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 W/bt-smp ( 2281): Encrypted text(LSB ~ MSB) = d3 67 6a 77 1a 6d 44 e8 4d b2 77 67 d2 58 9d 34 I/BluetoothAdapterProperties( 2281): adapterPropertyChangedCallback with type:7 len:4 D/BluetoothManagerService( 1646): Bluetooth Adapter name changed to Bluedroid TV 1.0 D/BluetoothManagerService( 1646): Stored Bluetooth name: Bluedroid TV 1.0 I/BluetoothAdapterProperties( 2281): adapterPropertyChangedCallback with type:9 len:4 I/BluetoothAdapterProperties( 2281): adapterPropertyChangedCallback with type:8 len:6 I/BluetoothAdapterProperties( 2281): adapterPropertyChangedCallback with type:3 len:48 E/BluetoothRemoteDevices( 2281): devicePropertyChangedCallback: bdDevice: F8:A4:5F:A0:64:CD, value is empty for type: 11 E/bt-btif ( 2281): ## btif_config_get assert section && *section && key && *key && name && *name && bytes && type failed at line:182 ## I/bte_conf( 2281): Attempt to load did conf from /etc/bluetooth/bt_did.conf D/ ( 2281): bta_pan_co_init I/bt-pan ( 2281): PAN_SetRole() called with role 0x5 I/bt-pan ( 2281): PAN role set to: 5 I/bte_conf( 2281): [1] primary_record=1 vendor_id=0x000F vendor_id_source=0x0001 product_id=0x1200 version=0x1436 I/bte_conf( 2281): Attempt to load did conf from /etc/bluetooth/bt_did.conf I/bte_conf( 2281): Attempt to load did conf from /etc/bluetooth/bt_did.conf D/BluetoothAdapterProperties( 2281): ScanMode = 20 D/BluetoothAdapterProperties( 2281): State = 11 D/BluetoothAdapterService( 2281): Broadcasting updateAdapterState() to 1 receivers. D/BluetoothManagerService( 1646): Message: 60 D/BluetoothManagerService( 1646): MESSAGE_BLUETOOTH_STATE_CHANGE: prevState = 11, newState=12 D/BluetoothManagerService( 1646): Broadcasting onBluetoothStateChange(true) to 8 receivers. D/BluetoothHeadset( 1849): onBluetoothStateChange: up=true D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: com.android.bluetooth.btservice.AdapterProperties@42309228 D/BluetoothAdapterService(1110478456)( 2281): Get Bonded Devices being called E/bt-btif ( 2281): ## btif_config_get assert section && *section && key && *key && name && *name && bytes && type failed at line:182 ## W/bt-btif ( 2281): btif_dm_cback : unhandled event (20) D/BluetoothPanServiceJni( 2281): control_state_callback(L61): state:0, local_role:0, ifname:bt-pan I/BluetoothAdapterProperties( 2281): adapterPropertyChangedCallback with type:7 len:4 D/HeadsetService( 2281): onBind D/BluetoothA2dp( 1982): onBluetoothStateChange: up=true D/BluetoothHeadset( 1849): Proxy object connected D/BluetoothAdapterService(1110478456)( 2281): Get Bonded Devices being called W/ApplicationContext( 1982): Calling a method in the system process without a qualified user: android.app.ContextImpl.bindService:1406 android.content.ContextWrapper.bindService:473 android.bluetooth.BluetoothA2dp$1.onBluetoothStateChange:131 I/BluetoothAdapterProperties( 2281): adapterPropertyChangedCallback with type:9 len:4 E/bt_usb ( 2281): vendor lib postload completed D/A2dpService( 2281): onBind D/BluetoothInputDevice( 1982): onBluetoothStateChange: up=true W/ApplicationContext( 1982): Calling a method in the system process without a qualified user: android.app.ContextImpl.bindService:1406 android.content.ContextWrapper.bindService:473 android.bluetooth.BluetoothInputDevice$1.onBluetoothStateChange:209 D/HidService( 2281): onBind D/BluetoothHeadset( 1849): onBluetoothStateChange: up=true D/BluetoothPan( 1982): onBluetoothStateChange(on) call bindService D/BluetoothHeadset( 1849): Proxy object connected W/ApplicationContext( 1982): Calling a method in the system process without a qualified user: android.app.ContextImpl.bindService:1406 android.content.ContextWrapper.bindService:473 android.bluetooth.BluetoothPan$1.onBluetoothStateChange:173 D/PanService( 2281): onBind D/BluetoothPan( 1982): BluetoothPan(), bindService called D/BluetoothHeadset( 1646): onBluetoothStateChange: up=true D/BluetoothHeadset( 1646): Proxy object connected D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: com.android.bluetooth.btservice.AdapterProperties@42309228 W/ApplicationContext( 1646): Calling a method in the system process without a qualified user: android.app.ContextImpl.bindService:1406 android.bluetooth.BluetoothHeadset$1.onBluetoothStateChange:244 com.android.server.BluetoothManagerService.sendBluetoothStateCallback:486 D/BluetoothHeadset( 1982): onBluetoothStateChange: up=true D/BluetoothA2dp( 1646): onBluetoothStateChange: up=true W/ApplicationContext( 1982): Calling a method in the system process without a qualified user: android.app.ContextImpl.bindService:1406 android.content.ContextWrapper.bindService:473 android.bluetooth.BluetoothHeadset$1.onBluetoothStateChange:244 D/BluetoothA2dp( 1646): Proxy object connected D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: com.android.bluetooth.btservice.AdapterProperties@42309228 W/ApplicationContext( 1646): Calling a method in the system process without a qualified user: android.app.ContextImpl.bindService:1406 android.bluetooth.BluetoothA2dp$1.onBluetoothStateChange:131 com.android.server.BluetoothManagerService.sendBluetoothStateCallback:486 D/BluetoothManagerService( 1646): Bluetooth State Change Intent: 11 -> 12 W/bt-btif ( 2281): btif_dm_cback : unhandled event (21) D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: com.android.bluetooth.btservice.AdapterProperties@42309228 D/BluetoothAdapterService(1110478456)( 2281): Get Bonded Devices being called D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: com.android.bluetooth.btservice.AdapterProperties@42309228 D/BluetoothManagerService( 1646): checkIfCallerIsForegroundUser: valid=true callingUser=0 foregroundUser=0 W/BluetoothAdapter( 2281): getBluetoothService() called with no BluetoothManagerCallback E/BluetoothServiceJni( 2281): SOCK FLAG = 1 *********************** V/BluetoothEventManager( 1982): Received android.bluetooth.device.action.NAME_CHANGED V/BluetoothEventManager( 1982): Received android.bluetooth.device.action.CLASS_CHANGED V/BluetoothEventManager( 1982): Received android.bluetooth.device.action.UUID D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: com.android.bluetooth.btservice.AdapterProperties@42309228 D/BluetoothA2dp( 1982): Proxy object connected D/BluetoothInputDevice( 1982): Proxy object connected D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: com.android.bluetooth.btservice.AdapterProperties@42309228 D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: com.android.bluetooth.btservice.AdapterProperties@42309228 D/BluetoothPan( 1982): BluetoothPAN Proxy object connected D/BluetoothHeadset( 1982): Proxy object connected D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: com.android.bluetooth.btservice.AdapterProperties@42309228 V/BluetoothEventManager( 1982): Received android.bluetooth.adapter.action.STATE_CHANGED D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: com.android.bluetooth.btservice.AdapterProperties@42309228 D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: com.android.bluetooth.btservice.AdapterProperties@42309228 D/BluetoothAdapterService(1110478456)( 2281): Get Bonded Devices being called D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: com.android.bluetooth.btservice.AdapterProperties@42309228 D/BluetoothAdapterService(1110478456)( 2281): getState(): mAdapterProperties: com.android.bluetooth.btservice.AdapterProperties@42309228 D/BluetoothAdapter( 1982): enable(): BT is already enabled..! W/ApplicationContext( 1982): Calling a method in the system process without a qualified user: android.app.ContextImpl.startService:1352 android.content.ContextWrapper.startService:450 android.content.ContextWrapper.startService:450 D/DockEventReceiver( 1982): finishStartingService: stopping service E/BtOppService( 2281): insertShare found null URI at cursor! D/BluetoothManagerService( 1646): checkIfCallerIsForegroundUser: valid=true callingUser=0 foregroundUser=0 W/BluetoothAdapter( 2281): getBluetoothService() called with no BluetoothManagerCallback E/BluetoothServiceJni( 2281): SOCK FLAG = 0 *********************** I/BtOppRfcommListener( 2281): Accept thread started. E/BtOppService( 2281): insertShare found null URI at cursor! E/BtOppService( 2281): insertShare found null URI at cursor! E/BtOppService( 2281): insertShare found null URI at cursor! E/BtOppService( 2281): insertShare found null URI at cursor! E/BtOppService( 2281): insertShare found null URI at cursor! E/BtOppService( 2281): insertShare found null URI at cursor! E/BtOppService( 2281): insertShare found null URI at cursor! E/BtOppService( 2281): insertShare found null URI at cursor! D/BtOppService( 2281): updateShare() called for ID 1 with null URI D/BtOppService( 2281): updateShare() called for ID 2 with null URI D/BtOppService( 2281): updateShare() called for ID 3 with null URI D/BtOppService( 2281): updateShare() called for ID 4 with null URI D/BtOppService( 2281): updateShare() called for ID 5 with null URI D/BtOppService( 2281): updateShare() called for ID 6 with null URI D/BtOppService( 2281): updateShare() called for ID 7 with null URI D/BtOppService( 2281): updateShare() called for ID 8 with null URI D/BtOppService( 2281): updateShare() called for ID 9 with null URI D/SizeAdaptiveLayout( 1756): com.android.internal.widget.SizeAdaptiveLayout{440a2600 V.E..... ......I. 0,0-0,0 #7f080063 app:id/adaptive}child view android.widget.FrameLayout{440a4458 G.E..... ......ID 0,0-0,0 #10203eb android:id/status_bar_latest_event_content} measured out of bounds at 95px clamped to 96px D/SizeAdaptiveLayout( 1756): com.android.internal.widget.SizeAdaptiveLayout{440a2600 V.E..... ......I. 0,0-0,0 #7f080063 app:id/adaptive}child view android.widget.FrameLayout{440a4458 G.E..... ......ID 0,0-0,0 #10203eb android:id/status_bar_latest_event_content} measured out of bounds at 95px clamped to 96px D/SizeAdaptiveLayout( 1756): com.android.internal.widget.SizeAdaptiveLayout{440a2600 V.E..... ......ID 0,0-669,96 #7f080063 app:id/adaptive}child view android.widget.FrameLayout{440a4458 V.E..... ......ID 0,0-669,96 #10203eb android:id/status_bar_latest_event_content} measured out of bounds at 95px clamped to 96px D/SizeAdaptiveLayout( 1756): com.android.internal.widget.SizeAdaptiveLayout{440a2600 V.E..... ......ID 0,0-669,96 #7f080063 app:id/adaptive}child view android.widget.FrameLayout{440a4458 V.E..... ......ID 0,0-669,96 #10203eb android:id/status_bar_latest_event_content} measured out of bounds at 95px clamped to 96px D/TvCommonClient( 1646): getCurrentInputSource, return int 34 D/TvCommonManager( 1764): getCurrentInputSource, return EnumInputSource E_INPUT_SOURCE_STORAGE D/dalvikvm( 2281): GC_CONCURRENT freed 340K, 19% free 2506K/3064K, paused 8ms+6ms, total 40ms W/BluetoothAdapterService( 2281): *************service already starting to cleanup... Ignoring cleanup request......... D/BluetoothAdapterService( 2281): REFCOUNT: FINALIZED. INSTANCE_COUNT= 1 D/BluetoothSocket( 2281): close() in, this: android.bluetooth.BluetoothSocket@42312c28, channel: 19, state: CLOSED D/BluetoothSocket( 2281): close() in, this: android.bluetooth.BluetoothSocket@422e5970, channel: 12, state: CLOSED
1.從UI操作開始,我們在設置界面中打開藍牙設備,這部分代碼在 Settings/bluetooth/BluetoothEnabler 類中。
/** * BluetoothEnabler is a helper to manage the Bluetooth on/off checkbox * preference. It turns on/off Bluetooth and ensures the summary of the * preference reflects the current state. */ public final class BluetoothEnabler implements CompoundButton.OnCheckedChangeListener { private final Context mContext; private final LocalBluetoothAdapter mLocalAdapter; .................................. public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { // Show toast message if Bluetooth is not allowed in airplane mode // if (isChecked // &&!WirelessSettings.isRadioAllowed(mContext, // Settings.System.RADIO_BLUETOOTH) // ) { // Toast.makeText(mContext, R.string.wifi_in_airplane_mode, // Toast.LENGTH_SHORT).show(); // // Reset switch to off // buttonView.setChecked(false); // } if (mLocalAdapter != null) { mLocalAdapter.setBluetoothEnabled(isChecked); } mSwitch.setEnabled(false); } ................................... }
從注釋中我們可以知道,這是一個藍牙開/關 的一個幫組類,類裡面實現了接口
CompoundButton.OnCheckedChangeListener 中的public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)方法。代碼中注釋掉的不管,那些是有關飛行模式下藍牙狀態的一個操作。我們看mLocalAdapter.setBluetoothEnabled(isChecked);是藍牙打開或者關閉的一個接口。我們查看mLocalAdapter類在哪裡???private final LocalBluetoothAdapter mLocalAdapter; 到了 Settings/bluetooth/LocalBluetoothAdapter 類中。
/** * LocalBluetoothAdapter provides an interface between the Settings app and the * functionality of the local {@link BluetoothAdapter}, specifically those * related to state transitions of the adapter itself. ** Connection and bonding state changes affecting specific devices are handled * by {@link CachedBluetoothDeviceManager}, {@link BluetoothEventManager}, and * {@link LocalBluetoothProfileManager}. */ public final class LocalBluetoothAdapter { private static final String TAG = "LocalBluetoothAdapter"; /** This class does not allow direct access to the BluetoothAdapter. */ private final BluetoothAdapter mAdapter; .................... public void setBluetoothEnabled(boolean enabled) { boolean success = enabled ? mAdapter.enable() : mAdapter.disable(); if (success) { setBluetoothStateInt(enabled ? BluetoothAdapter.STATE_TURNING_ON : BluetoothAdapter.STATE_TURNING_OFF); } else { if (Utils.V) { Log.v(TAG, "setBluetoothEnabled call, manager didn't return " + "success for enabled: " + enabled); } syncBluetoothState(); } } }
我們看注釋知道這個類在Settings app 和 Framworks 之間提供了一個接口去改變 藍牙開關狀態。關鍵代碼 看第 19行
boolean success = enabled ? mAdapter.enable() : mAdapter.disable(); 因為這裡的enable = true;也就是打開藍牙,所以我們走mAdapter.enable(),接著看下去,如果enable
成功,那麼 走 if 語句 (一般情況下能成功)我們看看 setBluetoothStateInt()的實現 在同一個文件目錄下
synchronized void setBluetoothStateInt(int state) { mState = state; if (state == BluetoothAdapter.STATE_ON) { // if mProfileManager hasn't been constructed yet, it will // get the adapter UUIDs in its constructor when it is. if (mProfileManager != null) { mProfileManager.setBluetoothStateOn(); } } }這裡關注 mProfileManager.setBluetoothStateOn(),設置藍牙的狀態開關,繼續跟蹤代碼
frameworks/base/core/java/android/bluetooth/LocalBluetoothProfileManager
下面,
final class LocalBluetoothProfileManager { ........... // Called from LocalBluetoothAdapter when state changes to ON void setBluetoothStateOn() { ParcelUuid[] uuids = mLocalAdapter.getUuids(); if (uuids != null) { updateLocalProfiles(uuids); } mEventManager.readPairedDevices(); } .............. }由上面的方法可以看出,當打開藍牙成功後,更新本地藍牙配置文件 和讀取 本地 藍牙設備列表顯示。
我們回到這裡,看boolean success = enabled ? mAdapter.enable() : mAdapter.disable(); 到底是怎麼打開藍牙開關的,接著看mAdapter對象的類 BluetoothAdapter會在哪裡呢??????????
我們看繼續查找 在 frameworks/base/core/java/android/bluetooth/BluetoothAdapter.java下,這會跳到了Frameworks中去了。(由原來的Settings APP 跳到 Framewoeks API中)
public final class BluetoothAdapter { ............ BluetoothAdapter(IBluetoothManager managerService) { if (managerService == null) { throw new IllegalArgumentException("bluetooth manager service is null"); } try { mService = managerService.registerAdapter(mManagerCallback); } catch (RemoteException e) {Log.e(TAG, "", e);} mManagerService = managerService; mServiceRecordHandler = null; } .............. public static synchronized BluetoothAdapter getDefaultAdapter() { if (sAdapter == null) { IBinder b = ServiceManager.getService(BLUETOOTH_MANAGER_SERVICE); if (b != null) { IBluetoothManager managerService = IBluetoothManager.Stub.asInterface(b); sAdapter = new BluetoothAdapter(managerService); } else { Log.e(TAG, "Bluetooth binder is null"); } } return sAdapter; } .................. public boolean enable() { if (isEnabled() == true){ if (DBG) Log.d(TAG, "enable(): BT is already enabled..!"); return true; } try { return mManagerService.enable(); } catch (RemoteException e) {Log.e(TAG, "", e);} return false; } .................. }
這裡我們看第 33 行 中的 enable() 方法中的第 39行 關鍵代碼 return mManagerService.enable(); mManagerService 對象是由 第 22 行的 IBluetoothManager 接口代碼實現的,一般這種遠程服務對應的類名就是 BluetoothManagerService 類,在路徑 frameworks/base/core/java/android/bluetooth/BluetoothManagerService 下面 ,我們進一步深入敵後看看 裡面什麼情況,
class BluetoothManagerService extends IBluetoothManager.Stub { ................... private void sendEnableMsg(boolean quietMode) { mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE, quietMode ? 1 : 0, 0)); } ............. private class BluetoothHandler extends Handler { public BluetoothHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { if (DBG) Log.d (TAG, "Message: " + msg.what); switch (msg.what) { .................... case MESSAGE_ENABLE: if (DBG) { Log.d(TAG, "MESSAGE_ENABLE: mBluetooth = " + mBluetooth); } mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE); mEnable = true; handleEnable(msg.arg1 == 1); break; ............. } private void handleEnable(boolean quietMode) { mQuietEnable = quietMode; Log.d(TAG, "handleEnable quietMode = " + quietMode); synchronized(mConnection) { if ((mBluetooth == null) && (!mBinding)) { //Start bind timeout and bind Log.d(TAG, "starting bind timeout and bind"); Message timeoutMsg=mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND); mHandler.sendMessageDelayed(timeoutMsg,TIMEOUT_BIND_MS); mConnection.setGetNameAddressOnly(false); Intent i = new Intent(IBluetooth.class.getName()); if (!mContext.bindService(i, mConnection,Context.BIND_AUTO_CREATE, UserHandle.USER_CURRENT)) { mHandler.removeMessages(MESSAGE_TIMEOUT_BIND); Log.e(TAG, "Fail to bind to: " + IBluetooth.class.getName()); } else { mBinding = true; } } else if (mBluetooth != null) { Log.d(TAG, "mBluetooth != null"); if (mConnection.isGetNameAddressOnly()) { // if GetNameAddressOnly is set, we can clear this flag, // so the service won't be unbind // after name and address are saved mConnection.setGetNameAddressOnly(false); //Register callback object try { mBluetooth.registerCallback(mBluetoothCallback); } catch (RemoteException re) { Log.e(TAG, "Unable to register BluetoothCallback",re); } //Inform BluetoothAdapter instances that service is up sendBluetoothServiceUpCallback(); } Log.d(TAG, "Try enable bluetooth"); //Enable bluetooth try { if (!mQuietEnable) { if(!mBluetooth.enable()) { Log.e(TAG,"IBluetooth.enable() returned false"); } } else { if(!mBluetooth.enableNoAutoConnect()) { Log.e(TAG,"IBluetooth.enableNoAutoConnect() returned false"); } } } catch (RemoteException e) { Log.e(TAG,"Unable to call enable()",e); } } } } ...................... public boolean enable() { if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) { Log.w(TAG,"enable(): not allowed for non-active and non system user"); return false; } mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); if (DBG) { Log.d(TAG,"enable(): mBluetooth =" + mBluetooth + " mBinding = " + mBinding); } synchronized(mReceiver) { mQuietEnableExternal = false; mEnableExternal = true; // waive WRITE_SECURE_SETTINGS permission check long callingIdentity = Binder.clearCallingIdentity(); persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH); Binder.restoreCallingIdentity(callingIdentity); sendEnableMsg(false); } return true; } ................... }
enable()方法中一直分析下來,
判斷是否是系統app 操作藍牙,檢查是否有操作藍牙的權限等,關鍵代碼 在第120行sendEnableMsg(false)這裡。看第 5行sendEnableMsg()方法
,繼續找 第25行 handler 中的 case MESSAGE_ENABLE:處理 第38行 handleEnable(msg.arg1 == 1); 最後跳到低 51行 綁定了一個遠程服務,這個遠程服務在哪裡????????是關鍵啊。。。。。。同一個目錄下
查找到了如下代碼
public void onServiceConnected(ComponentName className, IBinder service) { if (DBG) Log.d(TAG, "BluetoothServiceConnection: connected to AdapterService"); Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED); msg.obj = service; mHandler.sendMessage(msg); }
D/BluetoothManagerService( 1646): BluetoothServiceConnection: connected to AdapterService 在我們貼出來的打印裡面也可以找到這句話 ,在打印的第 13行就有。。。我們查找全局代碼 發現 AdapterService 類服務 在Packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService 下面。
注意了:我們從
Framworks 跳到 Bluetooth APP 中了 這個過程也正好符合我們前面貼出來的 Android4.2 Bluetooth 整體結構圖http://img.blog.csdn.net/20141114141134245?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmVpZHVjbGVhcl91cA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center
我們看看Bluetooth 裡面是怎麼實現的吧!!!代碼路徑 Packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService
看裡面的 enable(boolean)
實現
public class AdapterService extends Service { ...................... mAdapterStateMachine = AdapterState.make(this, mAdapterProperties); ................ public synchronized boolean enable(boolean quietMode) { enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); if (DBG)debugLog("Enable called with quiet mode status = " + mQuietmode); mQuietmode = quietMode; Message m = mAdapterStateMachine.obtainMessage(AdapterState.USER_TURN_ON); mAdapterStateMachine.sendMessage(m); return true; } ............... }
final class AdapterState extends StateMachine { .................... private class PendingCommandState extends State { @Override public boolean processMessage(Message msg) { boolean isTurningOn= isTurningOn(); boolean isTurningOff = isTurningOff(); switch (msg.what) { ........................... case STARTED: { if (DBG) Log.d(TAG,"CURRENT_STATE=PENDING, MESSAGE = STARTED, isTurningOn=" + isTurningOn + ", isTurningOff=" + isTurningOff); //Remove start timeout removeMessages(START_TIMEOUT); //Enable boolean ret = mAdapterService.enableNative(); if (!ret) { Log.e(TAG, "Error while turning Bluetooth On"); notifyAdapterStateChange(BluetoothAdapter.STATE_OFF); transitionTo(mOffState); } else { sendMessageDelayed(ENABLE_TIMEOUT, ENABLE_TIMEOUT_DELAY); } } break; ................. } return true; } } ...................... }
我們看第 27行代碼
//Enable
boolean ret = mAdapterService.enableNative(); 最終調用了 本地的 JNI 方法 來進行 enable 我們來到 Packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp 下面 看代碼如下:
static jboolean enableNative(JNIEnv* env, jobject obj) { ALOGV("%s:",__FUNCTION__); jboolean result = JNI_FALSE; if (!sBluetoothInterface) return result; int ret = sBluetoothInterface->enable(); result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; return result; }
當前文件路徑下 找到如下定義
static const bt_interface_t *sBluetoothInterface = NULL;那麼 bt_interface_t 結構體在哪裡呢??我找了好久也沒找到,因為這是依賴其他的庫 找到的 結構體,所有我找當前目錄下的 Android.mk 查看到裡面 編譯JNI的時候有依賴 一個庫
LOCAL_SHARED_LIBRARIES := \
libandroid_runtime \
libnativehelper \
libcutils \
libutils \
libhardware
就是 libhardware 庫了。自然找到 hardware/libhardware/include/hardware/bluetooth.h 有bluetooth.h 文件自然有 bluetooth.c 文件,我們查找全局代碼 找到了 bluetooth.c 在 external/bluedroid/btif/src/bluetooth.c 下面。看代碼如下:
static const bt_interface_t bluetoothInterface = { sizeof(bt_interface_t), init, enable, disable, cleanup, get_adapter_properties, get_adapter_property, set_adapter_property, get_remote_device_properties, get_remote_device_property, set_remote_device_property, get_remote_service_record, get_remote_services, start_discovery, cancel_discovery, create_bond, remove_bond, cancel_bond, pin_reply, ssp_reply, get_profile_interface, dut_mode_configure, dut_mode_send, enter_headless_mode, add_headless_mode_wakeup_device, delete_headless_mode_wakeup_device };
總結:借鑒了網上很多人的博客,寫的不是很詳細,繼續研究。
一:Android系統下JNI簡介 Android系統下的JNI的全稱是:Java Native Interface (JNI),JNI標准是java平台的
Android開發之給應用簽名打包什麼是簽名打包?在Android 系統中,所有安裝到系統的應用程序都必有一個數字證書,此數字證書用於標識應用程序的作者和在應用程序之間建
Android -- Camera2(Android5.0) Camera2 Camera2是Android5.0中的其中一個新的特性,新的API。與原來的
本文實例講述了Android中AsyncTask與handler用法。分享給大家供大家參考,具體如下:首先,我們得明確下一個概念,什麼是UI線程。顧名思義,ui線程就是管