Android 控制车载蓝牙播放音乐详解流程

 更新时间:2021年10月29日 17:13:52   作者:路过独木桥!!  
本篇文章介绍了手机端音乐暂停和播放状态,从服务端告诉客户端、设备端实现暂停、播放、上一首、下一首等功能的实现,通读本篇对大家的学习或工作具有一定的价值,需要的朋友可以参考下

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

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 控制车载蓝牙 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Android实现登录注册界面框架

    Android实现登录注册界面框架

    这篇文章主要介绍了Android实现登录注册界面的框架,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-09-09
  • 优化和瘦身Android APK的六个小技巧

    优化和瘦身Android APK的六个小技巧

    Android应用的大小对用户体验和应用性能至关重要,大型APK文件会增加应用的安装时间,启动时间和页面加载时间,降低了用户体验,因此,APK瘦身是Android开发中的重要任务,在本文中,我们将分享6个小技巧,帮助你优化和瘦身Android应用,需要的朋友可以参考下
    2023-11-11
  • Android App开发中将View或Drawable转为Bitmap的方法

    Android App开发中将View或Drawable转为Bitmap的方法

    这篇文章主要介绍了Android App开发中将View或Drawable转为Bitmap的方法,其中View转换时作者特别提到了getDrawingCache=null问题的解决方法,需要的朋友可以参考下
    2016-03-03
  • Android自定义Dialog框样式

    Android自定义Dialog框样式

    这篇文章主要为大家详细介绍了Android自定义Dialog框样式,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-06-06
  • Android自动获取短信验证码功能

    Android自动获取短信验证码功能

    这篇文章主要介绍了Android自动获取短信验证码功能,通过自定义短信监听器用于自动填充验证码功能,具体实现代码大家可以参考下本文
    2017-04-04
  • Android MPAndroidChart开源库图表之折线图的实例代码

    Android MPAndroidChart开源库图表之折线图的实例代码

    这篇文章主要介绍了Android MPAndroidChart开源库图表之折线图的实例代码,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • Android实现短信验证码自动填写

    Android实现短信验证码自动填写

    这篇文章主要为大家详细介绍了Android短信验证码自动填写功能的实现过程,感兴趣的小伙伴们可以参考一下
    2016-08-08
  • Android SpringAnimation弹性动画解析

    Android SpringAnimation弹性动画解析

    这篇文章主要为大家详细介绍了Android SpringAnimation弹性动画,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-03-03
  • Android自定义View app更新动画详解

    Android自定义View app更新动画详解

    这篇文章给大家分享了Android自定义View app更新动画的相关代码以及知识点内容,有兴趣的朋友参考学习下。
    2018-07-07
  • Android开发中Activity之间切换出现短暂黑屏的解决方法

    Android开发中Activity之间切换出现短暂黑屏的解决方法

    这篇文章主要介绍了Android开发中Activity之间切换出现短暂黑屏的解决方法,较为详细的分析了Android中Activity之间切换出现短暂黑屏的原因与解决方法,需要的朋友可以参考下
    2016-02-02

最新评论