I've created a simple music player in Android which has a seekbar which displays the current position in the song playing. The forward, rewind, play and pause functions work correctly. What I am trying to do is have the seekbar actually move the position within the song. (at present the seekbar does not change the position within the song. Heres my code
public class MusicPlayerA extends Activity {
private MediaPlayer mediaPlayer;
public TextView songName, duration;
private double timeElapsed = 0, finalTime = 0;
private int forwardTime = 2500, backwardTime = 2500;
private Handler durationHandler = new Handler();
private SeekBar seekbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//set the layout of the Activity
setContentView(R.layout.musicplayerview);
//initialize views
initializeViews();
}
#Override
protected void onPause() {
super.onPause();
if (mediaPlayer != null) {
mediaPlayer.pause();
if (isFinishing()) {
mediaPlayer.stop();
mediaPlayer.release();
}
}
}
public void initializeViews(){
songName = (TextView) findViewById(R.id.songName);
mediaPlayer = MediaPlayer.create(this, R.raw.druidsad);
finalTime = mediaPlayer.getDuration();
duration = (TextView) findViewById(R.id.songDuration);
seekbar = (SeekBar) findViewById(R.id.seekBar);
songName.setText("Druids Ad");
seekbar.setMax((int) finalTime);
seekbar.setClickable(true);
}
// play mp3 song
public void play(View view) {
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 remaining
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);
}
}
// 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);
}
}
// handler for back button used on music player screen
public void BackButton2 (View view) {
MediaPlayer mMediaPlayer = MediaPlayer.create(this, R.raw.soundbackbutton) ;
mMediaPlayer.start();
Vibrator vib = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
vib.vibrate(200);
Intent mus = new Intent (this, Music.class);
startActivity(mus);
}
// handler for home button used on all screens
public void BackButton (View view) {
MediaPlayer mMediaPlayer = MediaPlayer.create(this, R.raw.soundbackbutton) ;
mMediaPlayer.start();
Vibrator vib = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
vib.vibrate(200);
Intent mn = new Intent (this, Music.class);
startActivity(mn);
}
}
Its easy. Follow these steps :-
Add a seek bar change Listener.
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
int seeked_progess;
#Override
public void onProgressChanged(final SeekBar seekBar, int progress, boolean fromUser) {
seeked_progess = progress;
seeked_progess = seeked_progess * 1000;
if (fromUser) {
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
Now in if(fromUser), U need to add the implementation.
if (fromUser) {
Runnable mRunnable = new Runnable() {
#Override
public void run() {
int min, sec;
if (mediaPlayer != null /*Checking if the
music player is null or not otherwise it
may throw an exception*/) {
int mCurrentPosition = seekBar.getProgress();
min = mCurrentPosition / 60;
sec = mCurrentPosition % 60;
Log.e("Music Player Activity", "Minutes : "+min +" Seconds : " + sec);
/*currentime_mm.setText("" + min);
currentime_ss.setText("" + sec);*/
}
mHandler.postDelayed(this, 1000);
}
};
mRunnable.run();}
At last add this in onStopTrackingTouch()
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
mediaPlayer.seekTo(seeked_progess);
}
});
Note :-
mHandler in a global variable.
Initialize it as follows.
Handler mHandler = new Handler();
Secondly currentime_mm and currentime_ss are text views which display the current seek time of the seek bar.
and most Important,
dont forgot to add these when a song starts
seekBar.setProgress(0);// To set initial progress, i.e zero in starting of the song
seekBar.setMax(mediaDuration);// To set the max progress, i.e duration of the song
Put this code inside onCreate() method
seekbar.setMax(mediaPlayer.getDuration());
seekbar.setProgress(mediaPlayer.getCurrentPosition());
new Timer().scheduleAtFixedRate(new TimerTask() {
#Override
public void run()
{
seekbar.setProgress(mediaPlayer.getCurrentPosition());
}
},0,1000);
seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b)
{
mediaPlayer.seekTo(i);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
What Punam did is good but add a condition in your "onProgressChanged" function like this:
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b)
{
if(b)
mediaPlayer.seekTo(i);
}
Related
I have two audio files in my app. When the app is launched the first time and when the user plays the first audio for the first time, I want to show a dialog, but afterwards never show it again.
When the user clicks OK, then only the dialog will disappear.
I have only created the XML of the dialog because I don't know how to show a layout when the app is launched the first time.
MainActivity.java here the player1 (Media Player) and play1 (ImageView as the button to play the audio) is for the first audio where the dialog has to be shown.
public class MainActivity extends AppCompatActivity {
MediaPlayer player1, player2;
SeekBar seekBar1, seekBar2;
TextView currentTime1, currentTime2;
TextView remainingTime1, remainingTime2;
ImageView play1, play2;
int totalTime1, totalTime2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// PlayButton * The ButtonClick is in the last if you want to jump directly there *
play1 = findViewById(R.id.playbtn);
play2 = findViewById(R.id.playbtn2);
// TimeLables
currentTime1 = findViewById(R.id.currentTime1);
currentTime2 = findViewById(R.id.currentTime2);
remainingTime1 = findViewById(R.id.totalTime1);
remainingTime2 = findViewById(R.id.totalTime2);
// MediaPlayer
player1 = MediaPlayer.create(this, R.raw.dog_howl);
player2 = MediaPlayer.create(this, R.raw.dog_bark);
player1.setLooping(false);
player1.seekTo(0);
totalTime1 = player1.getDuration();
player2.setLooping(false);
player2.seekTo(0);
totalTime2 = player2.getDuration();
//SeekBar
seekBar1 = findViewById(R.id.seekbar1);
seekBar2 = findViewById(R.id.seekbar2);
seekBar1.setMax(totalTime1);
seekBar2.setMax(totalTime2);
seekBar1.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
player1.seekTo(progress);
seekBar1.setProgress(progress);
currentTime1.setText(createTimerLable1(progress));
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
seekBar2.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
player2.seekTo(i);
seekBar2.setProgress(i);
currentTime2.setText(createTimerLable2(i));
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
new Thread(() -> {
while (player1 != null) {
try {
Message msg = new Message();
msg.what = player1.getCurrentPosition();
handler1.sendMessage(msg);
Thread.sleep(1000000000);
} catch (InterruptedException ignored) {
}
}
}).start();
new Thread(() -> {
while (player2 != null) {
try {
Message msg = new Message();
msg.what = player2.getCurrentPosition();
handler2.sendMessage(msg);
Thread.sleep(1000000000);
} catch (InterruptedException ignored) {
}
}
}).start();
// Admob Banner Ad
MobileAds.initialize(this, initializationStatus -> {
});
AdView mAdView = findViewById(R.id.adView);
AdRequest adRequest = new AdRequest.Builder().build();
mAdView.loadAd(adRequest);
}
#SuppressLint("HandlerLeak")
private final Handler handler1 = new Handler() {
#Override
public void handleMessage(#NonNull Message msg) {
int currentPosition1 = msg.what;
//Update SeekBar
seekBar1.setProgress(currentPosition1);
// Update Timelable
String totTime1 = createTimerLable1(player1.getDuration());
remainingTime1.setText(totTime1);
}
};
#SuppressLint("HandlerLeak")
private final Handler handler2 = new Handler() {
#Override
public void handleMessage(#NonNull Message msg) {
int currentPosition2 = msg.what;
// Update SeekBar
seekBar2.setProgress(currentPosition2);
// Update Timelable
String totTime2 = createTimerLable2(player2.getDuration());
remainingTime2.setText(totTime2);
}
};
public String createTimerLable1(int duration) {
String timerLabel = "";
int min = duration / 1000 / 60;
int sec = duration / 1000 % 60;
timerLabel += min + ":";
if (sec < 10) timerLabel += "0";
timerLabel += sec;
return timerLabel;
}
public String createTimerLable2(int duration) {
String timerLabel = "";
int min = duration / 1000 / 60;
int sec = duration / 1000 % 60;
timerLabel += min + ":";
if (sec < 10) timerLabel += "0";
timerLabel += sec;
return timerLabel;
}
public void playBtnClick1(View view) {
if (player2.isPlaying()) {
player2.pause();
play2.setImageResource(R.drawable.ic_baseline_play_circle_filled_24);
}
if (!player1.isPlaying()) {
// Stoping
player1.start();
play1.setImageResource(R.drawable.ic_baseline_pause_circle_filled_24);
} else {
// Playing
player1.pause();
play1.setImageResource(R.drawable.ic_baseline_play_circle_filled_24);
}
}
public void playBtnClick2(View view) {
if (player1.isPlaying()) {
player1.pause();
play1.setImageResource(R.drawable.ic_baseline_play_circle_filled_24);
}
if (!player2.isPlaying()) {
// Stoping
player2.start();
play2.setImageResource(R.drawable.ic_baseline_pause_circle_filled_24);
} else {
// Playing
player2.pause();
play2.setImageResource(R.drawable.ic_baseline_play_circle_filled_24);
}
}
}
As #blackapps suggested, You will save the information about the user in SharedPreferences. You will save whether you have displayed the dialog and whether user's has played audio for first time or not.
To save or get the details from SharedPreferences,
You can follow this SO answer for storing strings, int, boolean etc.
You can follow this SO answer for storing custom objects.
I going to fix the issue about when I click the to go another activity and my timer started before, when I back to the timer count activity, the timer stopped and auto reset to 0. How can I manage the activity when I back to timer activity and keep the timer counting?
Here are my code of my timer counter.
// TimerCount
TextView txtvTimer;
Button pauseStartBtn;
Button stopFinishBtn;
boolean timerStarted = false;
Timer timer;
TimerTask timerTask;
Double time = 0.0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_timer_count);
Log.d(TAG_LIFECYCLE, "In the activity_timer_count onCreate() event");
// timer
txtvTimer = (TextView) findViewById(R.id.txtvTimer);
pauseStartBtn = (Button) findViewById(R.id.btnStartPause);
stopFinishBtn = (Button) findViewById(R.id.btnStopFinish);
stopFinishBtn.setEnabled(false);
timer = new Timer();
// bottom nav
BottomNavigationView bottomNavigationView = findViewById(R.id.bottom_nav);
bottomNavigationView.setSelectedItemId(R.id.timerCountActivity);
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.mainActivity:
startActivity(new Intent(getApplicationContext(),MainActivity.class));
overridePendingTransition(0,0);
return true;
case R.id.mapActivity:
startActivity(new Intent(getApplicationContext(),MapActivity.class));
overridePendingTransition(0,0);
return true;
case R.id.timerCountActivity:
return true;
case R.id.userInfoActivity:
startActivity(new Intent(getApplicationContext(),UserInfoActivity.class));
overridePendingTransition(0,0);
return true;
case R.id.settingActivity:
startActivity(new Intent(getApplicationContext(),SettingActivity.class));
overridePendingTransition(0,0);
return true;
}
return false;
}
});
}
// timer reset button
public void resetTapped(View v) {
AlertDialog.Builder resetAlert = new AlertDialog.Builder(this);
resetAlert.setTitle("Reset Timer");
resetAlert.setMessage("Reset the timer?");
resetAlert.setPositiveButton("Reset", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (timerTask != null) {
timerTask.cancel();
setButton("START", R.color.green);
time = 0.0;
timerStarted = false;
txtvTimer.setText(formatTime(0,0,0));
}
}
});
resetAlert.setNeutralButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
});
resetAlert.show();
}
// timer start pause button
public void startPauseTapped(View v) {
if (timerStarted == false){
timerStarted = true;
setButton("PAUSE", R.color.red);
startTimer();
onStartClicked(v);
onLocateClicked(v);
stopToPushData(v);
} else {
timerStarted = false;
setButton("Resume", R.color.green);
timerTask.cancel();
onStartClicked(v);
onLocateClicked(v);
}
}
private void setButton(String start, int color) {
pauseStartBtn.setText(start);
pauseStartBtn.setTextColor(ContextCompat.getColor(this, color));
}
private void startTimer() {
timerTask = new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
time++;
txtvTimer.setText(getTimerText());
}
});
}
};
timer.scheduleAtFixedRate(timerTask,0,1000);
}
private String getTimerText() {
int rounded = (int) Math.round(time);
int seconds = ((rounded % 86400) % 3600) % 60;
int minutes = ((rounded % 86400) % 3600) / 60;
int hours = ((rounded % 86400) / 3600) ;
return formatTime (seconds, minutes, hours);
}
private String formatTime(int seconds, int minutes, int hours) {
return String.format("%02d",hours) + " : " + String.format("%02d",minutes) + " : " + String.format("%02d",seconds);
}
Second, how can I get the timer to calculate the time per second?
Is it rounded % 86400 will be the real second I have counted?
I think it's better to use chronometer
Xml :
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white">
<Chronometer
android:id="#+id/chronometer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Main Acitvity:
public class MainActivity extends AppCompatActivity {
Chronometer chronometer ;
long stopTime ; // this variable will count the time when stop counting (when you have left the activity)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
chronometer = (Chronometer) findViewById(R.id.chronometer);
}
void StartCounting() {
chronometer.setBase(SystemClock.elapsedRealtime()-stopTime); // This line will set the time to correct when you return to the activity
chronometer.start();
}
void PauseCounting() {
stopTime = SystemClock.elapsedRealtime()-chronometer.getBase();
chronometer.stop();
}
}
I need your help to get a variable from the countdown and set that value to text view. Suppose if countdown stopped at 0:40 sec and I want to put that number to text view.
So I'm using Seekbar to update the time with progress and a textview. And suppose I stopped at a certain number, next time I start again, let the number start from when it stopped. I have uploaded the image of output. Thanks
I learned to create this app from udemy online tutorial. Its called Complete android developer course- Build 23 Apps!!. Its lesson 38- App Egg timer.
This is my MainActivity.java file
public class MainActivity extends AppCompatActivity {
TextView timerTv;
SeekBar timerSeekBar;
Button startBtn;
CountDownTimer countDownTimer;
boolean counterisActive = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
timerTv = (TextView) findViewById(R.id.countdowntimertextview);
timerSeekBar = (SeekBar) findViewById(R.id.timerSeekBar);
startBtn = (Button) findViewById(R.id.startBtn);
timerSeekBar.setMax(300);
timerSeekBar.setProgress(20);
timerSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
updateTimer(progress);
Log.i("Seekbar changes", String.valueOf(progress), null);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
public void resetTimer(){
//This is where I want to set the text.
timerTv.setText("Trying to get text from countdown!!");
startBtn.setText("START!");
timerSeekBar.setEnabled(true);
countDownTimer.cancel();
timerSeekBar.setProgress(20);
counterisActive = false;
}
public void buttonClicked(View view){
if(counterisActive){
resetTimer();
}else {
counterisActive = true;
timerSeekBar.setEnabled(false);
startBtn.setText("STOP!");
Log.i("Button Clicked", "Clicked");
countDownTimer = new CountDownTimer(timerSeekBar.getProgress() * 1000 + 100, 1000) {
#Override
public void onTick(long millisUntilFinished) {
updateTimer((int) millisUntilFinished / 1000);
}
#Override
public void onFinish() {
MediaPlayer mediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.templebell);
mediaPlayer.start();
Log.i("Timer Finished", "Done!!");
resetTimer();
}
}.start();
}
}
public void updateTimer(int secondLefts){
int minutes = secondLefts / 60;
int seconds = secondLefts - (minutes * 60);
String secondString = Integer.toString(seconds);
if(seconds <= 9) {
secondString = "0" + seconds;
}
timerTv.setText(minutes + " : " + secondString );
}
}
I think you need to pause the timer.
First create a global long variable in your activity;
long timerProgress;
Change your restProgress() method like below, or you can add new method pauseTimer().
public void restTimer(){
//This is where I want to set the text.
updateTimer((int) timerProgress/1000);
startBtn.setText("START!");
timerSeekBar.setEnabled(true);
countDownTimer.cancel();
timerSeekBar.setProgress((int) timerProgress/1000);
counterisActive = false;
}
Know add this line to your override method onTick.
#Override
public void onTick(long millisUntilFinished) {
updateTimer((int) millisUntilFinished / 1000);
// add this line for store progress timer.
timerProgress = millisUntilFinished;
}
You can add another button one for pause and other for rest Timer.
Try replacing timerTv.setText(minutes + " : " + secondString ); with
runOnUiThread(new Runnable() {
#Override
public void run() {
timerTv.setText(minutes + " : " + secondString );
}
});
If you try to update the UI mid-thread, it will wait until the current thread has finished before updating the text.
So I have been working with ExoPlayer for streaming content in MP4 Dash File Format, and everything works fine, until I decide to change the Seekbar to a new position. On changing the Seekbar to a new position, the audio plays absolutely fine, but the video is stuck at a frame like a picture. Not sure why it's happening. Any help would be greatly helpful.
Edit:
PlayerView ep;
SimpleExoPlayer player;
boolean secondTouch=false;
boolean isPlaying=false;
boolean isLandscape=false;
long lastTimeTouched;
//ON SCREEN CONTROLS
LinearLayout mcContainer;
ImageButton ivPlay;
ImageButton ivSize;
TextView totalDuration;
RelativeLayout buffer;
SeekBar progress;
int totalTime;
Runnable runnable;
LinearLayout commentsContainer;
Intent i;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
getSupportActionBar().hide();
i=getIntent();
setContentView(R.layout.activity_video);
details=findViewById(R.id.textView11);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
isLandscape=getResources().getConfiguration().orientation==Configuration.ORIENTATION_LANDSCAPE;
ep=findViewById(R.id.videoViewPlay);
ivSize=findViewById(R.id.imageButton2);
player = new SimpleExoPlayer.Builder(this).build();
ep.setPlayer(player);
mcContainer=findViewById(R.id.mcContainer);
ivPlay=findViewById(R.id.buttonPlay);
totalDuration=findViewById(R.id.textViewTotalDuration);
buffer=findViewById(R.id.bufferContainer);
progress=findViewById(R.id.seekBarProgress);
ivPlay.setOnClickListener(v -> {
if(isPlaying)
{
player.setPlayWhenReady(false);
isPlaying=false;
ivPlay.setBackgroundResource(android.R.drawable.ic_media_play);
}
else
{
player.setPlayWhenReady(true);
isPlaying=true;
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
ivPlay.setBackgroundResource(android.R.drawable.ic_media_pause);
}
});
ep.setOnClickListener(v -> {
ViewGroup.LayoutParams params = mcContainer.getLayoutParams();
params.height = Tools.convertDpToPx(this,48);
mcContainer.setLayoutParams(params);
lastTimeTouched=System.currentTimeMillis();
if(secondTouch==true){
params = mcContainer.getLayoutParams();
params.height = 0;
mcContainer.setLayoutParams(params);
}
secondTouch=!secondTouch;
});
progress.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if(fromUser) {
player.setPlayWhenReady(false);
player.seekTo(progress * 1000);
player.setPlayWhenReady(true);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
DefaultBandwidthMeter bandwidthMeterA = new DefaultBandwidthMeter();
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "eTuitionPro"), bandwidthMeterA);// This is the MediaSource representing the media to be played.
String media=Uri.parse(Tools.baseAddress+"VIDEO/"+i.getStringExtra("ModuleID")+"/index.php").buildUpon().appendQueryParameter("token", Tools.token).build().toString();//NEEDS CHANGE
MediaSource videoSource =new DashMediaSource.Factory(dataSourceFactory).createMediaSource(Uri.parse(media));// Prepare the player with the source.
player.prepare(videoSource);
Handler handler = new Handler();
runnable = () -> {
progress.setProgress(((int)(player.getCurrentPosition()/1000)));
if(((int)(player.getCurrentPosition()/1000))==progress.getMax())
{
player.setPlayWhenReady(false);
isPlaying=false;
ivPlay.setBackgroundResource(android.R.drawable.ic_media_play);
progress.setProgress(0);
}
else
handler.postDelayed(runnable, 1000);
};
player.addListener(new Player.EventListener() {
#Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
switch(playbackState)
{
case ExoPlayer.STATE_READY:
totalTime = (int)(player.getDuration()/1000);
progress.setMax(totalTime);
totalDuration.setText(msToString(player.getDuration()));
buffer.setVisibility(View.INVISIBLE);
handler.postDelayed(runnable, 0);
break;
case ExoPlayer.STATE_BUFFERING:
buffer.setVisibility(View.VISIBLE);
break;
}
}
#Override
public void onPlayerError(ExoPlaybackException error) {
}
});
...
In the above program I tried to make a custom Control Player UI for the ExoPlayer. Not sure if I did anything wrong, if there is a better way to do this, I will honoured to know more.
I'm trying to implement a series of music players in Android. When I press the back button I want the music to stop when the application returns to the the previous screen. I tried lots of solutions and searched online but the app is crashing if I put in lines such as 'stop' and 'release'. Maybe I'm not doing them correctly? Thanks for any help forthcoming... Here is my code...
public class MusicPlayerA extends Activity {
private MediaPlayer mediaPlayer;
public TextView songName, duration;
private double timeElapsed = 0, finalTime = 0;
private int forwardTime = 2500, backwardTime = 2500;
private Handler durationHandler = new Handler();
private SeekBar seekbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//set the layout of the Activity
setContentView(R.layout.musicplayerview);
//initialize views
initializeViews();
}
public void initializeViews(){
songName = (TextView) findViewById(R.id.songName);
mediaPlayer = MediaPlayer.create(this, R.raw.druidsad);
finalTime = mediaPlayer.getDuration();
duration = (TextView) findViewById(R.id.songDuration);
seekbar = (SeekBar) findViewById(R.id.seekBar);
songName.setText("Druids Ad");
seekbar.setMax((int) finalTime);
seekbar.setClickable(true);
}
// play mp3 song
public void play(View view) {
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 remaining
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);
}
}
// 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);
}
}
public void stopMusic(View view) {
mediaPlayer.stop();
mediaPlayer.release();
}
// handler for back button used on all screens
public void BackButton2 (View view) {
//mediaPlayer.pause();
//mediaPlayer.release();
//mediaPlayer.stop();
// mediaPlayer.release();
stopMusic(view);
MediaPlayer mMediaPlayer = MediaPlayer.create(this, R.raw.soundbackbutton) ;
mMediaPlayer.start();
Vibrator vib = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
vib.vibrate(200);
Intent mus = new Intent (this, Music.class);
startActivity(mus);
}
// handler for back button used on all screens
public void BackButton (View view) {
// mediaPlayer.pause();
//mediaPlayer.release();
// mediaPlayer.stop();
// mediaPlayer.release();
MediaPlayer mMediaPlayer = MediaPlayer.create(this, R.raw.soundbackbutton) ;
mMediaPlayer.start();
Vibrator vib = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
vib.vibrate(200);
Intent mn = new Intent (this, Music.class);
startActivity(mn);
}
}
When you hit the back button, the Android system should call on Activity.onPause(). I don't see any implementation for onPause(), unless your backbutton handler is calling it. I would try something like this:
#Override
protected void onPause() {
super.onPause();
if (mediaPlayer != null) {
mediaPlayer.pause();
if (isFinishing()) {
mediaPlayer.stop();
mediaPlayer.release();
}
}
}