How can I show a MediaController while playing audio in Android?

How can I show a MediaController while playing audio file? I am creating an instance of MediaController and calling its show() method, but it is not showing. Can any help me in sorting out this issue?


Solution 1:

Here is an example of an Activity that uses MediaPlayer and MediaController to play audio.

import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;

import android.media.MediaPlayer.OnPreparedListener;
import android.view.MotionEvent;
import android.widget.MediaController;
import android.widget.TextView;

import java.io.IOException;

public class AudioPlayer extends Activity implements OnPreparedListener, MediaController.MediaPlayerControl{
  private static final String TAG = "AudioPlayer";

  public static final String AUDIO_FILE_NAME = "audioFileName";

  private MediaPlayer mediaPlayer;
  private MediaController mediaController;
  private String audioFile;

  private Handler handler = new Handler();

  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.audio_player);

    audioFile = this.getIntent().getStringExtra(AUDIO_FILE_NAME);
    ((TextView)findViewById(R.id.now_playing_text)).setText(audioFile);

    mediaPlayer = new MediaPlayer();
    mediaPlayer.setOnPreparedListener(this);

    mediaController = new MediaController(this);

    try {
      mediaPlayer.setDataSource(audioFile);
      mediaPlayer.prepare();
      mediaPlayer.start();
    } catch (IOException e) {
      Log.e(TAG, "Could not open file " + audioFile + " for playback.", e);
    }

  }

  @Override
  protected void onStop() {
    super.onStop();
    mediaController.hide();
    mediaPlayer.stop();
    mediaPlayer.release();
  }

  @Override
  public boolean onTouchEvent(MotionEvent event) {
    //the MediaController will hide after 3 seconds - tap the screen to make it appear again
    mediaController.show();
    return false;
  }

  //--MediaPlayerControl methods----------------------------------------------------
  public void start() {
    mediaPlayer.start();
  }

  public void pause() {
    mediaPlayer.pause();
  }

  public int getDuration() {
    return mediaPlayer.getDuration();
  }

  public int getCurrentPosition() {
    return mediaPlayer.getCurrentPosition();
  }

  public void seekTo(int i) {
    mediaPlayer.seekTo(i);
  }

  public boolean isPlaying() {
    return mediaPlayer.isPlaying();
  }

  public int getBufferPercentage() {
    return 0;
  }

  public boolean canPause() {
    return true;
  }

  public boolean canSeekBackward() {
    return true;
  }

  public boolean canSeekForward() {
    return true;
  }
  //--------------------------------------------------------------------------------

  public void onPrepared(MediaPlayer mediaPlayer) {
    Log.d(TAG, "onPrepared");
    mediaController.setMediaPlayer(this);
    mediaController.setAnchorView(findViewById(R.id.main_audio_view));

    handler.post(new Runnable() {
      public void run() {
        mediaController.setEnabled(true);
        mediaController.show();
      }
    });
  }
}

Here is a layout that can be used with the code above:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:id="@+id/main_audio_view"
              android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:layout_gravity="center"
              android:orientation="vertical">
  <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:text="Now playing:"
    android:textSize="25sp"
    android:textStyle="bold"
    />
  <TextView
    android:id="@+id/now_playing_text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="20dip"
    android:layout_marginLeft="10dip"
    android:layout_marginRight="10dip"
    android:layout_gravity="center"
    android:text="Now playing.."
    android:textSize="16sp"
    android:textStyle="italic"
    />
</LinearLayout>

Solution 2:

I still don't have enough rep to Comment so i have to just post this as an answer.

@user229487's answer

you need to add mediaController.hide(); to the onStop() method. If you don't do this and you happen to rotate the window or close the window while it is showing you will get a Activity x has leaked window error

New method should look like this

@Override
protected void onStop() {
    super.onStop();
    mediaController.hide();
    mediaPlayer.stop();
    mediaPlayer.release();
}

Solution 3:

I copied the code above from user229487 verbatim but couldn't get it to work. Given I'm new to Android dev, I found out the hard way that you need to put an intent as well as a few other things. I also don't exactly understand how the intent will work with a user interface (again I'm new), but will work on it.

Few things for other noobs like me to get the code above to work (I at least got it to not crash now and play a song :) ):

  • Won't compile without this:

    @Override
    public int getAudioSessionId() {
    return 0;
    }

  • To set audio manually: (change line to:)

    public static final String AUDIO_FILE_NAME = Environment.getExternalStorageDirectory()+"/MusicFolder/Song.mp3";

  • Setup intent
    Add this line: this.getIntent().putExtra(AUDIO_FILE_NAME,AUDIO_FILE_NAME);
    Before this line: audioFile = this.getIntent().getStringExtra(AUDIO_FILE_NAME);

Should compile and play song now.