setSpeakerphoneOn 不会更改 Android 12 上的扬声器值,它始终保持 false。为什么?

问题描述 投票:0回答:3
fun toggleSpeaker(context: Context) {
        isSpeakerPhoneSelected.value?.let {
            val audioManager: AudioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
            audioManager.setSpeakerphoneOn = !it
            isSpeakerPhoneSelected.value = !it
            logDebug(context, it.toString().plus(audioManager.isSpeakerphoneOn.toString()))
        }
    }

记录器显示 isSpeakerPhoneSelected 值在 true 和 false 之间切换,但 isSpeakerphoneOn 始终返回 false。从 Android 12 开始,此功能已停止工作。

这些是我们的 build.gradle 中的版本:

        buildToolsVersion = "29.0.3"
        minSdkVersion = 23
        compileSdkVersion = 30
        targetSdkVersion = 30
        supportLibVersion = "28.0.0"

是什么导致 isSpeakerphoneOn 值不变以及如何解决此问题?我已经为此苦苦挣扎有一段时间了,所以我很感激任何建议:p谢谢!

android android-audiomanager
3个回答
5
投票

之前,当我将 targetSDKLevel 设置为 android 12 时,我也遇到过同样的问题。我有一个呼叫屏幕,在该屏幕上提供了一个扬声器按钮,用户可以通过该按钮打开/关闭扬声器。

我使用适用于 android 12 的 AudioDeviceInfo API 在audioManager 上设置通信设备。

public void switchSpeakerState() {
        if (isSpeakerOn) {
            isSpeakerOn = false;
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
                Utils.getInstance().setCommunicationDevice(getContext(), AudioDeviceInfo.TYPE_BUILTIN_EARPIECE);
            } else {
                audioManager.setSpeakerphoneOn(false);
            }
            ivSpeaker.setImageResource(R.drawable.speaker_outline);
        } else {
            isSpeakerOn = true;
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
                Utils.getInstance().setCommunicationDevice(getContext(), AudioDeviceInfo.TYPE_BUILTIN_SPEAKER);
            } else {
                audioManager.setSpeakerphoneOn(true);
            }
            ivSpeaker.setImageResource(R.drawable.speaker_filled);
        }
    }

Utils.java

@RequiresApi(api = Build.VERSION_CODES.S)
public void setCommunicationDevice(Context context, Integer targetDeviceType) {
    AudioManager audioManager = (AudioManager) context.getSystemService(AUDIO_SERVICE);
    List < AudioDeviceInfo > devices = audioManager.getAvailableCommunicationDevices();
    for (AudioDeviceInfo device: devices) {
        if (device.getType() == targetDeviceType) {
            boolean result = audioManager.setCommunicationDevice(device);
            Log.d("result: ", result);
        }
    }
}

0
投票

将其归结为 kotlin(因为问题是在 kotlin 中提出的):

val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
     audioManager.availableCommunicationDevices.firstOrNull { it.type == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER }
     ?.let {
          audioManager.setCommunicationDevice(it)
     }
} else {
     audioManager.isSpeakerphoneOn = true
}

0
投票

如果是 VoIP 应用程序(自我管理呼叫),如果您想将音频设置为扬声器,您需要添加以下 2 件事

  1. audioManager.setCommunicationDevice(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER);

  2. connection.setAudioRoute(CallAudioState.ROUTE_SPEAKER);
    里面 <T 扩展 android.telecom.ConnectionService> 类(ConnectionService 类)

     private void turnSpeakerOn(boolean turnOn, AudioManager 
     audioManager) {
        if (turnOn) {
           if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
              setAudioDevice(audioManager, 
              AudioDeviceInfo.TYPE_BUILTIN_SPEAKER);
           } else {
              audioManager.setSpeakerphoneOn(true);
           }
    
       sendSetAudioRouteLocalBroadcast(MyConstants.ROUTE_SPEAKER);
     } else {
       // OFF
       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
         audioManager.clearCommunicationDevice();
       } else {
         audioManager.setSpeakerphoneOn(false);
       }
     }
    

}

  private static void setAudioDevice(AudioManager audioManager, int 
  audioType) {
      List<AudioDeviceInfo> audioDevices = 
      audioManager.getAvailableCommunicationDevices();
      for (AudioDeviceInfo device : audioDevices) {
      if (device.getType() == audioType) {
         audioManager.setCommunicationDevice(device);
         break;
      }
    }
  }

  

[2] 内部连接类监听本地广播,在扬声器按钮上按下操作

// 公共类 MyConnectionService 扩展 ConnectionService

        private final BroadcastReceiver audioStateReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(final Context context, final Intent intent) {
        if (intent.getExtras() != null) {
            Connection connection = myConnection; //android.telecom.Connection class
            if (connection!= null) {
                connection.setAudioRoute(CallAudioState.ROUTE_SPEAKER);
            }
        }
    }
};


  
© www.soinside.com 2019 - 2024. All rights reserved.