You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 14:52:13