问题Android连接蓝牙设备调节音量会出现乱变的问题
原因是由于上层判断出支持绝对音量设置,会调用绝对音量的设置,有些蓝牙设备设置绝对音量出问题导致的异常。
解决办法设置黑名单让一些设备不支持绝对音量的设置。
external/bluetooth/bluedroid/btif/src/btif_rc.c
/*************************************************************************** ** ** Function set_volume ** ** Description Send current volume setting to remote side. ** Support limited to SetAbsoluteVolume ** This can be enhanced to support Relative Volume (AVRCP 1.0). ** With RelateVolume, we will send VOLUME_UP/VOLUME_DOWN ** as opposed to absolute volume level ** volume: Should be in the range 0-127. bit7 is reseved and cannot be set ** ** Returns bt_status_t ** ***************************************************************************/ static bt_status_t set_volume(uint8_t volume) { BTIF_TRACE_DEBUG1("%s", __FUNCTION__); CHECK_RC_CONNECTED tAVRC_STS status = BT_STATUS_UNSUPPORTED; rc_transaction_t *p_transaction=NULL; if(btif_rc_cb.rc_volume==volume) { status=BT_STATUS_DONE; BTIF_TRACE_ERROR2("%s: volume value already set earlier: 0x%02x",__FUNCTION__, volume); return status; } if ((btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG) && (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL)) { tAVRC_COMMAND avrc_cmd = {0}; BT_HDR *p_msg = NULL; BTIF_TRACE_ERROR2("%s: Peer supports absolute volume. newVolume=%d", __FUNCTION__, volume);
黑名单设置
static const UINT8 rc_black_addr_prefix[][3] = { {0x0, 0x18, 0x6B}, // LG HBS-730 {0x0, 0x26, 0x7E} // VW Passat }; static const UINT8 rc_white_addr_prefix[][3] = { {0x94, 0xCE, 0x2C}, // Sony SBH50 {0x30, 0x17, 0xC8} // Sony wm600 }; static BOOLEAN dev_blacklisted_for_absolute_volume(BD_ADDR peer_dev) { int i; int whitelist_size = sizeof(rc_white_addr_prefix)/sizeof(rc_white_addr_prefix[0]); for (i = 0; i < whitelist_size; i++) { if (rc_white_addr_prefix[i][0] == peer_dev[0] && rc_white_addr_prefix[i][1] == peer_dev[1] && rc_white_addr_prefix[i][2] == peer_dev[2]) { BTIF_TRACE_DEBUG3("whitelist absolute volume for %02x:%02x:%02x", peer_dev[0], peer_dev[1], peer_dev[2]); return FALSE; } } BTIF_TRACE_WARNING3("blacklist absolute volume for %02x:%02x:%02x", peer_dev[0], peer_dev[1], peer_dev[2]); return TRUE; } void handle_rc_features() { btrc_remote_features_t rc_features = BTRC_FEAT_NONE; bt_bdaddr_t rc_addr; bdcpy(rc_addr.address, btif_rc_cb.rc_addr); if (dev_blacklisted_for_absolute_volume(btif_rc_cb.rc_addr)) { //不支持绝对音量设置 btif_rc_cb.rc_features &= ~BTA_AV_FEAT_ADV_CTRL; } if (btif_rc_cb.rc_features & BTA_AV_FEAT_BROWSE) { rc_features |= BTRC_FEAT_BROWSE; } if ( (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL) && (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)) { rc_features |= BTRC_FEAT_ABSOLUTE_VOLUME; } if (btif_rc_cb.rc_features & BTA_AV_FEAT_METADATA) { rc_features |= BTRC_FEAT_METADATA; } ...
frameworks/base/media/java/android/media/AudioSerivce.java
public void applyDeviceVolume(int device) { int index; if (isMuted()) { index = 0; } else if ((device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0 && mAvrcpAbsVolSupported) { //mAvrcpAbsVolSupported 是底层返回是否支持绝对音量设置 index = (mIndexMax + 5)/10; } else { index = (getIndex(device) + 5)/10; } AudioSystem.setStreamVolumeIndex(mStreamType, index, device); }