1

In my application, there is one Card Reader which uses Audio Jack of devices.Now, my problem is I want to produce sound from built-in speakers when Card Reader is intact in HeadPhone Jack of the device.

Here are the codes I have tried:

1) Using Reflection Methods

Class audioSystemClass;
                try {
                     audioSystemClass = Class
                            .forName("android.media.AudioSystem");

                    Method setForceUse = audioSystemClass.getMethod(
                            "setForceUse", int.class, int.class);
                    // First 1 == FOR_MEDIA, second 1 == FORCE_SPEAKER. To go
                    // back to the default
                    // behavior, use FORCE_NONE (0).
                    setForceUse.invoke(null, 1, 1);
                    final float maxVolume = mAudioManager
                            .getStreamMaxVolume(AudioManager.STREAM_MUSIC);
                    soundPool.play(soundID, maxVolume, maxVolume, 1, 0, 1f);


                } catch (ClassNotFoundException e) {
                    Log.e("Test", e.toString());
                    e.printStackTrace();
                } catch (NoSuchMethodException e) {
                    Log.e("Test", e.toString());
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    Log.e("Test", e.toString());
                    e.printStackTrace();
                } catch (IllegalArgumentException e) {
                    Log.e("Test", e.toString());
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    Log.e("Test", e.toString());
                    e.printStackTrace();
                }

2) Using setMode method

mAudioManager.setMode(AudioManager.MODE_IN_CALL);
                mAudioManager.setSpeakerphoneOn(true);
                float maxVolume = mAudioManager
                        .getStreamMaxVolume(AudioManager.STREAM_RING);
                soundPool.play(soundID, maxVolume, maxVolume, 1, 0, 1f);

But these both codes are running in only those devices which have default FM application. But I want to have this functionality in all devices.

Please share your experience !!

  • maybe [this](http://stackoverflow.com/questions/2917184/forcing-sound-output-through-speaker-in-android) will help you out, it's slightly different than what you have tried. – Strider Jun 10 '15 at 07:53

3 Answers3

0

Your second approach setMode holds correct for phones with default Fm player.

However for devices without Default FM , I tried the following code:

mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
mAudioManager.setSpeakerphoneOn(true);

This code worked fine for the phones without default Fm player.I used a OnePlus device with Oxygen OS and worked fine. Hope this helps.

Saurav
  • 560
  • 4
  • 17
0

Alternatively, if you initialize your SoundPool to STREAM_VOICE_CALL, as:

SoundPool spool = new SoundPool(1,AudioManager.STREAM_VOICE_CALL, 0)

then also your audio should be routed to loudspeaker with any of the way you have mentioned above. I tried and its working on phones even without default FM.

Saurav
  • 560
  • 4
  • 17
  • Hey can u suggest any possible reason why the above code is not running on Samsung 4.4.2 version but its working on Nexus devices ?? – lifelongLearner Jun 11 '15 at 14:11
  • In Samsung devices possibly they have tweaked the audio parameter, that's the reason why audio api's are behaving differently. But its just my guess. By setting soundpool to stream_voice call possibly it should work on most of the phone because u are overriding the gsm call behavior ! – Saurav Jun 11 '15 at 14:33
0

Here, I have initiated a SoundPool and loaded a beep.

 SoundPool soundPool = new SoundPool(10, AudioManager.STREAM_VOICE_CALL, 0);

            soundPool
                    .setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {

                        @Override
                        public void onLoadComplete(SoundPool soundPool,
                                                   int sampleId, int status) {
                            loaded = true;
                        }
                    });
            soundID = soundPool.load(ApplicationChexology.getContext(), R.raw.beep_single, 1);

Now, after loading sound , I am setting AudioManager to MODE_IN_COMMUNICATION and playing sound. When sound has played , setting Audio Manager's mode to MODE_NORMAL.

 audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
 audioManager.setSpeakerphoneOn(true);

 float maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
        if (loaded)
         soundPool.play(soundID, maxVolume, maxVolume, 1, 0, 1f);

        Timer timer = new Timer();

        TimerTask delayedThreadStartTask = new TimerTask() {
          @Override
          public void run() {
             audioManager.setMode(AudioManager.MODE_NORMAL);
             audioManager.setSpeakerphoneOn(false);

                }};
    timer.schedule(delayedThreadStartTask, 500);