【问题标题】:how to turn speaker on/off programmatically in android Pie and UP如何在 android Pie 和 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 中使用。

标签: android


【解决方案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);
        }

【讨论】:

    猜你喜欢
    • 2012-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-02
    • 1970-01-01
    • 1970-01-01
    • 2011-09-21
    • 2015-05-27
    相关资源
    最近更新 更多