Music player with Seekbar (Android Studio) - java

I was working in a very simple music player with a seek bar. But I got a problem with playing music,it doesn't work correctly every second - it backwards a while, then remain again like it's a buggy.
I know why but I can't solve it.
When the progress bar moves forward, the music recalibrates and vice versa, when the music moves forward, the progress bar recalibrates.
It's probably because of that that every time it goes back.
But I tried several things and still have the same problem.
Another problem is that when the music is paused, the progress bar goes in the opposite direction until it reaches zero. It doesn't stay where it was before the break.
The full code :
public class MainActivity extends AppCompatActivity {
private MediaPlayer mediaPlayer;
private SeekBar seekBar;
private boolean bool = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.seekBar = (SeekBar) findViewById(R.id.sound_bar);
this.mediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.music);
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
seekBar.setProgress(mediaPlayer.getCurrentPosition() * seekBar.getMax() / mediaPlayer.getDuration());
}
}, 500, 500);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
mediaPlayer.seekTo(seekBar.getProgress() * mediaPlayer.getDuration() / seekBar.getMax());
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
public void playSound(View view) {
Button button = (Button) view;
if(bool) {
mediaPlayer.pause();
bool = false;
button.setText("Jouer le son");
} else {
mediaPlayer.start();
bool = true;
button.setText("Mettre en pause");
}
}
#Override
protected void onPause() {
super.onPause();
mediaPlayer.pause();
}
#Override
protected void onStart() {
super.onStart();
if(bool) {
mediaPlayer.start();
}
}
}

Maybe use another thread to control the seekbar would help.
Take a look at this

Related

how to make reset button automatically play again when its clicked?

another thing is the timer for seekBar its for the duration of the audio file the issue within it is that the audio file do (mini) stop every 1 sec so how to make seek bar update itself every second without doing any stops
seekBar2.setMax(mediaPlayer.getDuration());
seekBar2.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) {
}
});
new Timer().scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
seekBar2.setProgress(mediaPlayer.getCurrentPosition());
}
},0,1000);
public void reset(View v) {
mediaPlayer.reset();
}
Try this to Reset Your mediaPlayer
public void reset(View v) {
mediaPlayer.seekTo(0);
mediaPlayer.start();
}
Try this to update your seekbar
private Handler mHandler = new Handler();
//you have to update Seekbar on UI thread
Your.Activity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
if(mediaPlayer != null){
int mCurrentPosition = mediaPlayer.getCurrentPosition() / 1000;
seekBar2.setProgress(mCurrentPosition);
}
mHandler.postDelayed(this, 1000);
}
});
and whenyou need to update the MediaPlayer's position while user drag your SeekBar use below code
seekBar2.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if(mediaPlayer != null && fromUser){
mediaPlayer.seekTo(progress * 1000);
}
}
});

How to use Sound with Toast in Android

I want to play a sound when my toast pops up in my android app.
Here is my code for the toast in my main class:
private void workEndNotification() {
//Custom Toast notification for the Work End Reminder.
LayoutInflater inflaterWork = getLayoutInflater();
View toastLayout = inflaterWork.inflate(R.layout.work_notification_toast, (ViewGroup) findViewById(R.id.toast_root_view));
TextView header = (TextView) toastLayout.findViewById(R.id.toast_header);
header.setText("Work Day Over Soon!");
final Toast toastWork = new Toast(getApplicationContext());
toastWork.setGravity(Gravity.CENTER, 0, 0);
toastWork.setDuration(Toast.LENGTH_SHORT);
toastWork.setView(toastLayout);
toastWork.show();
myHandler.postDelayed(new Runnable() {
public void run() {
toastWork.cancel();
}
}, 1);
};
Here is the sound code in my SoundPool class (http://www.vogella.com/tutorials/AndroidMedia/article.html):
class PlaySound extends Activity implements OnTouchListener {
private SoundPool soundPool;
private int soundID;
boolean loaded = false;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.work_notification_toast);
View view = findViewById(R.id.toast_header);
view.setOnTouchListener(this);
// Set the hardware buttons to control the music
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
// Load the sound
soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool soundPool, int sampleId,int status) {
loaded = true;
}
});
soundID = soundPool.load(this, R.raw.sound1, 1);
}
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// Getting the user sound settings
AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
float actualVolume = (float) audioManager
.getStreamVolume(AudioManager.STREAM_MUSIC);
float maxVolume = (float) audioManager
.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float volume = actualVolume / maxVolume;
// Is the sound loaded already?
if (loaded) {
soundPool.play(soundID, volume, volume, 1, 0, 1f);
Log.e("Test", "Played sound");
}
}
return false;
}
}
I know I am not calling it in my toast method, and I know that I am using a touchview. How can I make it so the sound appears only when the toast appears, at the same time that is. I have been trying, but have not managed.
I don't want a touch or anything. Just for it to play with the toast simply.
Make a function like this
private void playSound(int resId){
mp = MediaPlayer.create(MainActivity.this, resId);
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.reset();
mediaPlayer.release();
}
});
mp.start();
}
and call it where you are displaying your Toast like this
playSound(R.raw.sound);
You also need to replace the resource so it matches yours
EDIT: You seem to want to play several sounds. You can make a simple sound pool on your own
Make a int array or resource you want to play like this and listen for when the MediaPlayer is done with playing, tell him to play the next one until it played the last one in the array.
public class TestActivity extends Activity implements MediaPlayer.OnCompletionListener {
private final int[] soundResources = {R.raw.sound1, R.raw.sound2, R.raw.sound3};
private int counter = 0;
private MediaPlayer mp;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
playSound(counter);
}
private void playSound(int resId){
mp = MediaPlayer.create(TestActivity.this, resId);
mp.setOnCompletionListener(this);
mp.start();
}
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
mp.reset();
mp.release();
if(counter < soundResources.length ) {
playSound(soundResources[++counter]);
}
}
}

Can't get media player to play mp3

Can anyone tell me why this code doesn't work? It compiles but when I click on the button nothing plays and then it crashes. I'm a noob =[
public class MainActivity extends ActionBarActivity {
private MediaPlayer newTune;
public void playB(View paramView) throws IOException {
newTune = MediaPlayer.create(this, R.raw.b);
if (newTune.isPlaying()) {
// newTune.stop();
} else {
newTune.prepare();
newTune.start();
}
}
There are a couple of problems I can see.
1.) You don't need to call prepare(), as create() has already taken care of this for you.
2.) newTune.isPlaying() is always going to be false, as you've just created a new MediaPlayer.
From the docs:
http://developer.android.com/reference/android/media/MediaPlayer.html
MediaPlayer.onCreate()...
Convenience method to create a MediaPlayer for a given resource id. On
success, prepare() will already have been called and must not be
called again.
Try something like this:
public class MainActivity extends ActionBarActivity {
private MediaPlayer newTune;
public void play() {
newTune = MediaPlayer.create(this, R.raw.b);
newTune.start();
}
}
Here's a simple example of a better way of handling the whole thing:
public class MainActivity extends Activity {
private MediaPlayer mMediaPlayer;
private boolean mIsPrepared;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMediaPlayer = MediaPlayer.create(this, R.raw.raw1);
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mIsPrepared = true;
}
});
Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
playOrPause();
}
});
}
public void playOrPause() {
if (mMediaPlayer == null || !mIsPrepared) {
return;
}
if (!mMediaPlayer.isPlaying()) {
mMediaPlayer.start();
} else {
mMediaPlayer.pause();
}
}
}

How would I set a delay on a toggle button based on the number entered into a number field?

I'm trying to make a toggle button play a song but on a delay. The user has to enter the minutes into a number field (Palette/Text Fields/Number), which will be used to set the delay. I've checked the android developer resources and I still have no idea where to start.
Currently I have this:
public class Main extends Activity {
MediaPlayer mp;
Button startButton;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
mp = MediaPlayer.create(getBaseContext(), R.raw.songthingy);
ToggleButton toggle = (ToggleButton) findViewById(R.id.ToggleButton);
toggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if (isChecked) {
mp.start();
} else {
mp.stop();
}
}
});
mp.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp.release();
}
});
}
A great method is Handler.postDelay. You have to make your action a Runnable, and pass it in the params of them method. Then it will execute after the given time.
Update:
private Runnable doStuff= new Runnable() {
//Notice doStuff is a member of the class.
public void run() {
//do awesome stuff here.
mp.start();
}
};
//...
toggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if (isChecked) {
final Handler mHandler= new Handler();
mHandler.postDelayed(doStuff,1000*30);//30 second delay.
} else {
mp.stop();
}
}
You can Google around and see examples on how to use this. Your code may look very something like this but this code won't run out of the box. You have to fix scopes and meet your requirments.

App crashes on button touch - onTouch method error?

My app keeps crashing when I click the "startButton". I guess the problem is somewhere within that onTouch method, but I've tried solving the problem for hours; disabling different things inside the startButton.setOnTouchListener doesn't make a difference. Can you find anything wrong?
MediaPlayer mp;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
final Button startButton = (Button) this.findViewById(R.id.button1);
final TextView timeLeft = (TextView) this.findViewById(R.id.timeLeft);
MediaPlayer.create(getBaseContext(), R.raw.songthingy);
startButton.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
mp.start();
timeLeft.setText("Status: Initiated");
startButton.setText("Stop");
startButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
mp.release();
}
});
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
timeLeft.setText("Status: Starting in... "
+ millisUntilFinished / 1000);
}
public void onFinish() {
timeLeft.setText("Status: Finished");
}
}.start();
mp.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp.release();
}
});
}
;
return true;
}
});
}
There is no exception stack in question, but one issue I see is:
MediaPlayer mp;
is pointed to null and you are calling
mp.start();
in OnTouchListener, which results in NullPointerException.
I think what you need to do is:
final TextView timeLeft = (TextView) this.findViewById(R.id.timeLeft);
mp= MediaPlayer.create(getBaseContext(), R.raw.songthingy);

Categories