BluetoothService類中定義的Native方法都在android_server_BluetoothServer.cpp裏創建jni調用java
1、開啓(BT Turn on Turn off) (藍牙的打開關閉由類BluetoothEnabler控制。)
1.由BluetoothEnabler控制界面操做,在其構造函數裏會先調用 LocalBluetoothManager.getInstance(context)。android
2.而後在LocalBluetoothManager類的getInstance函數裏會調用當前類下的init()函數,該init()函數中經過BluetoothAdapter.getDefaultAdapter()得到藍牙設備的句柄,若是當前沒有藍牙設備則返回null。 異步
3.初始化完畢會監聽checkbox的狀態,當觸發點擊checkbox會響應onPreferenceChange方法,其中將調用 LocalBluetoothManager.setBluetoothEnabled(enable)方法。函數
而LocalBluetoothManager.setBluetoothEnabled(enable)方法,會調用mAdapter.enable()方法,enable()方法又會調用 BluetoothService.enable()方法。其中,oop
(1)打開(關閉)操做成功後會有一個異步事件ACTION_STATE_CHANGED返回,異步事件由類BluetoothEventRedirector控制(接收廣播,進行處理)。在收到ACTION_STATE_CHANGED異步事件後,還須要作update本地設備profile的事情,讀取上次關閉前搜索到的藍牙設備。this
(1.1)update本地設備profile的事情:?spa
(1.2)讀取上次關閉前搜索到的藍牙設備:線程
經過LocalBluetoothManager.setBluetoothStateInt(int state)方法調到 CachedBluetoothDeviceManager.onBluetoothStateChanged方法來讀取上次關閉以前搜索到device. code
(2)來開啓EnableThread線程,進行打開操做,藍牙的打開關閉屬於異步操做。server
ps:在啓動藍牙的時候,要注意的地方是不能正常啓動藍牙的狀況,由於正常啓動的時候會返回BluetoothIntent.ENABLED_ACTION 這個Intent,當時當啓動出現異常的時候是沒有Intent返回的,android使用回調函數來解決這個問題。下面是在bluetoothdeviceservice.java 裏面enable((IBluetoothDeviceCallback callback) 的過程:(如下代碼屬於較低版本的android源碼,與較高版本源碼中已有所不一樣,只做爲參考...)
View Code public synchronized boolean enable(IBluetoothDeviceCallback callback) { checkPermissionBluetoothAdmin(); Log.d(TAG,"start enable! "); // Airplane mode can prevent Bluetooth radio from being turned on. if (mIsAirplaneSensitive && isAirplaneModeOn()) { return false; } if (mIsEnabled) { return false; } if (mEnableThread != null && mEnableThread.isAlive()) { return false; } // 主要的啓動過程是放在一個新起的線程裏面,可是無論能不能啓動 // 仍然返回了true mEnableThread = new EnableThread(callback); mEnableThread.start(); // return true; } private EnableThread mEnableThread; private class EnableThread extends Thread { private final IBluetoothDeviceCallback mEnableCallback; public EnableThread(IBluetoothDeviceCallback callback) { mEnableCallback = callback; } public void run() { boolean res = enableNative(); if (res) { mEventLoop.start(); } if (mEnableCallback != null) { try { // 經過回調函數來代表是否正常啓動藍牙設備 mEnableCallback.onEnableResult(res ? BluetoothDevice.RESULT_SUCCESS : BluetoothDevice.RESULT_FAILURE); } catch (RemoteException e) {} } if (res) { mIsEnabled = true; mIsDiscovering = false; Intent intent = new Intent(BluetoothIntent.ENABLED_ACTION); mContext.sendBroadcast(intent); } }else{ mIsEnabled = false; mIsDiscovering = false; } mEnableThread = null; } } // 這個回調函數將被做爲參數傳進bluetoothservice 裏面的enable(IBluetoothDeviceCallback callback) static class DeviceCallback extends IBluetoothDeviceCallback.Stub { Handler messageHandler; public void setHandler(Handler handler) { synchronized (this) { messageHandler = handler; } public void onEnableResult(int result) { switch(result) { // 啓動不成功的時候執行 case BluetoothDevice.RESULT_FAILURE: messageHandler.sendMessage(messageHandler.obtainMessage(EVENT_FAILED_BT_ENABLE,0)); break; } } // 配對完成時執行 public void onCreateBondingResult(String address, int result) { synchronized (this) { if (messageHandler != null) { if (result == BluetoothDevice.RESULT_FAILURE) { messageHandler.sendMessage(messageHandler.obtainMessage( HANDLE_PAIRING_FAILED, address)); } else { messageHandler.sendMessage(messageHandler.obtainMessage( HANDLE_PAIRING_PASSED, address)); } } } } }
涉及到的類:
BluetoothService(最主要的類,開啓具體命令的線程進行enable,disable等操做)
LocalBluetoothManager(本機藍牙設備管理,開啓關閉,搜索等等,初始化BluetoothAdapter)
BluetoothEnabler(界面的點擊和狀態文字的顯示)
BluetoothAdapter(framework封裝的類,提供本地藍牙設備的配置,包括開啓藍牙,搜索周圍藍牙設備,設置本地藍牙可見性;創建LocalBluetoothManager和BluetoothService的映射關係,主要是經過它調用BluetoothService的函數)
BluetoothEventRedirector(接收Bluetooth API 的廣播和回調,而且將Settings中的UI線程上的事件分派到正確的類)
2、可檢測性(Discoverable)
1.藍牙的discoverable mode由類BluetoothDiscoverableEnabler控制。點擊將觸發OnPreferenceChangeListener監聽事件,調用onPreferenceChange()方法,該方法中調用setEnabled(true),而setEnabled(true)方法將調用到BluetoothAdapter的setScanMode () 方法。
藍牙模式有兩種模式SCAN_MODE_CONNECTABLE_DISCOVERABLE(可鏈接可發現)和SCAN_MODE_CONNECTABLE(可鏈接但不可發現)
3、掃描
1.在BluetoothSetting裏觸發點擊,調用LocalBluetoothManager.startScanning(true)函數,經過BluetoothAdapter的startDiscovery調用到BluetoothService裏的startDiscovery來調用Native函數 startDiscoveryNative()。
startDiscovery()是個異步函數,會當即返回,經過註冊 ACTION_DISCOVERY_STARTED、ACTION_DISCOVERY_FINISHED、ACTION_FOUND,來肯定當前的狀態。
當藍牙由disable變成enable時會調用掃描,當距離上次掃描超過5分鐘的前提下,退出頁面,再進到頁面的時候也會啓動掃描。
在啓動scan的時候,還會判斷當前是否在播放音樂,若是在播放音樂,則不啓動掃描。
點擊查找設備後,會把設備列表裏沒有配對的設備清除掉,保留配對狀態的設備。
掃描的過程是一個很耗費資源的過程,在掃描過程,不會去嘗試進行新的鏈接,掃描時間默認是12秒,它是以一個系統服務的形式存在的,能夠調用cancelDiscovery()來取消掃描。
4、鏈接
1.1 在setting界面點擊鏈接,會調到CachedBluetoothDevice類的connect方法。
1.2 而connect方法會調用connectWithoutResettingTimer()方法。
1.3 而connectWithoutResettingTimer()方法會調用 connectInt方法。
在connectInt裏,根據不一樣的profile來得到profilemanger,而後調用 profilemanger.connect()函數 。此處的連接會涉及到的profile有A2DP AVRCP DUN HSP HFP 等。
同理若是配對或者解除配對,也會調到CachedBluetoothDevice類的pair()方法和unpair()。
以A2DP爲例,在connectInt裏,根據不一樣的profile來得到profilemanger,而後調用 profilemanger.connect()函數,在這個函數裏調用了BluetoothA2dpService的connectSink()函數,最後調到Native方法
connectSinkNative()去創建鏈接。
涉及到的一些類:
CachedBluetoothDevice(搜索到的設備)
BluetoothDevice(設備類)
LocalBluetoothProfileManager(是一個抽象類,各類ProfileManger,實例化各類Profile的service)
SettingsBtStatus(藍牙的狀態類)
BluetoothA2dp(爲LocalBluetoothProfileManager和BluetoothA2dpService創建映射關係)
BluetoothA2dpService(最終的服務類,由它調用鏈接、斷開等Native函數,和底層通訊)
其餘文件做用(接收與發送相似)
1.BluetoothOppReceiver.java 這個類裏描述的是藍牙傳輸文件過程當中接收到的廣播事件。
2.BluetoothOppTransfer.java 管理文件傳輸的類
3. BluetoothOppService.java 藍牙傳輸文件後臺的類
4. BluetoothOppObexClientSession.java 具體實現文件傳輸的類
1
、開啓
步驟
1
:首先從BTSettings開始,執行onCreate方法。由於是初始化狀態,因此
if
(action.equal(BTDevicePicker.ACTION_LAUNCH))不知足,故執行
else
語句。
步驟
2
:初始化mEnable對象,調用BTEnable構造函數。經過LocalBTManager.getInstance調用init方法,再經過init方法調用BTAdapter.getDefaultAdapter()得到適配器句柄。
步驟
3
:各類初始化完畢後,執行BTSettings中的onResume方法,調用BTEnabler.resume方法,該resume方法爲組合框設置監聽事件。
步驟
4
:當藍牙開啓時,該組合框被選中,將響應監聽事件,執行BTEnabler.onPreferenceChange方法。該方法中會調用LocalBTManager.setBTEnabled方法。而setBTEnabled方法會調用BTAdapter.enable()方法,繼而調用BTService.enable()方法,繼而調用BTService.enable(
true
)方法。在該方法中,
(
1
)當enable(
true
)方法返回
true
時,在setBTEnabled方法中會調用BTService中的setBTStateInt方法,繼而廣播出去,由BTEventRedirector類接收。
(
2
)開啓新的線程,主要的啓動過程是放在這個新啓動的線程裏面。
(
3
)開啓藍牙後,會調用CachedBTDeviceManager.onBTStateChanged方法來讀取上次關閉前搜索到的藍牙設備。
2
.可檢測的
點擊「可檢測性」組合框,將觸發BTDiscoverableEnabler.onPreferenceChange方法,而後調用同個類中的setEnabled方法,來調用BTAdapter.setScanMode方法(其中傳遞SCAN_MODE_CONNECTABLE_DISCOVERABLE參數),繼而會調用BTService.setScanMode方法,在該方法中,會經過setDiscoverableTimeout方法設置檢測時間。
3
.掃描
BTSettings的onResume方法繼續往下運行,將調用LocalBTManager.startScanning方法,該方法會調用BTAdapter.startDiscovery方法,繼而調用BTService.startDiscovery方法,再調用startDIscoveryNative方法。
4
.鏈接
步驟
1
:在setting界面點擊鏈接,會調到CachedBluetoothDevice類的connect方法。
步驟
2
:而connect方法會調用connectWithoutResettingTimer()方法。
步驟
3
:而connectWithoutResettingTimer()方法會調用 connectInt方法。
步驟
4
:在connectInt裏,根據不一樣的profile來得到profilemanger,而後調用 profilemanger.connect()函數 。此處的連接會涉及到的profile有A2DP AVRCP DUN HSP HFP 等。
同理若是配對或者解除配對,也會調到CachedBluetoothDevice類的pair()方法和unpair()。
|