Search code examples
androidmedia-playerseekbar

Seek bar and media player and a time of a track


In my media player (mp3) there is a seek bar. To play the next song i am using this logic:

if (seek bar progress == mediaplayerObject.getDuration())

if yes play the next song

but this condition does not work, because there is a small mili second gap between the full seek bar progress and mediaplayerObject.getDuration() value that difference is not static it changes. I think it comes because of the processing time delays though. If I can use a condition like if seek bar progress is 100% I can use that, but I tried it does not seems working

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.SeekBar;
import android.widget.TextView;

public class AndroidMediaPlayerExample extends Activity {

    private MediaPlayer mediaPlayer;
    public TextView songName, duration;
    private double timeElapsed = 0, finalTime = 0;
    private int forwardTime = 2000, backwardTime = 2000;
    private Handler durationHandler = new Handler();
    private SeekBar seekbar;
    private Field[] fields;
    private String name;
    private int resourceID;
    private List<String> songNames;
    private int nameIntRandom;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //set the layout of the Activity
        setContentView(R.layout.activity_main);
        songNames = new ArrayList();
        //initialize views
        initializeViews();



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

            //  seekBar.setMax(mediaPlayer.getDuration());

                System.out.println("progress"+ (progress));
                System.out.println("progress final - "+ finalTime);

                if(progress == finalTime){
                    System.out.println("progress 100 compleated ");
                }

            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
    }


    public void initializeViews(){
        listRaw();
        songName = (TextView) findViewById(R.id.songName);

        nameIntRandom = Integer.parseInt(songNames.get(2));


        mediaPlayer = MediaPlayer.create(this, nameIntRandom);
        finalTime = mediaPlayer.getDuration();


        duration = (TextView) findViewById(R.id.songDuration);
        seekbar = (SeekBar) findViewById(R.id.seekBar);
        songName.setText("Sample_Song.mp3");

        seekbar.setMax((int) finalTime);
        seekbar.setClickable(false);
    }

    // play mp3 song
    public void play(View view) {
        System.out.println("AndroidMediaPlayerExample play");
        mediaPlayer.start();
        timeElapsed = mediaPlayer.getCurrentPosition();
        seekbar.setProgress((int) timeElapsed);
        durationHandler.postDelayed(updateSeekBarTime, 100);
    }

    //handler to change seekBarTime
    private Runnable updateSeekBarTime = new Runnable() {
        public void run() {
            //get current position
            timeElapsed = mediaPlayer.getCurrentPosition();
            //set seekbar progress
            seekbar.setProgress((int) timeElapsed);
            //set time remaing
            double timeRemaining = finalTime - timeElapsed;
            duration.setText(String.format("%d min, %d sec", TimeUnit.MILLISECONDS.toMinutes((long) timeRemaining), TimeUnit.MILLISECONDS.toSeconds((long) timeRemaining) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes((long) timeRemaining))));

            //repeat yourself that again in 100 miliseconds
            durationHandler.postDelayed(this, 100);
        }
    };

    // pause mp3 song
    public void pause(View view) {
        mediaPlayer.pause();
    }

    // go forward at forwardTime seconds
    public void forward(View view) {
        //check if we can go forward at forwardTime seconds before song endes
        if ((timeElapsed + forwardTime) <= finalTime) {
            timeElapsed = timeElapsed + forwardTime;

            //seek to the exact second of the track
            mediaPlayer.seekTo((int) timeElapsed);
        }

    }

    public void listRaw() {

        fields = R.raw.class.getFields();
        for (int count = 0; count < fields.length; count++) {
            Log.i("Raw Asset: ", fields[count].getName());

            System.out.println("length .... " + fields[count].getName());

            try {
                System.out.println("trytrytrytry");
                resourceID = fields[count].getInt(fields[count]);
                System.out.println("resourceIDresourceID " + resourceID);
                name = String.valueOf(resourceID);
                songNames.add(name);
                System.out.println("songNames.size();" +songNames.size());
                songNames.size();

            } catch (IllegalAccessException e) {
                e.printStackTrace();
                System.out.println("catch" + e);
            }
        }

        System.out.println("resourceIDresourceID---------lastone " + resourceID);

        System.out.println("resourceIDresourceID---------set " + fields.toString());
    }


    // go backwards at backwardTime seconds
    public void rewind(View view) {
        //check if we can go back at backwardTime seconds after song starts
        if ((timeElapsed - backwardTime) > 0) {
            timeElapsed = timeElapsed - backwardTime;

            //seek to the exact second of the track
            mediaPlayer.seekTo((int) timeElapsed);
        }
    }

}

Currently mp3 arraylist id is hardcodeed

XML here

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center"
    android:background="#333333"
    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" >

    <TextView
        android:id="@+id/songName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="songName" />

    <ImageView
        android:id="@+id/mp3Image"
        android:layout_width="match_parent"
        android:layout_height="200dp"
         android:padding="30dp"
        android:src="@drawable/music"
        android:background="#ffffff"
        android:layout_margin="30dp" />

    <TextView
        android:id="@+id/songDuration"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="songDuration" />

    <SeekBar
        android:id="@+id/seekBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="30dp"
        android:gravity="center_horizontal"
        android:orientation="horizontal" >

        <ImageButton
            android:id="@+id/media_rew"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="14dp"
            android:onClick="rewind"
            android:src="@android:drawable/ic_media_rew" />

        <ImageButton
            android:id="@+id/media_pause"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="14dp"
            android:onClick="pause"
            android:src="@android:drawable/ic_media_pause" />

        <ImageButton
            android:id="@+id/media_play"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="14dp"
            android:onClick="play"
            android:src="@android:drawable/ic_media_play" />

        <ImageButton
            android:id="@+id/media_ff"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="14dp"
            android:onClick="forward"
            android:src="@android:drawable/ic_media_ff" />
    </LinearLayout>

</LinearLayout>

Solution

  • Found the answer, below i calculate timeElapsed ,set seekbar progress,calculate remaining time & display time already played in mins and seconds

    I used this method

    Ps : done this in 2015, no time to review code but explaining what i did.

    Runnable -This interface is designed to provide a common protocol for objects that wish to execute code while they are active.Being active simply means that a thread has been started and has not yet been stopped.

    varibales -

    1. timeElapsed - time of the clip that already played
    2. finalTime - relevant media player clip object's time
    3. duration -String that i used to display timeElapsed in minutes and seconds
    4. timeRemaining - remaining time to play the clip

    .

        private Runnable updateSeekBarTime = new Runnable() {
                public void run() {
    
                    //get current position
                    timeElapsed = mediaPlayer.getCurrentPosition();
    
                    //set seekbar progress using time played
                    seekbar.setProgress((int) timeElapsed);
    
                    //set time remaining in minutes and seconds 
                    timeRemaining = finalTime - timeElapsed;
                    duration.setText(String.format("%d min, %d sec", TimeUnit.MILLISECONDS.toMinutes((long) timeRemaining), TimeUnit.MILLISECONDS.toSeconds((long) timeRemaining) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes((long) timeRemaining))));
    
                    //holding time for 100 miliseconds
                    durationHandler.postDelayed(this, 100);
                }
            };
    

    so i can check timeRemaining == 0

    and yes there is a method in media player mediaPlayer.isPlaying() <--- but i didnt use this