0

I'm using MediaPlayer to play audio via an AsyncTask, and using AudioManager to set the stream. On a specific button press, I call AudioManager's setSpeakerPhoneOn() to toggle, but it doesn't switch to ear speaker. My audio always blasts through the main speaker.

I tried these solutions (as is apparent in the code below), but none worked:

  1. Switching between earpiece and speakerphone on button press
  2. Audiomanager Speaker not working

Here's my code for initializing the AudioManager in onViewCreated:

try {
            audioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
            audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
            audioManager.setSpeakerphoneOn(loudOn);
            // loudOn is defined globally, and initialized to false
        }

This is the audio playing function which uses AsyncTask:

static private void playCall(final Context context, final String[] contactParts)
    {
        final MediaPlayer mediaPlayer = new MediaPlayer();
        new AsyncTask<Void,Void,Boolean>() {
            @Override
            protected Boolean doInBackground(Void... voids) {
                try {

                    mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                        @Override
                        public void onPrepared(MediaPlayer mp) {
                            mp.start();
                        }
                    });

                    mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                        @Override
                        public void onCompletion(MediaPlayer mp) {
                            mp.reset();
                            mp.release();
                        }
                    });

                    int audioFile_R_id = //get audio file id
                    try {
                        AssetFileDescriptor afd = context.getResources().openRawResourceFd(audioFile_R_id);
                        if (afd == null) return false;
                        mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
                        afd.close();

                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                            mediaPlayer.setAudioAttributes(new AudioAttributes.Builder()
                                    .setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
                                    .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
                                    .build());

                        } else {
                            //deprecated in API 26
                            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                        }

                        mediaPlayer.prepare();
                        return true;
                    }
                    catch (Resources.NotFoundException rnf)
                    {
                        rnf.printStackTrace();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return false;
            }

            @Override
            protected void onPostExecute(Boolean prepared) {
                if (prepared) {
                    mediaPlayer.start();
                }
            }
        }.execute();
    }

And this is the button code that attempts to toggle:

loudFAB.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                loudOn = !loudOn;
                audioManager.setSpeakerphoneOn(loudOn);
            }
        });
3iL
  • 2,146
  • 2
  • 23
  • 47

1 Answers1

0

Change the AudioManager

    try {
            audioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
            audioManager.setMode(AudioManager.MODE_IN_CALL);
            audioManager.setSpeakerphoneOn(loudOn);
            // loudOn is defined globally, and initialized to false
        }
Deˣ
  • 4,191
  • 15
  • 24
  • I read here that MODE_IN_CALL _ensures_ that the audio will **never play** on some devices? https://stackoverflow.com/a/15255477/5719908 – Tanmay Band Jun 21 '19 at 08:50
  • I understand setting it on AudioManger should work. The link is about setting it on MediaPlayer instance. – Deˣ Jun 21 '19 at 08:53