Creating A Basic Android Music Player App Using MediaPlayer

This tutorial is for beginners in Android development, who intend to explore the exciting field of mobile app development and chose to begin with Android.

Following through this tutorial we will create two activities

  1. MusicPlayerActivity: To play the audio files
  2. MusicListActivity: To list all the audio files in our internal memory of the Android device

It’s very obvious for a beginner in Android development to wonder, what is an activity? In the most simple way: It is a page or screen of your application.

Remember how the screen changes when you the navigate through an android app? You are actually switching through “activities” while navigating (or fragments, which are components of an activity).

Since we want two screens in our application, we are going to create two activities as listed above.

Every activity has a xml file and a java class. The XML file is used to define the layout (look and feel) of the activity and the Java class contains code to make it interactive/dynamic. With this basic knowledge lets proceed to create our first activity.

At first glance the code below may look a bit scary for someone just starting Android development, but that’s universal so you need not to worry. We will explain each part of the code and its purpose, later in this blog.

MusicPlayerActivity

XML Layout: activity_music_player.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MusicPlayerActivity">

<Button
android:id="@+id/playBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Play"
tools:layout_editor_absoluteX="147dp"
tools:layout_editor_absoluteY="230dp" />

<TextView
android:id="@+id/audioName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="480dp"
android:text="TextView"
tools:layout_editor_absoluteX="162dp"
tools:layout_editor_absoluteY="178dp" />

<SeekBar
android:id="@+id/seekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="43dp" />

<Button
android:id="@+id/viewAllMedia"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/playBtn"
android:layout_alignStart="@+id/playBtn"
android:layout_marginStart="-21dp"
android:layout_marginTop="14dp"
android:text="View all media" />
</RelativeLayout>

JAVA class: MusicPlayerActivity.java

package com.hack4m.android.basicmusicplayer;

import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.media.MediaPlayer;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import java.util.Timer;
import java.util.TimerTask;

public class MusicPlayerActivity extends AppCompatActivity {

MediaPlayer mediaPlayer;
AudioModel audio;
SeekBar seekBar;

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

Intent intent = getIntent();
audio = (AudioModel) intent.getSerializableExtra("audio");

TextView audioName = findViewById(R.id.audioName);
Button playBtn = findViewById(R.id.playBtn);
Button viewAllMediaBtn = findViewById(R.id.viewAllMedia);

if(audio!=null){
audioName.setText(audio.getaName());
}else{
audioName.setText("Piano.wav");
}


playBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startPlaying();
}
});

viewAllMediaBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
stopPlaying();
startActivity(new Intent(getApplicationContext(),MusicListActivity.class));
//finish();
}
});

}

public void startPlaying(){
if(mediaPlayer!=null && mediaPlayer.isPlaying()){
mediaPlayer.stop();
}

if(audio!=null){

Toast.makeText(getApplicationContext(),"Playing from device; "+audio.getaPath(),Toast.LENGTH_SHORT).show();
mediaPlayer = MediaPlayer.create(MusicPlayerActivity.this, Uri.parse(audio.getaPath()));
mediaPlayer.start();

}else{

Toast.makeText(getApplicationContext(),"Playing from app",Toast.LENGTH_SHORT).show();
try {
AssetFileDescriptor afd = getAssets().openFd("piano.wav");
mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
afd.close();
mediaPlayer.prepare();
mediaPlayer.start();

} catch (Exception e) {
e.printStackTrace();
}
}

enableSeekBar();
}

public void stopPlaying(){
if(mediaPlayer!=null){
mediaPlayer.stop();
}
}

public void enableSeekBar(){
seekBar = findViewById(R.id.seekBar);
seekBar.setMax(mediaPlayer.getDuration());

new Timer().scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {

if(mediaPlayer!=null && mediaPlayer.isPlaying()){
seekBar.setProgress(mediaPlayer.getCurrentPosition());
}
}
}, 0, 10);


seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

// Update the progress depending on seek bar
if(fromUser){
mediaPlayer.seekTo(progress);
}

}

@Override
public void onStartTrackingTouch(SeekBar seekBar) {

}

@Override
public void onStopTrackingTouch(SeekBar seekBar) {

}
});
}

@Override
public void onBackPressed() {
stopPlaying();
super.onBackPressed();
}

}

MusicListActivity

This activity lists all the audio files in the internal memory of our Android device and we can select them to play in our MusicPlayerActivity.

XML layout: activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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"
tools:context=".MusicListActivity">

<android.support.v7.widget.RecyclerView
android:id="@+id/audioListView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.constraint.ConstraintLayout>

Java Class: MusicListActivity.java

package com.hack4m.android.basicmusicplayer;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

public class MusicListActivity extends AppCompatActivity {

RecyclerView audioListView;
AudioListAdapter audioListAdapter;
Context context;

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


//Checks permissions
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {

requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},1);
return;
}
}

//Finds all the mp3 files in device and makes a list
getSongs();

}

public void getSongs(){
context = MusicListActivity.this;
audioListView = findViewById(R.id.audioListView);

List allAudioFiles = getAllAudioFromDevice(context);

audioListAdapter = new AudioListAdapter(context,allAudioFiles);
audioListView.setLayoutManager(new LinearLayoutManager(context));
audioListView.setAdapter(audioListAdapter);
}

public List getAllAudioFromDevice(final Context context) {

final List tempAudioList = new ArrayList<>();

Uri uri = MediaStore.Audio.Media.INTERNAL_CONTENT_URI;
String[] projection = {MediaStore.Audio.AudioColumns.DATA, MediaStore.Audio.AudioColumns.ALBUM, MediaStore.Audio.ArtistColumns.ARTIST,};
Cursor c = context.getContentResolver().query(uri,
projection,
null,
null,
null);

if (c != null) {
while (c.moveToNext()) {

AudioModel audioModel = new AudioModel();

String path = c.getString(0);
String album = c.getString(1);
String artist = c.getString(2);

String name = path.substring(path.lastIndexOf("/") + 1);

audioModel.setaName(name);
audioModel.setaAlbum(album);
audioModel.setaArtist(artist);
audioModel.setaPath(path);

tempAudioList.add(audioModel);
}
c.close();
}

return tempAudioList;
}

//Handling callback
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case 1: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
getSongs();
Toast.makeText(context,"Permission granted",Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context,"Permission denied",Toast.LENGTH_SHORT).show();
}
}
}
}
}

This activity scans the internal memory of device and creates a list of audio files. We pass that list to the RecyclerView adapter (Create a List with RecyclerView ) which adds them in the RecyclerView and we can see the list on our screen.

XML design for a single row in the RecyclerView: audio_list_row.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<TextView
android:id="@+id/audioName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Placeholder"
android:padding="20dp"
android:layout_marginTop="3dp"
android:background="#fff"
android:layout_marginBottom="3dp" />

</android.support.constraint.ConstraintLayout>

The Adpater class: AudioListAdapter.java

package com.hack4m.android.basicmusicplayer;

import android.content.Context;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.List;

public class AudioListAdapter extends RecyclerView.Adapter {

private List audioDataSet;
private LayoutInflater mInflater;
Context mContext;

public AudioListAdapter(Context context, List audioModelList){

mInflater = LayoutInflater.from(context);
mContext = context;
audioDataSet = audioModelList;
}

@NonNull
@Override
public AudioViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
// create a new view
View v = mInflater.inflate(R.layout.audio_list_row, viewGroup, false);

AudioViewHolder vh = new AudioViewHolder(mContext,audioDataSet,v);
return vh;
}

@Override
public void onBindViewHolder(@NonNull AudioViewHolder audioViewHolder, int i) {
audioViewHolder.mTextView.setText(audioDataSet.get(i).getaName());
}

@Override
public int getItemCount() {
return audioDataSet.size();
}

public static class AudioViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
Context nContext;
List audioList;
public TextView mTextView;

public AudioViewHolder(Context context,List audioModelList, View v) {
super(v);
nContext = context;
audioList = audioModelList;
mTextView = v.findViewById(R.id.audioName);

v.setOnClickListener(this);
}

@Override
public void onClick(View view){

int itemPosition = getAdapterPosition();

Intent intent = new Intent(nContext,MusicPlayerActivity.class);
intent.putExtra("audio",audioList.get(itemPosition));

nContext.startActivity(intent);

}
}
}

And the last class in our app: AudioModel.java

package com.hack4m.android.basicmusicplayer;

import java.io.Serializable;

public class AudioModel implements Serializable {

String aPath;
String aName;
String aAlbum;
String aArtist;

public String getaPath() {
return aPath;
}

public void setaPath(String aPath) {
this.aPath = aPath;
}

public String getaName() {
return aName;
}

public void setaName(String aName) {
this.aName = aName;
}

public String getaAlbum() {
return aAlbum;
}

public void setaAlbum(String aAlbum) {
this.aAlbum = aAlbum;
}

public String getaArtist() {
return aArtist;
}

public void setaArtist(String aArtist) {
this.aArtist = aArtist;
}
}

That’s it, these are all the files we need to develop this basic audio player.

Try the code, comment if you run into any problem implementing the project.
 I will try to explain the code later by editing this blog, till then you have Google!

This project is open-source and hosted on GitHub: https://github.com/hack4mer/Android-BasicMusicPlayer.git


Originally published at Hack4m.