Android 控制車載藍(lán)牙播放音樂詳解流程
需求:手機(jī)端音樂暫停和播放狀態(tài)從服務(wù)端告訴客戶端、設(shè)備端實(shí)現(xiàn)暫停、播放、上一首、下一首等功能
代碼路徑:
packages/apps/Bluetooth/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java
packages/apps/Bluetooth/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java
packages/apps/Bluetooth/src/com/android/bluetooth/a2dpsink/A2dpSinkService.java
packages/apps/Bluetooth/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java
packages/apps/Bluetooth/jni/com_android_bluetooth_avrcp_controller.cpp
一、藍(lán)牙音樂播放狀態(tài)
1、在AvrcpControllerService.java文件中onPlayStatusChanged()方法就是音樂播放狀態(tài)改變,該方法是由JNI層中com_android_bluetooth_avrcp_controller.cpp中調(diào)用java層的
private synchronized void onPlayStatusChanged(byte[] address, byte playStatus) { if (DBG) { Log.d(TAG, "onPlayStatusChanged " + playStatus); } int playbackState = PlaybackState.STATE_NONE; switch (playStatus) { case JNI_PLAY_STATUS_STOPPED: playbackState = PlaybackState.STATE_STOPPED; break; case JNI_PLAY_STATUS_PLAYING: playbackState = PlaybackState.STATE_PLAYING; break; case JNI_PLAY_STATUS_PAUSED: playbackState = PlaybackState.STATE_PAUSED; break; case JNI_PLAY_STATUS_FWD_SEEK: playbackState = PlaybackState.STATE_FAST_FORWARDING; break; case JNI_PLAY_STATUS_REV_SEEK: playbackState = PlaybackState.STATE_REWINDING; break; default: playbackState = PlaybackState.STATE_NONE; } BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address); AvrcpControllerStateMachine stateMachine = getStateMachine(device); if (stateMachine != null) { stateMachine.sendMessage( AvrcpControllerStateMachine.MESSAGE_PROCESS_PLAY_STATUS_CHANGED, playbackState); } }
2、在AvrcpControllerStateMachine.java文件中Connected類中
MESSAGE_PROCESS_PLAY_STATUS_CHANGED消息就是處理播放狀態(tài)的,然后通過廣播方式把該狀態(tài)發(fā)送出去
case MESSAGE_PROCESS_PLAY_STATUS_CHANGED: if (SystemProperties.get("persist.ivi.feature", "0").equals("1")) { A2dpSinkService a2dpSinkService = A2dpSinkService.getA2dpSinkService(); Log.d(TAG, "the state: " + msg.arg1); if (a2dpSinkService != null && msg.arg1 != preAudioStatus) { preAudioStatus = msg.arg1; Log.d(TAG, "preAudioStatus: " + msg.arg1); if (msg.arg1 == PlaybackState.STATE_PLAYING) { //播放 a2dpSinkService.informPlayState(mDevice, true); } else if (msg.arg1 == PlaybackState.STATE_PAUSED) { //暫停 a2dpSinkService.informPlayState(mDevice, false); } } } Intent intent = new Intent("zqc.bluetooth.PLAY_STATUS_CHANGED"); intent.putExtra("zqc.bluetooth.PLAYBACK", msg.arg1); mService.sendBroadcast(intent); mAddressedPlayer.setPlayStatus(msg.arg1); BluetoothMediaBrowserService.notifyChanged(mAddressedPlayer.getPlaybackState()); if (mAddressedPlayer.getPlaybackState().getState() == PlaybackState.STATE_PLAYING && A2dpSinkService.getFocusState() == AudioManager.AUDIOFOCUS_NONE && !shouldRequestFocus()) { sendMessage(MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE); } return true;
二、藍(lán)牙音樂中怎么獲取音樂信息
1、在AvrcpControllerService.java文件中onTrackChanged()方法中是獲取JNI層上報的音樂信息,該方法是由JNI層中com_android_bluetooth_avrcp_controller.cpp中調(diào)用java層的
private synchronized void onTrackChanged(byte[] address, byte numAttributes, int[] attributes, String[] attribVals) { if (DBG) { Log.d(TAG, "onTrackChanged"); } BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address); AvrcpControllerStateMachine stateMachine = getStateMachine(device); //該方法就是把藍(lán)牙音樂的信息傳遞給java層 getElementAttrRsp(attributes,attribVals,numAttributes); if (stateMachine != null) { stateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_TRACK_CHANGED, TrackInfo.getMetadata(attributes, attribVals)); } }
2、在AvrcpControllerService.java文件中g(shù)etElementAttrRsp()中,然后通過該方法中通過廣播告訴出去
private void getElementAttrRsp(int[] attr_id,String[] textArray,byte num_attr){ String artist = null; String trackTitle = null; String album = null; for (int i = 0; i < num_attr; i++){ switch (attr_id[i]) { case JNI_MEDIA_ATTR_ID_TITLE: trackTitle = textArray[i]; if (trackTitle == null){ trackTitle = "Unknown"; } break; case JNI_MEDIA_ATTR_ID_ARTIST: artist = textArray[i]; if (artist == null){ artist = "Unknown"; } break; case JNI_MEDIA_ATTR_ID_ALBUM: album = textArray[i]; if (album == null){ album = "Unknown"; } break; } } Intent intent = new Intent("com.android.getelementattrrsp"); intent.putExtra("artist", artist); intent.putExtra("trackTitle",trackTitle); intent.putExtra("album",album); Log.d(TAG,"getElementAttrRsp,artist: " + artist + ",trackTitle: " + trackTitle + ",album: " + album); intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); sendBroadcast(intent, ProfileService.BLUETOOTH_PERM); }
三、設(shè)備藍(lán)牙音樂中上一首、下一首、暫停功能控制手機(jī)端
1、在AvrcpControllerService.java文件中sendPassThroughCmd()方法來控制暫停、播放、上一首、下一首等功能
public synchronized void sendPassThroughCmd(BluetoothDevice device, int keyCode, int keyState) { Log.v(TAG, "sendPassThroughCmd keyCode: " + keyCode + " keyState: " + keyState); if (device == null) { Log.e(TAG, "sendPassThroughCmd Device is null"); return; } AvrcpControllerStateMachine stateMachine = getStateMachine(device); if (stateMachine != null) { stateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_SEND_PASS_THROUGH_CMD, keyCode, keyState, device); } }
2、在AvrcpControllerStateMachine.java文件中MESSAGE_SEND_PASS_THROUGH_CMD變量中通過JNI層來實(shí)現(xiàn)功能
case MESSAGE_SEND_PASS_THROUGH_CMD: BluetoothDevice device = (BluetoothDevice) msg.obj; mService.sendPassThroughCommandNative(Utils.getByteAddress(device), msg.arg1, msg.arg2); return true;
到此這篇關(guān)于Android 控制車載藍(lán)牙播放音樂詳解流程的文章就介紹到這了,更多相關(guān)Android 控制車載藍(lán)牙 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
android TextView屬性的詳細(xì)介紹 分享
android TextView屬性的詳細(xì)介紹 分享,需要的朋友可以參考一下2013-05-05Android中的Service相關(guān)全面總結(jié)
接下來將介紹Service的種類;Service與Thread的區(qū)別;Service的生命周期;startService 啟動服務(wù);Local與Remote服務(wù)綁定等等,感興趣的朋友可以了解下2013-01-01詳細(xì)介紹Android-Room數(shù)據(jù)庫的使用
這篇文章主要介紹了詳細(xì)介紹Android-Room數(shù)據(jù)庫的使用,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-03-03android viewpager實(shí)現(xiàn)豎直滑動效果
這篇文章主要為大家詳細(xì)介紹了android viewpager實(shí)現(xiàn)豎直滑動效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-07-07Android中實(shí)現(xiàn)詞組高亮TextView方法示例
高亮顯示大家應(yīng)該都不陌生,在開發(fā)中經(jīng)常會遇到這個需求,所以下面這篇文章主要給大家介紹了關(guān)于Android中實(shí)現(xiàn)詞組高亮TextView的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧。2017-10-10android實(shí)現(xiàn)將位置信息寫入JPEG圖片文件
下面小編就為大家?guī)硪黄猘ndroid實(shí)現(xiàn)將位置信息寫入JPEG圖片文件。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-03-03