需求:手机端音乐暂停和播放状态从服务端告诉客户端、设备端实现暂停、播放、上一首、下一首等功能
代码路径:

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

一、蓝牙音乐播放状态

1、在AvrcpControllerService.java文件中onPlayStatusChanged()方法就是音乐播放状态改变,该方法是由JNI层中com_android_bluetooth_avrcp_controller.cpp中调用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消息就是处理播放状态的,然后通过广播方式把该状态发送出去

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;

二、蓝牙音乐中怎么获取音乐信息

1、在AvrcpControllerService.java文件中onTrackChanged()方法中是获取JNI层上报的音乐信息,该方法是由JNI层中com_android_bluetooth_avrcp_controller.cpp中调用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);    //该方法就是把蓝牙音乐的信息传递给java层    getElementAttrRsp(attributes,attribVals,numAttributes);    if (stateMachine != null) {        stateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_TRACK_CHANGED,                TrackInfo.getMetadata(attributes, attribVals));    }}

2、在AvrcpControllerService.java文件中getElementAttrRsp()中,然后通过该方法中通过广播告诉出去

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

三、设备蓝牙音乐中上一首、下一首、暂停功能控制手机端

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层来实现功能

case MESSAGE_SEND_PASS_THROUGH_CMD:    BluetoothDevice device = (BluetoothDevice) msg.obj;    mService.sendPassThroughCommandNative(Utils.getByteAddress(device), msg.arg1,                    msg.arg2);    return true;

到此这篇关于Android 控制车载蓝牙播放音乐详解流程的文章就介绍到这了,更多相关Android 控制车载蓝牙 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

更多相关文章

  1. Android(安卓)同时播放缩放动画和位移动画 时, 位移的路径会发生
  2. 使用BleLib的轻松搞定Android低功耗蓝牙Ble 4.0开发详解
  3. Android低功耗蓝牙应用开发获取的服务UUID
  4. android:自己实现能播放网络视频url的播放器
  5. android 闹钟提醒并且在锁屏下弹出Dialog对话框并播放铃声和震动
  6. Android(安卓)bluetooth介绍(三): 蓝牙扫描(scan)设备分析
  7. 从头学Android之多媒体--使用MediaPlayer播放音频
  8. Android(安卓)4.2 BT系统之蓝牙关闭过程全跟踪
  9. android之动画(一)通过AnimationDrawable控制逐帧动画

随机推荐

  1. android 图形系统
  2. Android入门教程五十五之DrawerLayout(官
  3. android 显示pdf文件内容
  4. HTML---Android与js交互实例
  5. 索引:Android Studio安装及工程项目目录简
  6. Android学习笔记之开发必备
  7. FFMpeg For Android之Ubuntu下编译
  8. Android设计原则/Android Design Princip
  9. Cocos2d-x移植android加入震动效果
  10. Android自用-----Intent 介绍