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谢谢!
之前,当我将 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);
}
}
}
将其归结为 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
}
如果是 VoIP 应用程序(自我管理呼叫),如果您想将音频设置为扬声器,您需要添加以下 2 件事
audioManager.setCommunicationDevice(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER);
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);
}
}
}
};