weixin_43916667 2024-11-19 14:52 采纳率: 0%
浏览 27

android 外置USB设备输入声卡切换问题

我使用AudioRecord类中的setPreferredDevice方法切换两张外置USB声卡失败了,看了楼主名为《Android 9.0 Mtk 平台 如何切换使用的USB Audio 设备》的博客想问切换两张外置USB声卡是否一定要修改android源码,以及想请教一下源码修改以后应用层该如何编码,希望楼主看到后能回复我,这个问题已经困扰我半个月了,谢谢

  • 写回答

1条回答 默认 最新

  • 越重天 新星创作者: Java技术领域 2024-11-20 10:41
    关注

    本答案参考 多次询问 ChatGPT-3.5 后选择的最佳回答,若是满意,还请采纳,谢谢

    一、关于是否一定要修改Android源码来切换两张外置USB声卡

    1. 不一定要修改源码的情况

      • 设备支持自动切换
        • 某些Android设备在硬件和驱动层面可能已经支持USB声卡的自动切换。例如,一些高端的Android平板设备,其USB接口的驱动程序可能被设计为能够自动检测到新插入的USB声卡,并将音频输入/输出切换到新设备。如果设备的内核驱动和硬件设计支持USB音频设备的热插拔和自动切换,那么在应用层可能通过合适的API就可以实现切换,而不需要修改源码。
        • 对于符合Android音频框架标准的USB声卡,Android系统本身可能会提供一定程度的自动管理。比如,当新的USB声卡被插入时,系统会发送广播通知音频相关的服务,这些服务可能会自动调整音频路由到新设备,而不需要对系统源码进行修改。
      • 使用标准音频管理API
        • 在Android中,有一些标准的音频管理API可以用于设备切换。例如,AudioManager类除了有一些用于管理设备音量、音频模式等的方法外,也可能在某些情况下用于设备切换。如果两张USB声卡都能被系统正确识别为音频输入设备,并且遵循Android音频设备管理的规范,可能可以通过AudioManager的某些未被充分发掘的方法或者组合方法来实现切换,而无需修改源码。
    2. 可能需要修改源码的情况

      • 驱动兼容性问题

        • 如果USB声卡的驱动与Android设备的内核不兼容,例如,驱动没有正确实现Android音频框架所要求的某些接口或者回调函数,那么可能需要修改源码来使驱动与系统更好地协同工作。例如,在某些Mtk平台上,如果USB声卡的驱动没有正确处理音频流的暂停和恢复操作,这可能会导致在切换设备时出现问题,需要修改内核中的音频相关代码来修复这个问题。
      • 特定平台限制

        • 不同的Android平台(如Mtk、高通等)可能有自己特定的音频处理逻辑和限制。如果平台的音频框架没有考虑到同时存在两张USB声卡并且需要切换的情况,可能就需要修改源码。例如,平台的音频路由算法可能只设计为处理单个USB音频设备,当有第二个设备插入时,无法正确切换,此时可能需要深入到平台相关的音频源码部分进行修改。
      • 定制音频策略需求

        • 如果想要实现特定的音频切换策略,例如根据应用场景(如在录音应用中,根据录制内容类型切换不同的USB声卡),而这种策略不是Android默认音频框架所支持的,那么可能需要修改源码。例如,想要在一个语音通话应用中,根据网络质量动态切换到不同的USB声卡以保证通话质量,这可能需要修改Android的音频管理和通信相关的源码。

    二、源码修改后应用层的编码

    1. 检测设备变化

      • 如果修改了源码以支持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>
        
    2. 与修改后的音频框架交互

      • 如果源码修改涉及到音频框架的扩展,例如添加了新的方法来切换USB声卡,应用层需要调用这些新的方法。假设在修改源码后,AudioManager类有了一个新的方法switchToUsbAudioDevice(UsbDevice device)来切换到指定的USB声卡设备,那么在应用层可以这样使用:
        AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        // 假设已经获取到了要切换到的USB声卡设备对象usbDevice
        audioManager.switchToUsbAudioDevice(usbDevice);
        
    3. 处理音频流的迁移

      • 当切换USB声卡时,正在进行的音频流(如正在录制的音频)需要正确地迁移到新的设备上。如果修改源码后提供了相应的机制,应用层需要按照这个机制来操作。例如,如果有一个新的回调接口AudioStreamMigrationListener,应用层可以实现这个接口来处理音频流迁移过程中的事件:
        public class MyAudioActivity extends Activity implements AudioStreamMigrationListener {
          @Override
          public void onAudioStreamMigrationStart() {
              // 可以在这里显示一个进度条或者提示信息,表示音频流正在迁移
          }
          @Override
          public void onAudioStreamMigrationComplete() {
              // 迁移完成后,可以更新界面或者继续其他操作
          }
        }
        
    评论

报告相同问题?

问题事件

  • 请选择合适的标签 11月19日
  • 创建了问题 11月19日