如何在 android Pie 和 UP 中以编程方式打开/关闭扬声器
Posted
技术标签:
【中文标题】如何在 android Pie 和 UP 中以编程方式打开/关闭扬声器【英文标题】:how to turn speaker on/off programmatically in android Pie and UP 【发布时间】:2019-06-03 11:56:08 【问题描述】:与这个问题以及几年前的许多其他问题相同: how to turn speaker on/off programmatically in android 4.0
Android 似乎改变了它处理这个问题的方式。
以下是我尝试以编程方式拨打电话以使用免提电话的方式。这些解决方案都不适用于 Android Pie。 虽然它们似乎在 Android Nougat 和 Oreo 上运行良好
解决方案 1。
final static int FOR_MEDIA = 1;
final static int FORCE_NONE = 0;
final static int FORCE_SPEAKER = 1;
Class audiosystemClass = Class.forName("android.media.AudioSystem");
Method setForceUse = audioSystemClass.getMethod("setForceUse", int.class, int.class);
setForceUse.invoke(null, FOR_MEDIA, FORCE_SPEAKER);
2.
AudioManager audioManager = (AudioManager)getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
if (audioManager != null)
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
audioManager.setSpeakerphoneOn(true);
3.
AudioManager audioManager = (AudioManager)getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
if (audioManager != null)
audioManager.setMode(AudioManager.MODE_IN_CALL);
audioManager.setSpeakerphoneOn(true);
4.
Thread thread = new Thread()
@Override
public void run()
try
while(true)
sleep(1000);
audioManager.setMode(AudioManager.MODE_IN_CALL);
if (!audioManager.isSpeakerphoneOn())
audioManager.setSpeakerphoneOn(true);
catch (InterruptedException e)
e.printStackTrace();
;
thread.start();
该应用具有以下授予的许多其他权限:
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
我还尝试了以下仅用于拨出电话的解决方案。它也没有工作。
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.putExtra("speaker", true);
callIntent.setData(Uri.parse("tel:" + number));
context.startActivity(callIntent);
【问题讨论】:
你是怎么解决这个问题的? M 在 oreo nd up 上面临同样的问题 问题尚未解决。 我有更多信息。在Android Pie中,该应用程序需要一个额外的权限,MODIFY_AUDIO_ROUTING,据我所知,这只能授予系统应用程序。如果您拥有此权限,解决方案 1 应该可以工作。 ndroidaudiotes:访问隐藏方法 Landroid/media/AudioSystem;->setForceUse(II)I(浅灰名单,反射)权限失败:android.permission.MODIFY_AUDIO_ROUTING from uid=10296 pid=26584 CALL_LOG 不能在 Android 9 中使用。 【参考方案1】:在 Android Pie 中,我遇到了同样的问题。我使用带有
的InCallService 解决了它setAudioRoute(ROUTE_SPEAKER)
您的应用需要是默认手机应用。
【讨论】:
有没有其他方法不做默认手机应用? 我尝试了许多不同的方法,但这是我发现的唯一可行的解决方案【参考方案2】:我很惊讶没有人提到TelecomManager.EXTRA_START_CALL_WITH_SPEAKERPHONE。
作为一个意图:
val uri = Uri.fromParts("tel", PHONE_NUMBER, null)
val intentCall = Intent(Intent.ACTION_CALL, uri).apply
putExtra(TelecomManager.EXTRA_START_CALL_WITH_SPEAKERPHONE, true)
flags = Intent.FLAG_ACTIVITY_NEW_TASK
startActivity(intentCall)
使用 TelecomManager.placeCall:
val uri = Uri.fromParts("tel", PHONE_NUMBER, null)
val extras = Bundle().apply putBoolean(TelecomManager.EXTRA_START_CALL_WITH_SPEAKERPHONE, true)
val telecomManager = getSystemService(TELECOM_SERVICE) as TelecomManager
telecomManager.placeCall(uri, extras)
默认手机应用应处理这些额外数据并启用扬声器。
记得请求android.permission.CALL_PHONE
的权限。
【讨论】:
在 Android 11 中为我工作【参考方案3】:对于这个问题,请尝试下面的代码,它对我有用。
AudioManager myAudioManager;
myAudioManager.setMode(AudioManager.MODE_NORMAL);
myAudioManager.setSpeakerphoneOn(true);
【讨论】:
这并不能解决问题,这只会打开免提电话,而不是启用听筒而不是耳机。【参考方案4】:在我的自我管理的语音通话应用程序中,我通过更改连接服务音频路由来管理,如下所示,除了使用 audioManager,
public void setSpeakerphoneOn(final boolean enabled)
if (enabled != audioManager.isSpeakerphoneOn())
Log.d(TAG, "setSpeakerphoneOn(): " + enabled);
audioManager.setSpeakerphoneOn(enabled);
在我的连接服务类中,
public void speakerOnOff(String uuid,boolean on)
Log.d(TAG,"SPEAKER is" + String.valueOf(on));
Connection connection = VoipConnectionService.getConnection(uuid);
if (on)
connection.setAudioRoute(CallAudioState.ROUTE_SPEAKER);
else
connection.setAudioRoute(CallAudioState.ROUTE_EARPIECE);
或者您可以根据您的音频设备更改路由以进行输出
public void speakerOnOff(String uuid,String device)
Log.d(TAG,"Device to route is" + device);
Connection connection = VoipConnectionService.getConnection(uuid);
int state = CallAudioState.ROUTE_EARPIECE ;
switch (device)
case "SPEAKER_PHONE":
state = CallAudioState.ROUTE_SPEAKER ;
break;
case "WIRED_HEADSET":
state = CallAudioState.ROUTE_WIRED_HEADSET ;
break;
case "EARPIECE" :
case "NONE" :
state = CallAudioState.ROUTE_EARPIECE ;
break;
case "BLUETOOTH" :
state = CallAudioState.ROUTE_BLUETOOTH ;
break;
connection.setAudioRoute(state);
【讨论】:
以上是关于如何在 android Pie 和 UP 中以编程方式打开/关闭扬声器的主要内容,如果未能解决你的问题,请参考以下文章
以编程方式获取 Android 手机型号,如何在 android 中以编程方式获取设备名称和型号?