11

I was using following code to play sound. Everything worked fine before ICS. But on ICS and higher versions no sound is heard. There is no error, but no sound can be heard.

EDIT: Note, the following code is triggered by a broadcase receiver. BroadCast receiver invokes a async task. In the post process method of asycn task the following method is called.

What could the error possibly be?

public static void playSound(final Context context, final int volume,
            Uri uri, final int stream, int maxTime, int tickTime) {
        //stopPlaying();
        /*
        if (stream < 0 || stream > 100) {
            throw new IllegalArgumentException(
                    "volume must be between 0 and 100 .Current volume "
                            + volume);
        }*/

        final AudioManager mAudioManager = (AudioManager) context
                .getSystemService(Context.AUDIO_SERVICE);

        int deviceLocalVolume = getDeviceVolume(volume,
                mAudioManager.getStreamMaxVolume(stream));

        Log.d(TAG,
                "device max volume = "
                        + mAudioManager.getStreamMaxVolume(stream)
                        + " for streamType " + stream);
        Log.d(TAG, "playing sound " + uri.toString()
                + " with device local volume " + deviceLocalVolume);

        final int oldVolume = mAudioManager.getStreamVolume(stream);

        // set the volume to what we want it to be. In this case it's max volume
        // for the alarm stream.
        Log.d(Constants.APP_TAG, "setting device local volume to " + deviceLocalVolume);
        mAudioManager.setStreamVolume(stream, deviceLocalVolume,
                AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);

         final MediaPlayer mediaPlayer = new MediaPlayer();
         golbalMMediaPlayer = mediaPlayer;

        try {
             final OnPreparedListener OnPreparedListener = new OnPreparedListener() {

                @Override
                public void onPrepared(final MediaPlayer mp) {
                    Log.d(TAG, "onMediaPlayercompletion listener");
                    mp.start();
                    countDownTimer.start();
                }
            };

            mediaPlayer.setDataSource(context.getApplicationContext(), uri);
            mediaPlayer.setAudioStreamType(stream);
            mediaPlayer.setLooping(false);
            mediaPlayer.setOnPreparedListener(OnPreparedListener);
            mediaPlayer.setOnCompletionListener(new OnCompletionListener() {

                @Override
                public void onCompletion(MediaPlayer mp) {
                    Log.d(Constants.APP_TAG, "Entered onCompletion listener of mediaplayer");
                    mAudioManager.setStreamVolume(stream, oldVolume,
                            AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
                    try{
                    if(mediaPlayer != null && mediaPlayer.isPlaying()){
                        mediaPlayer.release();
                    }
                    }catch(Exception ex){
                        Log.e(Constants.APP_TAG, "error on oncompletion listener" ,ex);
                    }
                }

            });

             CountDownTimer timer = new CountDownTimer(maxTime*1000, tickTime*1000) {

                @Override
                public void onTick(long millisUntilFinished) {
                    Log.d(TAG, "tick while playing sound ");
                }

                @Override
                public void onFinish() {
                    Log.d(TAG, "timer finished");
                    stopPlaying();
                }
            };

            countDownTimer = timer;

            mediaPlayer.prepareAsync();

        } catch (Exception e) {
            Log.e(TAG, "problem while playing sound", e);
        } finally {

        }
    }

LOGS:

:07-01 00:00:00.030: D/beephourly(9500): device max volume = 7 for streamType 5
07-01 00:00:00.030: D/beephourly(9500): playing sound content://media/internal/audio/media/166 with device local volume 7
07-01 00:00:00.030: D/beephourly(9500): setting device local volume to 7
07-01 00:00:00.080: D/beephourly(9500): vibrating with pattern = [J@428bae20
07-01 00:00:00.090: D/beephourly(9500): will show normal notification
07-01 00:00:00.100: D/beephourly(9500): notification is enabled
07-01 00:00:00.100: D/usersettings(9500): hr = 0
07-01 00:00:00.110: D/beephourly(9500): onMediaPlayercompletion listener
07-01 00:00:00.451: D/beephourly(9500): tick while playing sound 
07-01 00:00:20.460: D/beephourly(9500): timer finished
07-01 00:00:20.460: D/beephourly(9500): got request to stop playing
07-01 00:00:20.460: D/beephourly(9500): cancelling countdowntimer
07-01 00:00:20.460: D/beephourly(9500): releasing mediaplayer now
John Powell
  • 12,253
  • 6
  • 59
  • 67
user93796
  • 18,749
  • 31
  • 94
  • 150
  • Have you tried in some other devices ICS+ as well? – Pr38y Jul 08 '14 at 09:44
  • That call to setStreamVolume looks suspicous. Can you validate your device's volume settings and then remove the call to `mAudioManager.setStreamVolume`? – selbie Jul 09 '14 at 06:18
  • i have also problem with ics before following [this](http://www.androidhive.info/2012/03/android-building-audio-player-tutorial/) example it will work for you. – bhavesh kaila Jul 09 '14 at 08:55

6 Answers6

9

Try this :

Playing sound

public class PlaySound extends Activity implements OnTouchListener {
  private SoundPool soundPool;
  private int soundID;
  boolean loaded = false;


/** Called when the activity is first created. */

@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  View view = findViewById(R.id.textView1);
  view.setOnTouchListener(this);
  // Set the hardware buttons to control the music
  this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
  // Load the sound
  soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
  soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {

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

  }

 @Override
 public boolean onTouch(View v, MotionEvent event) {
  if (event.getAction() == MotionEvent.ACTION_DOWN) {
  // Getting the user sound settings
  AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
  float actualVolume = (float) audioManager
      .getStreamVolume(AudioManager.STREAM_MUSIC);
  float maxVolume = (float) audioManager
      .getStreamMaxVolume(AudioManager.STREAM_MUSIC);
  float volume = actualVolume / maxVolume;
  // Is the sound loaded already?
  if (loaded) {
    soundPool.play(soundID, volume, volume, 1, 0, 1f);
    Log.e("Test", "Played sound");
  }
}
 return false;
}
} 

Layout file :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TextView
    android:id="@+id/textView1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:text="Click on the screen to start playing" >
</TextView>

</LinearLayout> 

Source link : http://www.vogella.com/tutorials/AndroidMedia/article.html#sound

Siddharth_Vyas
  • 9,972
  • 10
  • 39
  • 69
1

Sometimes MediaPlayer objects have to be declared as a public variable or they will be deleted by the Dalvik Heap.

public final MediaPlayer mediaPlayer = new MediaPlayer();
ByteBit
  • 333
  • 1
  • 9
1
private MediaPlayer mPlayer;
....
SoundPool sp = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
    int iTmp = sp.load(getBaseContext(), R.raw.windows_8_notify, 1); 
    sp.play(iTmp, 1, 1, 0, 0, 1);
    mPlayer = MediaPlayer.create(getBaseContext(), R.raw.windows_8_notify);
    mPlayer.start();
    mPlayer.setLooping(true); }

First , where all your privates are , before the onCreate, put the first line, then, Inside the onCreate start the music, just make sure to change the "windows_8_notify" to the name of the song you want.

DavidBalas
  • 333
  • 7
  • 21
1

I would Wrap the call in an IllegalStateException, run it through the debugger and see what you get.

Things to try

  1. Set the boolean isPlaying=mp.isPlaying(); and check its value.

  2. Try a mp.reset() before starting and see if it works.

  3. Implement MediaPlayer.OnErrorListener and register the method with the media player.

See what error you get. This might be helpful.

Community
  • 1
  • 1
SeahawksRdaBest
  • 868
  • 5
  • 17
1

LOGS
...streamType 5

StreamType 5 means STREAM_NOTIFICATION.
(Called from notification?)

It should be STREAM_MUSIC (3)


To check it's not ICS/device specific problem,
- place a sound file (sound_01.ogg or sound_01.mp3) under res/raw/ folder
- place buttons named start_button and stop_button in main_layout
and try this.
(I've checked this code with API10 and API19 emulator and sounds are played.)

import android.app.Activity;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;

public class MainActivity extends Activity
// implements MediaPlayer.OnPreparedListener
{
    private MediaPlayer mediaPlayer;
    private boolean isPrepared;
    private boolean isPlaying;

    private View start_button;
    private View stop_button;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_layout);
        Init();
    }

    @Override
    protected void onResume()
    {
        super.onResume();
        Load();
    }

    @Override
    protected void onPause()
    {
        super.onPause();
        Unload();
    }

    private void Init()
    {
        setVolumeControlStream(AudioManager.STREAM_MUSIC);

        start_button = findViewById(R.id.start_button);
        stop_button = findViewById(R.id.stop_button);

        start_button.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                Play();
            }
        });
        stop_button.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                Stop();
            }
        });
    }

    private void Load()
    {
        Unload();

        // load from resource (res/raw/xx.ogg or .mp3)
        // It's better to use thread
        mediaPlayer = MediaPlayer.create(MainActivity.this, R.raw.sound_01); // On success, prepare() will already have been called
        // mediaPlayer.setOnPreparedListener(this); // cannot set this listener (MediaPlayer.create does not return before prepared)
        isPrepared = true;
    }

    private void Unload()
    {
        isPrepared = false;
        if (null != mediaPlayer)
        {
            mediaPlayer.release();
            mediaPlayer = null;
        }
    }

    // @Override
    // public void onPrepared(MediaPlayer mp)
    // {
    // isPrepared = true;
    // }

    private void Play()
    {
        // If you got "start called in state xx" error, no sound will be heard.
        // To reset this error, call reset(), setDataSource() and prepare()
        // (for resources: call release() and create())
        if (!isPrepared)
        {
            return;
        }
        mediaPlayer.start();
        isPlaying =  true;
    }

    private void Stop()
    {
        // Do not omit this check
        // or you will get "called in wrong state" errors
        // like "pause called in state 8"   
        // and error (-38, 0)
        if (!isPlaying)
        {
            return;
        }
        isPlaying = false;
        mediaPlayer.pause();
        mediaPlayer.seekTo(0);
    }
}

If it's ICS/device specific, these links may help. (A little old...)

Toris
  • 2,348
  • 13
  • 16
  • :Thanks for replying. Previously i was using stream type 3, now am using 5 but still facing same issue.OTE : This code is triggered by a broadcast receiver. BroadCast receiver invokes a async task.In the post process method of asycn task playSound method is called.This issues is strange.Can you please help – user93796 Aug 04 '14 at 15:20
0

You might have a problem if you are using other AsyncTasks or the SerialExecutor in another task elsewhere in your program (and you may not even know it if you are using third party SDK's).

See the post here:

https://code.google.com/p/android/issues/detail?id=20941

I'm suggesting this because your sound "tick" isn't working either. So it isn't a matter of AudioPlayer executing with an incorrect setting necessarily, but rather some other task appears to be blocking it until that task stops, and it probably is a task that runs concurrently with when you expect to hear sound.

Jim
  • 10,172
  • 1
  • 27
  • 36