Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 4.2 Bluetooth 分析總結(二) 藍牙enable 的整個過程

Android 4.2 Bluetooth 分析總結(二) 藍牙enable 的整個過程

編輯:關於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;
            }
        	
        	...............
        	
        	
        }

這裡我們看重點代碼 mAdapterStateMachine.sendMessage(m); 跳到Packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterState 下面, 尼媽。。。。。。。狀態機 ,什麼狀態機啊。。。不懂啊,,看這裡吧,了解一下也好android StateMachine 狀態機

 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;
}


看到沒??? 調用 int ret = sBluetoothInterface->enable(); 來驅動底層 打開 藍牙開關。那麼我們找找 sBluetoothInterface是什麼吧???

當前文件路徑下 找到如下定義

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
};

在這個結構體裡邊 可以看到藍牙的所有抽象層 HAL 的操作。包括藍牙初始化,打開藍牙,關閉藍牙,等等。到這裡Bluetooth enable 基本上結束了,接下來實現 bt_interface_t bluetoothInterface 接口就是各個藍牙生產商 自己實現了,一般代生產商的代碼會放在 vendor 目錄下邊。


總結:借鑒了網上很多人的博客,寫的不是很詳細,繼續研究。



  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved