AI智能
改变未来

Android 8.1开启Bluetooth A2DP 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 runningbreak;case BTA_A2DP_SINK_SERVICE_ID:if (!btif_a2dp_sink_startup())return BT_STATUS_FAIL;  // Already runningbreak;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;}

修改完这个后A2DP sink profile是有了,另外的手机也可以连上,数据也有传到我们的板子上,就是没有声音,调试发现就是播放没有执行
播放函数在pachages\\appsBluetooth\\src\\com\\android\\bluetooth\\a2dpsink\\A2dpSinkStreamHandler.java

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

开始播放后mAudioFocus 为0,就不会进到startAvrcpUpdates();,现在是在前面去requestAudioFocus();,这样在手机上播放的声音就都要RK3399的板子上了。

目前没有发现什么问题,有问题一起讨论哈!

赞(0) 打赏
未经允许不得转载:爱站程序员基地 » Android 8.1开启Bluetooth A2DP sink