How to turn-on SpeakerPhone during a call in Xamarin.Forms Android 13

Universal Camera 276 Reputation points
2022-10-16T20:21:46.933+00:00

I have Telephony Xamarin.Forms App that is able to turn-on speaker phone in Android 11 and earlier using

        AudioManager audioManager = (AudioManager)Android.App.Application.Context.GetSystemService(Context.AudioService);  
                App.audioManager.SpeakerphoneOn = true;  

however in android 12 & 13 this code is NOT turning-on speakerphone

I have now modified this code per this posting

https://stackoverflow.com/questions/72098404/setspeakerphoneon-from-audiomanager-is-not-changing-speakerphone-value-on-androi

adapting it this is what I got

                            IList<AudioDeviceInfo> devices = audioManager.AvailableCommunicationDevices;  
                                Boolean result = audioManager.SetCommunicationDevice(devices[1]);  //device[0] is earphone  
                               CallService.getInstance().SetAudioRoute(VideoQuality.High);  
                                audioManager.SpeakerphoneOn = true;  

which does NOT work!!!!!

What am I doing wrong in converting Java code????

Update:

I implemented it in my PhoneCallListner BroadcastReciever where I used the Context as Application.Context instead your recommendation of "this". I am not sure what to use for Context since "this" is not resolved by compiler. So the SpeakerPhone is NOT activated even though the "result" is computed to be TRUE.

   Utils.setCommunicationDevice(Application.Context, AudioDeviceType.BuiltinSpeaker);  // Application.Context vs this  
                    bool result = audioManager.SetCommunicationDevice(device); // the result computed to be TRUE  

In desperation I tried that earlier with no success. Also I used the Context of the BroadcastReciever

   [BroadcastReceiver(Enabled = true, Exported = true)]  
   [IntentFilter(new[] { TelephonyManager.ActionPhoneStateChanged }, Priority = (int)IntentFilterPriority.HighPriority)]  
   public class PhoneCallListener : BroadcastReceiver  
   {  
   public override void OnReceive(Context context, Intent intent)  
   {  
   var state = intent.GetStringExtra(TelephonyManager.ExtraState);  
     
            if (intent.Action == TelephonyManager.ActionPhoneStateChanged)  
            {  
                if (state == TelephonyManager.ExtraStateOffhook)  
                {  
   Task.Run(() =>  
   {  
   Task.Delay(10000).Wait();  
   Xamarin.Forms.Device.BeginInvokeOnMainThread(() =>  
   {  
   if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.S)  
   {  
   Utils.setCommunicationDevice(MainActivity.mainActivity, AudioDeviceType.BuiltinSpeaker);  
   }  
   else  
   {  
   audioManager.SpeakerphoneOn = false;  
   }  
   });  
   });  
   }  
   }  
   }  
Developer technologies | .NET | Xamarin
0 comments No comments
{count} votes

Accepted answer
  1. Yonglun Liu (Shanghai Wicresoft Co,.Ltd.) 50,126 Reputation points Microsoft External Staff
    2022-10-17T05:46:02.387+00:00

    Hello,

    I've converted the Java code to Xamarin, and it just works fine on Android 10 and 11.

    It is more recommended to post your issue in Xamarin.Forms-issues to make our Product Group aware of it.

    Please refer to the following code:

       public void switchSpeakerState()   
       {  
           AudioManager audioManager = (AudioManager)GetSystemService(Context.AudioService);  
           if (isSpeakerOn)  
           {  
               isSpeakerOn = false;  
               if (Android.OS.Build.VERSION.SdkInt >= BuildVersionCodes.S)  
               {  
                   Utils.setCommunicationDevice(this, Android.Media.AudioDeviceType.BuiltinEarpiece);  
               }  
               else  
               {  
                   audioManager.SpeakerphoneOn = false;  
               }  
           }  
           else  
           {  
               isSpeakerOn = true;  
               if (Android.OS.Build.VERSION.SdkInt >= BuildVersionCodes.S)  
               {  
                   Utils.setCommunicationDevice(this, Android.Media.AudioDeviceType.BuiltinSpeaker);  
               }  
               else  
               {  
                   audioManager.SpeakerphoneOn = true;  
               }  
           }  
       }  
    

    Utils.cs:

       public static class Utils   
       {  
           public static void setCommunicationDevice(Context context, AudioDeviceType targetDeviceType)  
           {  
               AudioManager audioManager = (AudioManager)context.GetSystemService(Context.AudioService);  
               var devices = audioManager.AvailableCommunicationDevices;  
               foreach (AudioDeviceInfo device in devices)  
               {  
                   if (device.Type == targetDeviceType)  
                   {  
                       bool result = audioManager.SetCommunicationDevice(device); // the result will be true  
                       Log.Debug("result: ", result.ToString());  
                   }  
               }  
           }  
       }  
    

    Best Regards,

    Alec Liu.


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.