Android Media Tutorial and Examples


Android MediaPlayer Tutorial and Examples.

Here we want to explore some examples regarding the MediaPlayer class.

Android Simple ListView MP3 Player Example

In this example we want to see how to create a simple MP3 Player using ListView and MediaPlayer class. We load mp3 files from our external storage and show them in a simple listview. We do this recursively so that we don't miss songs found in sub-directories. We display the song names in a ListView.

Then when the user clicks a single song in our ListView, we open a new activity, a Player activity and automatically play the song. We will be passing the song path to that activity. Then we use the MediaPlayer class to play the song.

As we play the song we display the a Lottie Animation. When the user will click the back button of our Player Activity, we will continue playing the song. In fact even if we open a new app, that is our app is paused we still continue playing the song.

Android ListView MP3 Player

Android ListView MP3 Player

Video Tutorial

If you prefer a video tutorial then we have one here:

1. MainActivity.java

Here's our MainActivity. The main responsibility of this class is to show our ListView of MP3 songs. To turn it into an Activity we derive from the android.app.Activity class.

Among our imports include the java.io.File as we are reading the file system. Please make sure you add the READ_EXTERNAL_STORAGE permission in your android manifest. We also have the android.os.AsyncTask, a class that allows us implement basic threading. In this case we create a simple asynctask to read our songs in the background. We've called it the SongsLoaderAsyncTask. AsyncTask is an abstract class so we have to atleast override the doInBackground method. The android.widget.ProgressBar allows us show an indeterminate progressbar as we read our songs into the listview.

android.widget.ListView is our list component. android.widget.ArrayAdapter will be enough for us to adapt our simple data to our listview.

package info.camposha.mrmp3player;

import android.app.Activity;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.Toast;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends Activity {

    private ListView listview;
    private String mediaPath;
    private List<String> songs = new ArrayList<String>();
    private MediaPlayer mediaPlayer = new MediaPlayer();
    private SongsLoaderAsyncTask task;
    ProgressBar songsLoadingProgressBar;
    ArrayList<String> songNames=new ArrayList<>();

    /**
     * We will scan and load all mp3 files in a background thread via asynctask.
     */
    // Use AsyncTask to read all mp3 file names
    private class SongsLoaderAsyncTask extends AsyncTask<Void, String, Void> {
        private List<String> loadedSongs = new ArrayList<String>();

        /**
         * Before our background starts
         */
        protected  void onPreExecute() {
            songsLoadingProgressBar.setVisibility(View.VISIBLE);
            songNames.clear();
            Toast.makeText(getApplicationContext(),"Scanning Songs..Please Wait.",Toast.LENGTH_LONG).show();
        }

        /**
         * Load files in background thread here
         * @param url
         * @return
         */
        protected Void doInBackground(Void... url) {
            updateSongListRecursive(new File(mediaPath));
            return null;
        }

        /**
         * Recursively Load Files From ExternalStorage
         * @param path
         */
        public void updateSongListRecursive(File path) {
            if (path.isDirectory()) {
                for (int i = 0; i < path.listFiles().length; i++) {
                    File file = path.listFiles()[i];
                    updateSongListRecursive(file);
                }
            } else {
                String songPath = path.getAbsolutePath();
                String songName=path.getName();
                publishProgress(songPath);
                if (songPath.endsWith(".mp3")) {
                    loadedSongs.add(songPath);
                    songNames.add(songName.substring(0,songName.length()-4));
                }
            }
        }

        /**
         * When our background work is over.
         * @param args
         */
        protected void onPostExecute(Void args) {
            songsLoadingProgressBar.setVisibility(View.GONE);
            ArrayAdapter<String> songList =  new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, songNames);
            listview.setAdapter(songList);
            songs = loadedSongs;
            Toast.makeText(getApplicationContext(),"Scanning Complete."+songs.size()+" Songs Found.",Toast.LENGTH_LONG).show();
        }
    }

    /*
     *OPEN PLAYER ACTIVITY PASSING THE SONG TO PLAYER
     */
    private void openPlayerActivity(int position)
    {
        Intent i=new Intent(this,PlayerActivity.class);
        i.putExtra("SONG_KEY",songs.get(position));
        startActivity(i);
    }

    /**
     * When the activity is created.
     * @param savedInstanceState
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        songsLoadingProgressBar=findViewById(R.id.myProgressBar);
        listview = findViewById(R.id.mListView);
        mediaPath = Environment.getExternalStorageDirectory().getPath() + "/Music/";
        //mediaPath = Environment.getExternalStorageDirectory().getPath() + "/Download/";
        //mediaPath = Environment.getExternalStorageDirectory().getPath() + "/mnt/shared/Other/";
        //mediaPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getPath() ;
        //mediaPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath() ;
        // itemclick listener for our listview
        listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                openPlayerActivity(position);
            }
        });
        //instantiate and execute our asynctask
        task = new SongsLoaderAsyncTask();
        task.execute();

    }

    /** Called when the activity is stopped */
    @Override
    public void onStop() {
        super.onStop();
        if (mediaPlayer.isPlaying()) mediaPlayer.reset();
    }

}

2. PlayerActivity.java

Here's our PlayerActivity. This activity will play our song. As we play the song we will use the LottieAnimationView to play our animation. Obviously MediaPlayer is the class responsible for playing our mp3 files.

package info.camposha.mrmp3player;

import android.app.Dialog;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.media.MediaPlayer;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import com.airbnb.lottie.LottieAnimationView;

import java.io.IOException;

public class PlayerActivity extends AppCompatActivity {

    private MediaPlayer mediaPlayer = new MediaPlayer();

    TextView songTxt;
    LottieAnimationView rippleAnimation;
    String songToPlay;

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

        initializeViews();
        receiveSong();
        playSong();
    }

    /**
     * Initialize widgets
     */
    private void initializeViews(){
        songTxt=findViewById(R.id.songTxt);
        rippleAnimation = findViewById(R.id.lottieloading);

    }
    private void receiveSong(){

        //receive passed song via intent
        Intent i=this.getIntent();
        songToPlay=i.getStringExtra("SONG_KEY");
    }

    private void playSong(){
        //TextView to display the song name
        songTxt.setText(songToPlay);

        if(TextUtils.isEmpty(songToPlay))
        {
            Toast.makeText(this, "Hey PlayerActivity has received a null or empty song.", Toast.LENGTH_LONG).show();
        }
        else{
            try {
                mediaPlayer.reset();
                // in recursive version
                mediaPlayer.setDataSource(songToPlay);
                mediaPlayer.prepare();
                mediaPlayer.start();

            } catch(IOException e) {
                Toast.makeText(getBaseContext(), "Cannot Play Song!", Toast.LENGTH_SHORT).show();

            }
        }
        showSplash();
    }

    public void showSplash() {
        if (mediaPlayer.isPlaying()) {
            rippleAnimation.setAnimation(R.raw.ripple);
            rippleAnimation.playAnimation();
        } else {
            rippleAnimation.pauseAnimation();
        }
    }

    /** Called when the activity is stopped */
    @Override
    public void onStop() {
        super.onStop();
        //if you want to stop playing when this activity is closed then uncomment this.
//        if (mediaPlayer.isPlaying()){
//            mediaPlayer.reset();
//            rippleAnimation.pauseAnimation();
//        }
    }

}

3. activity_main.xml

This is the layout to be used as the user interface for MainActivity. First it will contain a header textview to display our header text. Then below it we have a ListView to render our data in a list. We arrange them linearly using a LinearLayout with vertical orientation.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/headerTxt"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="5dp"
        android:text="ListView MP3 Player"
        android:textAlignment="center"
        android:textAppearance="@style/TextAppearance.AppCompat.Large"
        android:textColor="@color/colorAccent"
        android:textStyle="bold" />

    <ProgressBar
        android:id="@+id/myProgressBar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:indeterminate="true"
        android:indeterminateBehavior="cycle"
        android:visibility="gone" />

    <ListView
        android:id="@+id/mListView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>

4. activity_player.xml

This is the layout responsible for showing our LottieAnimationView. We will be showing an animation as our song plays. We wrap a TextView and LottieAnimationView inside a RelativeLayout.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/activity_mp3_player"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:background="#25272d"
    tools:context="info.camposha.mrmp3player.PlayerActivity">

    <TextView
        android:id="@+id/songTxt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:textColor="@android:color/white"
        android:textSize="10sp"
        android:text="Rock With You"
        android:layout_marginTop="50dp"/>

    <com.airbnb.lottie.LottieAnimationView
        android:id="@+id/lottieloading"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:lottie_loop="true" />

</RelativeLayout>

5. AndroidManifest.xml

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

How do You Feel after reading this?

According to scientists, we humans have 8 primary innate emotions: joy, acceptance, fear, surprise, sadness, disgust, anger, and anticipation. Feel free to tell us how you feel about this article using these emotes or via the comment section. This feedback helps us gauge our progress.

Help me Grow.

I set myself some growth ambitions I desire to achieve by this year's end regarding this website and my youtube channel. Am halfway. Help me reach them by:




Recommendations


What do You Think


Previous Post Next Post