music is not playing smoothly when updating seekbar every 1 second - java

After adding Timer() method seekbar should be updated every second, it is getting updated but their is a small pause like updating seekbar require a time to update... this has cause seekbar is not running smoothly gives a feel that there is a lag...
package com.example.musicplayer;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.widget.SeekBar;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends AppCompatActivity {
MediaPlayer mediaPlayer;
AudioManager audioManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mediaPlayer = MediaPlayer.create(this,R.raw.senorita);
audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
int myMaxValume= audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
int myCurrentValume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
SeekBar valumeRocker = findViewById(R.id.seekBar);
valumeRocker.setMax(myMaxValume);
valumeRocker.setProgress(myCurrentValume);
valumeRocker.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,progress,0);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
//timeline part of music app
final SeekBar timeline = findViewById(R.id.timeline);
timeline.setMax(mediaPlayer.getDuration());
//set onChange listner on timeline
timeline.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
mediaPlayer.seekTo(progress);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
//customise timeline seekbar
new Timer().scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
timeline.setProgress(mediaPlayer.getCurrentPosition());
}
}
, 0, 1000);
}
public void playMe(View view){
mediaPlayer.start();
}
public void pauseMe(View view){
mediaPlayer.pause();
}
}
if i remover Timer method.. every this is fine ... i guess i have done something woring in this ...
help me out
thank you in advance..

You need to check 'fromUser' variable is true or not on seekbar progress changed. Because you will get seekbar change callback in both cases, when the user change manually and when Timer update seekbar progress.
Updated code:-
package com.example.musicplayer;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.widget.SeekBar;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends AppCompatActivity {
MediaPlayer mediaPlayer;
AudioManager audioManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mediaPlayer = MediaPlayer.create(this,R.raw.senorita);
audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
int myMaxValume= audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
int myCurrentValume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
SeekBar valumeRocker = findViewById(R.id.seekBar);
valumeRocker.setMax(myMaxValume);
valumeRocker.setProgress(myCurrentValume);
valumeRocker.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,progress,0);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
//timeline part of music app
final SeekBar timeline = findViewById(R.id.timeline);
timeline.setMax(mediaPlayer.getDuration());
//set onChange listner on timeline
timeline.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser) mediaPlayer.seekTo(progress);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
//customise timeline seekbar
new Timer().scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
timeline.setProgress(mediaPlayer.getCurrentPosition());
}
}
, 0, 1000);
}
public void playMe(View view){
mediaPlayer.start();
}
public void pauseMe(View view){
mediaPlayer.pause();
}
}

Related

MediaPlayer App is crashing when i try to run

I'm beginner in android development and tried to create a simple mediaplayer app which plays media from local source.
But it's crashing when i try to open it.
This is my java code.
package com.example.media;
import androidx.appcompat.app.AppCompatActivity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;
public class MainActivity extends AppCompatActivity {
Button play,pause;
SeekBar s;
MediaPlayer m;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
m=MediaPlayer.create(this,R.raw.live);
play=findViewById(R.id.button3);
pause=findViewById(R.id.button4);
s.findViewById(R.id.seekBar);
s.setMax(m.getDuration());
s.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if(fromUser)m.seekTo(progress);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
play.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
m.start();
}
});
pause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
m.pause();
}
});
}
}
You need to initialize the seekbar object instead of calling the findViewById method.
So just replace the dot with equal sign :
s=findViewById(R.id.seekBar);

Losing state of the activity when navigating from notification to activity

I have an activity named Player Activity in which I am streaming music with the help of MediaPlayer API. Whenever my activity is created a notification is displayed which has some basic control of the music player.
So when I tap on my notification it jumps back to the Player Activity, but the state of the activity is lost.
Before tapping on notification :
After tapping on notification :
Here is the code of my notification's Pending Intent
Intent notifyIntent = new Intent(context, PlayerActivity.class);
notifyIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
notifyIntent.setAction("android.intent.action.MAIN");
notifyIntent.addCategory("android.intent.category.LAUNCHER");
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Here is the code for PlayerActivity.java :
package com.example.user.musicplayer;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.media.MediaMetadataRetriever;
import android.media.MediaPlayer;
import android.os.AsyncTask;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import com.squareup.picasso.Picasso;
import java.util.concurrent.TimeUnit;
import de.hdodenhof.circleimageview.CircleImageView;
public class PlayerActivity extends AppCompatActivity implements MediaPlayer.OnBufferingUpdateListener,MediaPlayer.OnCompletionListener{
private static Button btn_play_pause;
private Button btnToggleRepeat;
private Button btnStop;
private SeekBar seekBar;
private TextView textView;
public static MediaPlayer mediaPlayer;
private int mediaFileLength;
private int realtimeLength;
private String musicUrl;
private String imageUrl;
final Handler handler = new Handler();
private boolean isRepeat;
private CircleImageView musicImage;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_player);
Log.d("TAG", "onCreate");
NotificationGenerator.customBigNotification(getApplicationContext());
musicUrl = getIntent().getStringExtra("musicUrl");
imageUrl = getIntent().getStringExtra("imageUrl");
seekBar = (SeekBar)findViewById(R.id.seekbar);
seekBar.setMax(99); // 100% (0~99)
seekBar.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(mediaPlayer.isPlaying())
{
SeekBar seekBar = (SeekBar)v;
int playPosition = (mediaFileLength/100)*seekBar.getProgress();
mediaPlayer.seekTo(playPosition);
}
return false;
}
});
textView = (TextView)findViewById(R.id.txtTime);
btnToggleRepeat = findViewById(R.id.btnRepeat);
btnStop = findViewById(R.id.btnStop);
musicImage = findViewById(R.id.musicImgView);
Picasso.get().load(imageUrl).placeholder(R.drawable.music).error(R.drawable.music).into(musicImage);
btn_play_pause = (Button) findViewById(R.id.btnTogglePlay);
btn_play_pause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final ProgressDialog mDialog = new ProgressDialog(PlayerActivity.this);
AsyncTask<String,String,String> mp3Play = new AsyncTask<String, String, String>() {
#Override
protected void onPreExecute() {
mDialog.setMessage("Please wait");
mDialog.show();
}
#Override
protected String doInBackground(String... params) {
try{
mediaPlayer.setDataSource(params[0]);
mediaPlayer.prepare();
}
catch (Exception ex)
{
}
return "";
}
#Override
protected void onPostExecute(String s) {
mediaFileLength = mediaPlayer.getDuration();
realtimeLength = mediaFileLength;
if(!mediaPlayer.isPlaying())
{
playMusic();
}
else
{
pauseMusic();
}
updateSeekBar();
mDialog.dismiss();
}
};
mp3Play.execute(musicUrl); // direct link mp3 file
}
});
btnToggleRepeat.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(isRepeat){
isRepeat = false;
mediaPlayer.setLooping(false);
btnToggleRepeat.setText("Repeat");
}
else{
isRepeat = true;
mediaPlayer.setLooping(true);
btnToggleRepeat.setText("Single");
}
}
});
btnStop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
mediaPlayer.pause();
mediaPlayer.stop();
}
catch (Exception e){
Toast.makeText(PlayerActivity.this, "Opps! sorry something bad happened", Toast.LENGTH_SHORT).show();
}
}
});
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnBufferingUpdateListener(this);
mediaPlayer.setOnCompletionListener(this);
}
public void pauseMusic() {
mediaPlayer.pause();
btn_play_pause.setText("Play");
}
public void playMusic() {
mediaPlayer.start();
btn_play_pause.setText("Pause");
}
private void updateSeekBar() {
seekBar.setProgress((int)(((float)mediaPlayer.getCurrentPosition() / mediaFileLength)*100));
if(mediaPlayer.isPlaying())
{
Runnable updater = new Runnable() {
#Override
public void run() {
updateSeekBar();
realtimeLength-=1000; // declare 1 second
textView.setText(String.format("%d:%d",TimeUnit.MILLISECONDS.toMinutes(realtimeLength),
TimeUnit.MILLISECONDS.toSeconds(realtimeLength) -
TimeUnit.MILLISECONDS.toSeconds(TimeUnit.MILLISECONDS.toMinutes(realtimeLength))));
}
};
handler.postDelayed(updater,1000); // 1 second
}
}
#Override
protected void onResume() {
super.onResume();
Log.d("TAG", "onResume");
}
#Override
protected void onStart() {
super.onStart();
Log.d("TAG", "onStart");
}
#Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
seekBar.setSecondaryProgress(percent);
}
#Override
public void onCompletion(MediaPlayer mp) {
if(!mediaPlayer.isLooping())
btn_play_pause.setText("Play");
}
#Override
protected void onStop() {
super.onStop();
}
#Override
protected void onPause() {
super.onPause();
}
public static class DownloadCancelReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("notificationPlayer","Received Cancelled Event");
}
}
}
Thanks in advance. Pardon me if the explanation is not clear, because if i might have right words to explain it, I would have googled it.
Add this to your PlayerActivity activity in manifest :
android:launchMode="singleTask"
And use these flags in the intent for pendingintent :
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

Runtime error in thread of music app

**Down here I am trying to build a music app in android studio,my app is working fine displaying all my SD card songs and play too ,all button works but when I click on next button it works normally but don't know why app sometimes gets stopped working and shows runtime exception ->>please open the image of run log of the application.
package com.example.ramandeepsingh.tunes;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Build;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
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.Toast;
import java.io.File;
import java.util.ArrayList;
import java.util.jar.Manifest;
public class PlayerActivity extends AppCompatActivity{
static MediaPlayer mp;//assigning memory loc once or else multiple songs will play at once
int position;
SeekBar sb;
ArrayList<File> mySongs;
Thread updateSeekBar;
Button pause,forward,reverse,next,previous;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_player);
pause = (Button)findViewById(R.id.pause);
forward = (Button)findViewById(R.id.forward);
previous = (Button)findViewById(R.id.previous);
next = (Button)findViewById(R.id.next);
reverse = (Button)findViewById(R.id.reverse);
sb=(SeekBar)findViewById(R.id.seekBar);
updateSeekBar=new Thread(){
#Override
public void run(){
int totalDuration = mp.getDuration();
int currentPosition = 0;
// sb.setMax(totalDuration);
while(currentPosition < totalDuration){
try{
sleep(500);
currentPosition=mp.getCurrentPosition();
}
catch (InterruptedException e){
e.printStackTrace();
System.out.println(e);
}
sb.setProgress(currentPosition);
}
}
};
if(mp != null){
mp.stop();
mp.release();
}
Intent i = getIntent();
Bundle b = i.getExtras();
mySongs = (ArrayList) b.getParcelableArrayList("songs");
position = b.getInt("pos",0);
Uri u = Uri.parse(mySongs.get(position).toString());
mp = MediaPlayer.create(getApplicationContext(),u);
mp.start();
sb.setMax(mp.getDuration());
updateSeekBar.start();
sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
mp.seekTo(seekBar.getProgress());
}
});
pause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
sb.setMax(mp.getDuration());
if(mp.isPlaying()){
pause.setText(">");
mp.pause();
}
else {
pause.setText("||");
mp.start();
}
}
});
forward.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
sb.setMax(mp.getDuration());
mp.seekTo(mp.getCurrentPosition()+5000);
}
});
reverse.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
sb.setMax(mp.getDuration());
mp.seekTo(mp.getCurrentPosition()-5000);
}
});
next.setOnClickListener(new
View.OnClickListener() {
#Override
public void onClick(View v) {
mp.stop();
mp.reset();
position=((position+1)%mySongs.size());
Uri u = Uri.parse(mySongs.get( position).toString());
mp = MediaPlayer.create(getApplicationContext(),u);
mp.start();
sb.setMax(mp.getDuration());
updateSeekBar.start();
}
});
previous.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mp.stop();
mp.release();
position=((position-1)<0)?(mySongs.size()-1):(position-1);
Uri u = Uri.parse(mySongs.get( position).toString());//%mysongs so that it do not go to invalid position
mp = MediaPlayer.create(getApplicationContext(),u);
mp.start();
}
});
}}

Change the image transparency using a SeekBar

I have to do an Android Studio project that it has to change the transparency of an ImageView using a SeekBar.
I have this program:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private int seekTransparent;
ImageView color;
SeekBar seekBarTransparent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
color = (ImageView)findViewById(R.id.changeColor);
seekBarTransparent = (SeekBar) findViewById(R.id.seekBar);
updateNow();
seekBarTransparent.setOnSeekBarChangeListener(seekBarChangeListener);
}
private SeekBar.OnSeekBarChangeListener seekBarChangeListener = new
SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean
fromUser) {
updateNow();
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
Toast.makeText(getApplicationContext(), "toast in uso",
Toast.LENGTH_SHORT).show();
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
Toast.makeText(getApplicationContext(), "toast non in uso",
Toast.LENGTH_SHORT).show();
}
};
private void updateNow(){
seekTransparent = seekBarTransparent.getProgress();
color.getBackground().setAlpha(192 + seekTransparent * 0x10000);
}
}
I run the application but on my smartphone it doesn't work anyone can help me?
This is the xml of the seekbar
<SeekBar
android:id="#+id/opacitybar"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:max="10"
android:progress="10"
android:layout_alignTop="#+id/opacitylbl"
android:layout_centerHorizontal="true" />
And this is the code of the Activity
logoseekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
int opacity = 100; // from 0 to 255
#Override
public void onProgressChanged(SeekBar seekBar, int progresValue, boolean fromUser) {
im_move_zoom_rotate.setAlpha(progresValue * 25);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
You can change the values if you want

Android SeekBar extension

I have multiple Seek Bars on my activity (4) and for each there is a textView that suppose to show the progress of each SeekBar. I thought to extend the SeekBar Class and add to it's constructor a TextView Parameter so I can bind the two -> SeekBar and TextView . Here is my extended SeekBar class:
import android.content.Context;
import android.widget.SeekBar;
import android.widget.TextView;
public class SeekBarPlus extends SeekBar {
private TextView numberOfDrills;
public SeekBarPlus(Context context, TextView text) {
super(context);
// TODO Auto-generated constructor stub
numberOfDrills = (TextView) text;
}
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
numberOfDrills.setText(progress);
}
}
What is the Context option?
Now here is my MainActivity:
package com.simplemathgame;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import com.simplemathgame.SeekBarPlus;
public class MainActivity extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView numberOfAddDrills = (TextView) findViewById(R.id.add_drills_number);
TextView numberOfSubDrills = (TextView) findViewById(R.id.sub_drills_number);
TextView numberOfMulDrills = (TextView) findViewById(R.id.mul_drills_number);
TextView numberOfDivDrills = (TextView) findViewById(R.id.div_drills_number);
SeekBarPlus addSeekBar = SeekBarPlus((SeekBar) findViewById(R.id.add_seek_bar), numberOfAddDrills);
SeekBarPlus subSeekBar = SeekBarPlus((SeekBar) findViewById(R.id.sub_seek_bar), numberOfAddDrills);
SeekBarPlus mulSeekBar1 = SeekBarPlus((SeekBar) findViewById(R.id.mul_seek_bar), numberOfAddDrills);
SeekBarPlus divSeekBar1 = SeekBarPlus((SeekBar) findViewById(R.id.div_seek_bar), numberOfAddDrills);
}
}
I don't know how to it wright! Any suggestions would be appreciated!!!
try to use setter instead of constructor in your custom SeekBar:
public void setTextView(TextView text) {
numberOfDrills = text;
}
then in your activity, use
SeekBarPlus subSeekBar = (SeekBarPlus) findViewById(R.id.sub_seek_bar);
subSeekBar.setTextView(numberOfAddDrills);
you can also use normal Seekbar with OnSeekBarChangeListener:
SeekBar subSeekBar = (SeekBar) findViewById(R.id.sub_seek_bar);
subSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
#Override
public void onStopTrackingTouch(SeekBar seekBar) { }
#Override
public void onStartTrackingTouch(SeekBar seekBar) { }
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
numberOfDrills.setText(String.valueOf(progress));
}
});

Categories