API 33下如何在Kotlin中通过代码修改蓝牙编解码器?
问题描述
想将蓝牙编解码器类型从AAC切换为SBC,针对Android API 33+开发,尝试使用setCodecConfigPreference方法但遇到不支持的问题,已创建好BluetoothCodecConfig实例,不知道如何应用。现有代码如下:
// Manifest <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" /> <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" tools:ignore="ProtectedPermissions" /> override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // API 33+ ----------------------------------------------------// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { val permissions = arrayOf( android.Manifest.permission.BLUETOOTH, android.Manifest.permission.BLUETOOTH_PRIVILEGED, android.Manifest.permission.BLUETOOTH_ADMIN, android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_SCAN ) if (applicationContext.checkSelfPermission(android.Manifest.permission.BLUETOOTH) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, permissions,0) } val device = BluetoothDevice.DEVICE_TYPE_CLASSIC val codec = BluetoothCodecConfig.Builder() .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC) .build() // HOW DO I APPLY THIS ??? } }
解决方案
API 33+中,要应用自定义的蓝牙编解码器配置,需要通过A2DP蓝牙代理来操作,具体步骤如下:
- 获取
BluetoothAdapter实例,通过getProfileProxy获取BluetoothA2dp代理对象 - 在代理回调中,获取当前已连接的蓝牙设备(必须是已配对且连接的设备)
- 调用
BluetoothA2dp.setCodecConfigPreference()方法传入目标设备和编解码器配置
注意:BLUETOOTH_PRIVILEGED是系统级权限,普通第三方应用通常无法获取,多数厂商会限制该权限的使用,仅系统应用或拥有系统签名的应用才能生效。
修正后的代码示例:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { val permissions = arrayOf( android.Manifest.permission.BLUETOOTH, android.Manifest.permission.BLUETOOTH_PRIVILEGED, android.Manifest.permission.BLUETOOTH_ADMIN, android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_SCAN ) if (applicationContext.checkSelfPermission(android.Manifest.permission.BLUETOOTH) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, permissions, 0) } // 创建SBC编解码器配置 val codec = BluetoothCodecConfig.Builder() .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC) // 可根据需求补充其他配置,比如采样率、比特率等 // .setSampleRate(BluetoothCodecConfig.SAMPLE_RATE_48000) // .setBitsPerSample(BluetoothCodecConfig.BITS_PER_SAMPLE_16) .build() // 获取蓝牙适配器 val bluetoothAdapter = BluetoothAdapter.getDefaultAdapter() if (bluetoothAdapter == null) { // 设备不支持蓝牙 return } // 获取A2DP代理 val a2dpCallback = object : BluetoothProfile.ServiceListener { override fun onServiceConnected(profile: Int, proxy: BluetoothProfile) { if (profile == BluetoothProfile.A2DP) { val a2dp = proxy as BluetoothA2dp // 获取已连接的A2DP设备 val connectedDevices = a2dp.connectedDevices if (connectedDevices.isNotEmpty()) { val targetDevice = connectedDevices[0] // 尝试设置编解码器偏好 val success = a2dp.setCodecConfigPreference(targetDevice, codec) // 验证是否设置成功 if (success) { // 设置成功逻辑 } else { // 设置失败,可能是权限不足或设备不支持 } } // 使用完后释放代理 bluetoothAdapter.closeProfileProxy(BluetoothProfile.A2DP, a2dp) } } override fun onServiceDisconnected(profile: Int) { // 代理断开处理 } } // 请求A2DP代理 bluetoothAdapter.getProfileProxy(this, a2dpCallback, BluetoothProfile.A2DP) } }
补充说明:
- 必须确保目标蓝牙设备处于已连接状态,否则设置无效
- 部分蓝牙设备可能不支持强制切换编解码器,即使代码执行成功也可能不生效
BLUETOOTH_PRIVILEGED权限需要系统签名或厂商授予,普通应用无法通过常规权限申请流程获取
内容的提问来源于stack exchange,提问作者István
相关产品推荐
相关产品推荐

