Wednesday, June 6, 2012

Play "audio/mp3" with MediaPlayer

Updated@2016-05-03:NOT WORK NOW
Refer "Intent.ACTION_GET_CONTENT to open mp3, play using MediaPlayer, tested on Android 5.1 Lollipop"



android.media.MediaPlayer can be used to control playback of audio/video files and streams.

Modify last exercise "Start Intent to choice 'audio/mp3' using installed app" to retrieve the selected file using MediaPlayer.

Play 'audio/mp3' with MediaPlayer


Playback control of audio/video files and streams is managed as a state machine.(Refer to the State Diagram), we have to check the Valid and invalid states. Currently, there are no API to retrieve the current state of our MediaPlayer. So we implement our state machine (partially) and mediaPlayerState in our code.

package com.exercise.AndroidPlayer;

import java.io.IOException;

import android.app.Activity;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnErrorListener;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class AndroidPlayerActivity extends Activity {
 
 TextView info, state;
 Button buttonOpen;
 Button buttonPlay, buttonPause, buttonStop;
 
 final static int RQS_OPEN_AUDIO_MP3 = 1;
 
 MediaPlayer mediaPlayer;
 String srcPath = null;
 enum MP_State {
     Idle, Initialized, Prepared, Started, Paused, 
     Stopped, PlaybackCompleted, End, Error, Preparing}
     
 MP_State mediaPlayerState;
 
 String[] stringState = {
   "Idle", 
   "Initialized", 
   "Prepared", 
   "Started", 
   "Paused", 
      "Stopped", 
      "PlaybackCompleted", 
      "End", 
      "Error", 
      "Preparing"
 };
 
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        buttonOpen = (Button)findViewById(R.id.open);
        buttonOpen.setOnClickListener(buttonOpenOnClickListener);
        
        info = (TextView)findViewById(R.id.info);
        state = (TextView)findViewById(R.id.state);
        
        buttonPlay = (Button)findViewById(R.id.play);
        buttonPlay.setOnClickListener(buttonPlayOnClickListener);
        buttonPause = (Button)findViewById(R.id.pause);
        buttonPause.setOnClickListener(buttonPauseOnClickListener);
        buttonStop = (Button)findViewById(R.id.stop);
        buttonStop.setOnClickListener(buttonStopOnClickListener);
        
    }
    
    OnErrorListener mediaPlayerOnErrorListener
    = new OnErrorListener(){

  @Override
  public boolean onError(MediaPlayer mp, int what, int extra) {
   // TODO Auto-generated method stub
   
   mediaPlayerState = MP_State.Error;
   showMediaPlayerState();
   
   return false;
  }};
    
    
    private void cmdReset(){
     if (mediaPlayer == null){
      mediaPlayer = new MediaPlayer();
      mediaPlayer.setOnErrorListener(mediaPlayerOnErrorListener);
     }
     mediaPlayer.reset();
        mediaPlayerState = MP_State.Idle;
        showMediaPlayerState();
    }
    
    private void cmdSetDataSource(String path){
     if(mediaPlayerState == MP_State.Idle){
      try {
       mediaPlayer.setDataSource(path);
       mediaPlayerState = MP_State.Initialized;
      } catch (IllegalArgumentException e) {
       Toast.makeText(AndroidPlayerActivity.this, 
         e.toString(), Toast.LENGTH_LONG).show();
       e.printStackTrace();
      } catch (IllegalStateException e) {
       Toast.makeText(AndroidPlayerActivity.this, 
         e.toString(), Toast.LENGTH_LONG).show();
       e.printStackTrace();
      } catch (IOException e) {
       Toast.makeText(AndroidPlayerActivity.this, 
         e.toString(), Toast.LENGTH_LONG).show();
       e.printStackTrace();
      }
     }else{
      Toast.makeText(AndroidPlayerActivity.this, 
     "Invalid State@cmdSetDataSource - skip", 
     Toast.LENGTH_LONG).show();
     }

     showMediaPlayerState();
    }
    
    private void cmdPrepare(){
     
     if(mediaPlayerState == MP_State.Initialized
      ||mediaPlayerState == MP_State.Stopped){
      try {
       mediaPlayer.prepare();
       mediaPlayerState = MP_State.Prepared;
      } catch (IllegalStateException e) {
       Toast.makeText(AndroidPlayerActivity.this, 
         e.toString(), Toast.LENGTH_LONG).show();
       e.printStackTrace();
      } catch (IOException e) {
       Toast.makeText(AndroidPlayerActivity.this, 
         e.toString(), Toast.LENGTH_LONG).show();
       e.printStackTrace();
      }
     }else{
      Toast.makeText(AndroidPlayerActivity.this, 
     "Invalid State@cmdPrepare() - skip", 
     Toast.LENGTH_LONG).show();
     }

     showMediaPlayerState();
    }
    
    private void cmdStart(){
     if(mediaPlayerState == MP_State.Prepared
          ||mediaPlayerState == MP_State.Started
          ||mediaPlayerState == MP_State.Paused
          ||mediaPlayerState == MP_State.PlaybackCompleted){
      mediaPlayer.start();
      mediaPlayerState = MP_State.Started;
     }else{
      Toast.makeText(AndroidPlayerActivity.this, 
     "Invalid State@cmdStart() - skip", 
     Toast.LENGTH_LONG).show();
     }

  showMediaPlayerState();
    }
    
    private void cmdPause(){
     if(mediaPlayerState == MP_State.Started
          ||mediaPlayerState == MP_State.Paused){
      mediaPlayer.pause();
      mediaPlayerState = MP_State.Paused;
     }else{
      Toast.makeText(AndroidPlayerActivity.this, 
     "Invalid State@cmdPause() - skip", 
     Toast.LENGTH_LONG).show();
     }
  showMediaPlayerState();
    }
    
    private void cmdStop(){
  
  if(mediaPlayerState == MP_State.Prepared
    ||mediaPlayerState == MP_State.Started
    ||mediaPlayerState == MP_State.Stopped
          ||mediaPlayerState == MP_State.Paused
          ||mediaPlayerState == MP_State.PlaybackCompleted){
   mediaPlayer.stop();
   mediaPlayerState = MP_State.Stopped;
     }else{
      Toast.makeText(AndroidPlayerActivity.this, 
     "Invalid State@cmdStop() - skip", 
     Toast.LENGTH_LONG).show();
     }
  showMediaPlayerState();

    }
    
    private void showMediaPlayerState(){
     
     switch(mediaPlayerState){
     case Idle:
      state.setText("Idle");
      break;
     case Initialized:
      state.setText("Initialized");
      break;
     case Prepared:
      state.setText("Prepared");
      break;
     case Started:
      state.setText("Started");
      break;
     case Paused:
      state.setText("Paused");
      break;
     case Stopped:
      state.setText("Stopped");
      break;
     case PlaybackCompleted:
      state.setText("PlaybackCompleted");
      break;
     case End:
      state.setText("End");
      break;
     case Error:
      state.setText("Error");
      break;
     case Preparing:
      state.setText("Preparing");
      break;
     default:
      state.setText("Unknown!");
     }
    }
    
    OnClickListener buttonPlayOnClickListener
    = new OnClickListener(){

  @Override
  public void onClick(View v) {
   
   if(srcPath == null){
    Toast.makeText(AndroidPlayerActivity.this, 
      "No file selected", 
      Toast.LENGTH_LONG).show();
   }else{
    cmdPrepare();
    cmdStart();
   }

  }
     
    };
    
    OnClickListener buttonPauseOnClickListener
    = new OnClickListener(){

  @Override
  public void onClick(View v) {
   cmdPause();
  }
     
    };
    
    OnClickListener buttonStopOnClickListener
    = new OnClickListener(){

  @Override
  public void onClick(View v) {
   
   cmdStop();
   
  }
     
    };
    
    OnClickListener buttonOpenOnClickListener
    = new OnClickListener(){

  @Override
  public void onClick(View arg0) {
   Intent intent = new Intent();
   intent.setType("audio/mp3");
   intent.setAction(Intent.ACTION_GET_CONTENT);
   startActivityForResult(Intent.createChooser(
     intent, "Open Audio (mp3) file"), RQS_OPEN_AUDIO_MP3);

  } 
    };

 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  if (resultCode == RESULT_OK) {
   if (requestCode == RQS_OPEN_AUDIO_MP3) {
    Uri audioFileUri = data.getData();
    
    srcPath = audioFileUri.getPath();
    info.setText(srcPath);
    
    cmdReset();
    
    cmdSetDataSource(srcPath);
   } 
  } 
 }

}


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

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />
    <Button
        android:id="@+id/open"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Open MP3 file" />
    <TextView
        android:id="@+id/info"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
    <Button
        android:id="@+id/play"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Play" />
    <Button
        android:id="@+id/pause"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Pause" />
    <Button
        android:id="@+id/stop"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Stop" />
    <TextView
        android:id="@+id/state"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />

</LinearLayout>


Download the files.

Next:
- Display playing time for MediaPlayer


No comments: