【问题标题】:Android 10 - Audio Settings Permission Denial: setSpeakerphoneOn()Android 10 - 音频设置权限被拒绝:setSpeakerphoneOn()
【发布时间】:2021-04-04 15:08:54
【问题描述】:

我在 Android 10 上运行,无法使用 Kotlin 打开免提电话。 下面是我的代码,它在调用期间总是显示 False。

MainActivity.kt

val audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager
audioManager.mode = AudioManager.MODE_IN_COMMUNICATION
audioManager.isSpeakerphoneOn = true
if (audioManager.isSpeakerphoneOn)
    Toast.makeText(this, "True", Toast.LENGTH_SHORT).show()
else
    Toast.makeText(this, "False", Toast.LENGTH_SHORT).show()

AndroidManifest.xml

<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

Logcat

04-18 10:43:58.064  1313  3118 W AS.AudioService: Audio Settings Permission Denial: setSpeakerphoneOn() from pid=8073, uid=10213

【问题讨论】:

    标签: android kotlin


    【解决方案1】:

    我能够使用 InCallService 解决问题,我正在使用它作为默认拨号器开发应用程序。您所要做的就是获取扩展 InCallService 的 CallService 类的实例。由于在 Android 10 上您不能直接使用 setSpeakerphoneOn(),它在 Android 9 上运行良好。InCallService 有一个方法 setAudioRoute(),您可以使用它来路由音频。到目前为止,我已经在 Android 10 和 9 上测试了以下代码。还测试了 Wouter Vanhauwaert 在通话期间在扬声器和听筒之间交替的问题,该问题也可以正常工作。我的代码如下。

    CallService.java

    public class CallService extends InCallService {
    
      private static CallService sInstance;
      ……
    
      @Override
      public void onCreate() {
        super.onCreate();
        sInstance = this;
      }
      public static CallService getInstance(){
        return sInstance;
      }
    }
    

    AnotherActivity.java

    public void toggleSpeaker() {
     AudioManager am = (AudioManager)this.getSystemService(Context.AUDIO_SERVICE);
     boolean isSpeakerOn = audioManager.isSpeakerphoneOn();
     int earpiece = CallAudioState.ROUTE_WIRED_OR_EARPIECE;
     int speaker = CallAudioState.ROUTE_SPEAKER;
    
     if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.P){
     CallService.getInstance().setAudioRoute(isSpeakerOn ? earpiece : speaker);
     } else {
       am.setSpeakerphoneOn(!isSpeakerOn);
     }
    }
    

    【讨论】:

    • 如何在不使用 InCallService 的情况下做到这一点?我在 webView 上有一个 webRTC 语音通话应用程序。和 am.setSpeakerphoneOn(false);不会改变 android 12 上的任何内容。
    • 嗨@SujithManjavana,你找到解决方案了吗?我也面临与 android 12 相同的问题,即 am.setSpeakerphoneOn(false) 不起作用
    • @ShivamSharma 你找到解决方案了吗?我遇到了同样的问题:setSpeakerphoneOn 不会改变 isSpeakerphoneOn 的状态。
    • 是的,对于 android 12,您需要添加额外的处理 @CaitlynCodr
    • @ShivamSharma 不错!你能详细说明一下吗?我真的坚持这一点。我也发布了我自己的问题,我可以让你回答:)
    【解决方案2】:

    我在使用 java 时偶然发现了同样的问题...还有 Android 10 但是,当我在拨打电话之前更改模式时,它可以正常工作。只有在通话期间在扬声器和听筒之间交替出现问题

    AudioManager am = (AudioManager)this.getSystemService(Context.AUDIO_SERVICE);
    am.setMode(AudioManager.MODE_IN_CALL);
    if(am.isSpeakerphoneOn())
        am.setSpeakerphoneOn(false);
    else
        am.setSpeakerphoneOn(true);
    

    【讨论】:

      【解决方案3】:

      我发现 Wouter Vanhauwaert 是正确的。澄清一下:对于 Android 9 及更低版本,请在 TelephonyManager.CALL_STATE_OFFHOOK 期间调用 setSpeakerphoneOn(true)。对于 Android 10 及更高版本,请在开始电话呼叫活动之前调用它。要支持所有 Android 版本,请在两个地方调用它。

      新更新:我发现此解决方案不再适用于 Android System Update 28 (android-11.0.0_r28)。它使用的版本必须是 System Update 23 (android-11.0.0_r23) 或更早版本。

      【讨论】:

      • 问题出在 audioManager.setMode(AudioManager.MODE_IN_CALL);它不工作。在呼叫之前,振铃期间模式不会更改为 MODE_IN_CALL。答案是自动更改的,不需要显式更改。 :-(
      猜你喜欢
      • 2021-01-01
      • 2022-07-21
      • 1970-01-01
      • 1970-01-01
      • 2019-03-25
      • 1970-01-01
      • 2013-07-03
      • 2015-12-21
      • 2020-06-03
      相关资源
      最近更新 更多