我使用AudioRecord类中的setPreferredDevice方法切换两张外置USB声卡失败了,看了楼主名为《Android 9.0 Mtk 平台 如何切换使用的USB Audio 设备》的博客想问切换两张外置USB声卡是否一定要修改android源码,以及想请教一下源码修改以后应用层该如何编码,希望楼主看到后能回复我,这个问题已经困扰我半个月了,谢谢
1条回答 默认 最新
关注本答案参考 多次询问 ChatGPT-3.5 后选择的最佳回答,若是满意,还请采纳,谢谢
一、关于是否一定要修改Android源码来切换两张外置USB声卡
不一定要修改源码的情况
- 设备支持自动切换
- 某些Android设备在硬件和驱动层面可能已经支持USB声卡的自动切换。例如,一些高端的Android平板设备,其USB接口的驱动程序可能被设计为能够自动检测到新插入的USB声卡,并将音频输入/输出切换到新设备。如果设备的内核驱动和硬件设计支持USB音频设备的热插拔和自动切换,那么在应用层可能通过合适的API就可以实现切换,而不需要修改源码。
- 对于符合Android音频框架标准的USB声卡,Android系统本身可能会提供一定程度的自动管理。比如,当新的USB声卡被插入时,系统会发送广播通知音频相关的服务,这些服务可能会自动调整音频路由到新设备,而不需要对系统源码进行修改。
- 使用标准音频管理API
- 在Android中,有一些标准的音频管理API可以用于设备切换。例如,
AudioManager类除了有一些用于管理设备音量、音频模式等的方法外,也可能在某些情况下用于设备切换。如果两张USB声卡都能被系统正确识别为音频输入设备,并且遵循Android音频设备管理的规范,可能可以通过AudioManager的某些未被充分发掘的方法或者组合方法来实现切换,而无需修改源码。
- 在Android中,有一些标准的音频管理API可以用于设备切换。例如,
- 设备支持自动切换
可能需要修改源码的情况
驱动兼容性问题
- 如果USB声卡的驱动与Android设备的内核不兼容,例如,驱动没有正确实现Android音频框架所要求的某些接口或者回调函数,那么可能需要修改源码来使驱动与系统更好地协同工作。例如,在某些Mtk平台上,如果USB声卡的驱动没有正确处理音频流的暂停和恢复操作,这可能会导致在切换设备时出现问题,需要修改内核中的音频相关代码来修复这个问题。
特定平台限制
- 不同的Android平台(如Mtk、高通等)可能有自己特定的音频处理逻辑和限制。如果平台的音频框架没有考虑到同时存在两张USB声卡并且需要切换的情况,可能就需要修改源码。例如,平台的音频路由算法可能只设计为处理单个USB音频设备,当有第二个设备插入时,无法正确切换,此时可能需要深入到平台相关的音频源码部分进行修改。
定制音频策略需求
- 如果想要实现特定的音频切换策略,例如根据应用场景(如在录音应用中,根据录制内容类型切换不同的USB声卡),而这种策略不是Android默认音频框架所支持的,那么可能需要修改源码。例如,想要在一个语音通话应用中,根据网络质量动态切换到不同的USB声卡以保证通话质量,这可能需要修改Android的音频管理和通信相关的源码。
二、源码修改后应用层的编码
检测设备变化
- 如果修改了源码以支持USB声卡切换,在应用层首先需要能够检测到设备的变化。可以使用
BroadcastReceiver来监听与USB设备相关的广播。例如:
public class UsbAudioDeviceReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) { // 处理USB设备插入事件,可能是新的USB声卡插入 UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); // 在这里可以根据设备信息判断是否是USB声卡,并进行后续操作 } else if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_DETACHED)) { // 处理USB设备拔出事件 UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); // 进行相应的音频设备切换或状态更新操作 } } }- 然后在
AndroidManifest.xml中注册这个广播接收器:<receiver android:name=".UsbAudioDeviceReceiver"> <intent - filter> <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"/> <action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED"/> </intent - filter> </receiver>
- 如果修改了源码以支持USB声卡切换,在应用层首先需要能够检测到设备的变化。可以使用
与修改后的音频框架交互
- 如果源码修改涉及到音频框架的扩展,例如添加了新的方法来切换USB声卡,应用层需要调用这些新的方法。假设在修改源码后,
AudioManager类有了一个新的方法switchToUsbAudioDevice(UsbDevice device)来切换到指定的USB声卡设备,那么在应用层可以这样使用:AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); // 假设已经获取到了要切换到的USB声卡设备对象usbDevice audioManager.switchToUsbAudioDevice(usbDevice);
- 如果源码修改涉及到音频框架的扩展,例如添加了新的方法来切换USB声卡,应用层需要调用这些新的方法。假设在修改源码后,
处理音频流的迁移
- 当切换USB声卡时,正在进行的音频流(如正在录制的音频)需要正确地迁移到新的设备上。如果修改源码后提供了相应的机制,应用层需要按照这个机制来操作。例如,如果有一个新的回调接口
AudioStreamMigrationListener,应用层可以实现这个接口来处理音频流迁移过程中的事件:public class MyAudioActivity extends Activity implements AudioStreamMigrationListener { @Override public void onAudioStreamMigrationStart() { // 可以在这里显示一个进度条或者提示信息,表示音频流正在迁移 } @Override public void onAudioStreamMigrationComplete() { // 迁移完成后,可以更新界面或者继续其他操作 } }
- 当切换USB声卡时,正在进行的音频流(如正在录制的音频)需要正确地迁移到新的设备上。如果修改源码后提供了相应的机制,应用层需要按照这个机制来操作。例如,如果有一个新的回调接口
解决 无用评论 打赏 举报