BluetoothA2DP sink

Android 8.1开启Bluetooth A2DP sink功能
**

Android O源码已经支持A2DP sink,只需要开启就可以了

一个是BTA_AV_SINK_INCLUDED设为TRUE,BTA_AV_SINK_INCLUDED在\system\bt\include的bt_target.h
另外一个是bluetooth app这边的profile_supported_a2dp_sink需设为true开启这个profile

但是实际上光开启这两个值A2DP sink是不能工作的,我用的是RK3399,不知道其他平台是不是OK的

调试发现这个btif_av_init只会执行一次,也就是加了source之后sink是加不进来了,因为这个if判断执行过一次就不会再成立了,这个设计的初衷不知道是不是source和sink只能有一个,因为我这边发现打开sink后,source是有问题的,看起来是不能使用了,目前是暂时把这个判断拿掉了,因为我们source端没什么要求应该是用不上,但是sink端是一定需要的

/*******************************************************************************
 *
 * Function         btif_av_init
 *
 * Description      Initializes btif AV if not already done
 *
 * Returns          bt_status_t
 *
 ******************************************************************************/

bt_status_t btif_av_init(int service_id) {
  if (btif_av_cb.sm_handle == NULL) {
    alarm_free(av_open_on_rc_timer);
    av_open_on_rc_timer = alarm_new("btif_av.av_open_on_rc_timer");
    switch (service_id) {
      case BTA_A2DP_SOURCE_SERVICE_ID:
        if (!btif_a2dp_source_startup())
          return BT_STATUS_FAIL;  // Already running
        break;
      case BTA_A2DP_SINK_SERVICE_ID:
        if (!btif_a2dp_sink_startup())
          return BT_STATUS_FAIL;  // Already running
        break;
      default:
        break;
    }
    btif_enable_service(service_id);

    /* Also initialize the AV state machine */
    btif_av_cb.sm_handle = btif_sm_init(
        (const btif_sm_handler_t*)btif_av_state_handlers, BTIF_AV_STATE_IDLE);
  }

  return BT_STATUS_SUCCESS;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
修改完这个后A2DP sink profile是有了,另外的手机也可以连上,数据也有传到我们的板子上,就是没有声音,调试发现就是播放没有执行
播放函数在pachages\appsBluetooth\src\com\android\bluetooth\a2dpsink\A2dpSinkStreamHandler.java

@Override
    public void handleMessage(Message message) {
        if (DBG) {
            Log.d(TAG, " process message: " + message.what);
            Log.d(TAG, " audioFocus =  " + mAudioFocus);
        }
        switch (message.what) {
            case SRC_STR_START:
                // Audio stream has started, stop it if we don't have focus.
                mStreamAvailable = true;
                +++++
                /*if (mAudioFocus == AudioManager.AUDIOFOCUS_NONE) {
                    requestAudioFocus();
                }*/
                +++++
                if (mAudioFocus == AudioManager.AUDIOFOCUS_NONE) {
                    sendAvrcpPause();
                } else {
                    startAvrcpUpdates();
                }
                break;

            case SRC_STR_STOP:
                // Audio stream has stopped, maintain focus but stop avrcp updates.
                mStreamAvailable = false;
                stopAvrcpUpdates();
                break;

            case SNK_PLAY:
                // Local play command, gain focus and start avrcp updates.
                if (mAudioFocus == AudioManager.AUDIOFOCUS_NONE) {
                    requestAudioFocus();
                }
                startAvrcpUpdates();
                break;

            case SNK_PAUSE:
                // Local pause command, maintain focus but stop avrcp updates.
                stopAvrcpUpdates();
                break;

            case SRC_PLAY:
                // Remote play command, if we have audio focus update avrcp, otherwise send pause.
                if (mAudioFocus == AudioManager.AUDIOFOCUS_NONE) {
                    sendAvrcpPause();
                } else {
                    startAvrcpUpdates();
                }
                break;

            case SRC_PAUSE:
                // Remote pause command, stop avrcp updates.
                stopAvrcpUpdates();
                break;

            case DISCONNECT:
                // Remote device has disconnected, restore everything to default state.
                sendAvrcpPause();
                stopAvrcpUpdates();
                abandonAudioFocus();
                mSentPause = false;
                break;

            case AUDIO_FOCUS_CHANGE:
                // message.obj is the newly granted audio focus.
                switch ((int) message.obj) {
                    case AudioManager.AUDIOFOCUS_GAIN:
                        // Begin playing audio, if we paused the remote, send a play now.
                        startAvrcpUpdates();
                        startFluorideStreaming();
                        if (mSentPause) {
                            sendAvrcpPlay();
                            mSentPause = false;
                        }
                        break;

                    case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
                        // Make the volume duck.
                        int duckPercent = mContext.getResources().getInteger(
                                R.integer.a2dp_sink_duck_percent);
                        if (duckPercent < 0 || duckPercent > 100) {
                            Log.e(TAG, "Invalid duck percent using default.");
                            duckPercent = DEFAULT_DUCK_PERCENT;
                        }
                        float duckRatio = (duckPercent / 100.0f);
                        if (DBG) {
                            Log.d(TAG, "Setting reduce gain on transient loss gain=" + duckRatio);
                        }
                        setFluorideAudioTrackGain(duckRatio);
                        break;

                    case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                        // Temporary loss of focus, if we are actively streaming pause the remote
                        // and make sure we resume playback when we regain focus.
                        if (mStreamAvailable) {
                            sendAvrcpPause();
                            mSentPause = true;
                        }
                        stopFluorideStreaming();
                        break;

                    case AudioManager.AUDIOFOCUS_LOSS:
                        // Permanent loss of focus probably due to another audio app, abandon focus
                        // and stop playback.
                        mAudioFocus = AudioManager.AUDIOFOCUS_NONE;
                        abandonAudioFocus();
                        sendAvrcpPause();
                        break;
                }
                break;

            default:
                Log.w(TAG, "Received unexpected event: " + message.what);
        }
    }
————————————————
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值