How to prepare sound after reset MediaPlayer? - java

I'm trying to make app like soundboard. Now I have small problem with playing the same sound after reset after playing 1st time.
final MediaPlayer SoundOne = MediaPlayer.create(this, R.raw.somesound);
final Button play_SoundOne = (Button) this.findViewById(R.id.play_SoundOne);
play_SoundOne.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SoundOne.start();
}
});
SoundOne.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
SoundOne.reset();
}
});
Can I get help how can I prepare that sound to play again after reset (I do reset to make space in memory for next sounds) but SoundOne.prepare() doesn't work if I put that before .start(). Any advice?

Based on the documentation:
It is a programming error to invoke methods such as getCurrentPosition(), getDuration(), getVideoHeight(), getVideoWidth(), setAudioAttributes(AudioAttributes), setLooping(boolean), setVolume(float, float), pause(), start(), stop(), seekTo(long, int), prepare() or prepareAsync() in the Idle state for both cases. If any of these methods is called right after a MediaPlayer object is constructed, the user supplied callback method OnErrorListener.onError() won't be called by the internal player engine and the object state remains unchanged; but if these methods are called right after reset(), the user supplied callback method OnErrorListener.onError() will be invoked by the internal player engine and the object will be transfered to the Error state.
You cannot immediately start() or prepare after reset(). Based on the documentation for reset:
Resets the MediaPlayer to its uninitialized state. After calling this method, you will have to initialize it again by setting the data source and calling prepare().
The solution would be
Initialize the MediaPlayer again -> set the Data Source -> call prepare.
Alternatively you can avoid performing reset onCompletion. Instead, release the MediaPlayer onStop()
You can update your as follows:
MediaPlayer soundOne = null;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
....
play_SoundOne.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
soundOne.start();
}
});
}
#Override
protected void onStart() {
super.onStart();
if(soundOne == null){
soundOne = MediaPlayer.create(this, R.raw.somesound);
soundOne.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
//Don't reset
}
});
}
}
#Override
protected void onStop() {
super.onStop();
soundOne.release();
soundOne = null;
}

Related

How to stop a MediaPlayer using a button

The code I have so far is:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void SoundPlayer(View view) {
MediaPlayer soundMediaPlayer1 = MediaPlayer.create(this, R.raw.gun_sound);
soundMediaPlayer1.start();
}
public void DogSound(View view) {
MediaPlayer soundMediaPlayer2 = MediaPlayer.create(this, R.raw.cat_sound);
soundMediaPlayer2.start();
}
public void NewSound(View view) {
MediaPlayer soundMediaPlayer3 = MediaPlayer.create(this, R.raw.new_sound);
soundMediaPlayer3.start();
}
public void LaughTrack(View view) {
MediaPlayer soundMediaPlayer12 = MediaPlayer.create(this, R.raw.laugh_sound);
soundMediaPlayer12.start();
}
public void HorseSound(View view) {
MediaPlayer soundMediaPlayer4 = MediaPlayer.create(this, R.raw.horse_sound);
soundMediaPlayer4.start();
}
public void HeySound(View view) {
MediaPlayer soundMediaPlayer5 = MediaPlayer.create(this, R.raw.hey_sound);
soundMediaPlayer5.start();
}
private void Stop() {
startActivity(new Intent(this, MainActivity.class));
}
public void stop(View view) {
Stop();
}
}
The problem I face is that all the sounds overlaps and plays. I have a STOP button set up, but have no idea has to how to make it stops the media. Any feedback is helpful.
Thank you.
First of all, I would use only one Instance of the MediaPlayer. You can then use mediaPlayer.stop() to stop a sound and prepare the next one.
See the state diagram on https://developer.android.com/reference/android/media/MediaPlayer.html
1) Make the object of MediaPlayer in onCreate method don't create in every new method.
2) Before playing the music in another method first use stop() function to stop current playing sound(like mediaPlayer.stop(); ) then play the sound by start().

Updating TextView with timer onTick after leaving and returning to activity

I'm writing a workout app and am trying to implement a rest timer in the Train activity. CountDownTimer located within Train and is called when the user presses a start button.
public CountDownTimer createTimer(long timerDuration) {
Log.d("new timer duration:", "value: " + timerDuration);
return new CountDownTimer(timerDuration, 1000) {
#Override
public void onTick(long millisUntilFinished) {
int progress = (int) (millisUntilFinished / 1000);
secondsLeftOnTimer = progress; // update variable for rest of app to access
// Update the output text
breakTimerOutput.setText(secondsToString(progress));
}
#Override
public void onFinish() { // Play a beep on timer finish
breakTimerOutput.setText(secondsToString(timerDurationSeconds));
playAlertSound(); // TODO: Fix the delay before playing beep.
}
}.start();
}
The timer works, as long as the user stays in the Train activity. If you switch to another activity, the timer continues to run in the background (the beep still occurs), which is what I want. If you go back to the Train activity, however, the breakTimerOutput TextView is no longer updated by onTick.
How can I "reconnect" breakTimerOutput to onTick when the user re-enters the Train activity?
Here is the full code for the activity, just in case.
I would like to suggest to keep the timer inside a Service and use BroadcastReceiver to receive the tick to update the TextView in your TrainActivity.
You need to start the CountDownTimer from the Service. So in the onCreate method of your Service you need to initialize a LocalBroadcastManager.
broadcastManager = LocalBroadcastManager.getInstance(this);
So on each tick on your timer (i.e. onTick method), you might consider calling a function like this.
static final public String UPDATE_TIME = "UPDATE_TIME";
static final public String UPDATED_TIME = "UPDATED_TIME";
public void updateTextView(String time) {
Intent intent = new Intent(UPDATE_TIME);
if(time != null)
intent.putExtra(UPDATED_TIME, time);
broadcastManager.sendBroadcast(intent);
}
Now in your TrainActivity create a BroadcastReceiver.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.copa);
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String time = intent.getStringExtra(YourService.UPDATED_TIME);
// Update your TextView here.
}
};
}
And additionally you need to register and unregister the BroadcastReceiver.
#Override
protected void onStart() {
super.onStart();
LocalBroadcastManager.getInstance(this).registerReceiver((receiver),
new IntentFilter(YourService.UPDATE_TIME)
);
}
#Override
protected void onStop() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
super.onStop();
}

Media PLayer is null in onPause and onResume

I have a media player as global variable and i wanna resume it in onResume and pause it in onPause but both give me nullpointerException. I don't know why it's giving media player as null. I don't thin we need log coz i know the error is nullpointerexception and on the line below mentioned.Here is my code
MediaPlayer md;
int position;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_slide_show);
md = new MediaPlayer();
md.setAudioStreamType(AudioManager.STREAM_MUSIC);
md = MediaPlayer.create(this, R.raw.tone);
md.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
md.start();
}
});
#Override
public void onPause(){
if(md != null ){
md.pause();
position = md.getCurrentPosition();
}
super.onPause();
}
#Override
public void onResume(){
super.onResume();
if(md != null){
md.start(); NullPointerException here
md.seekTo(position);
}
}
#Override
public void onStop(){
if(md != null){
md.stop(); NullPointerException here
md.release();
md = null;}
super.onStop();
}
I think you have misunderstood the android app cycle..when ever you press the home button to come out of the app, onStop() is being called along with onPause().
Because of this reason the MediaPlayer gets released every time, so you are receiving that null pointer Exception.
I believe, that you want to stop the music when the app is closed completely, then replace the onStop() with onDestroy()...that is the only problem related to null pointer Exception..

Seekbar handler Null Exception

In the mainactivity I have create a handler as instance variable:
SeekBar seek_bar;
MediaPlayer player;
Handler seekHandler = new Handler();
Then I have the following two methods in the MainActivity to update the seekbar as the audio plays in media player:
public void getInit() {
seek_bar = (SeekBar) findViewById(R.id.seek_bar);
}
Runnable run = new Runnable() {
#Override
public void run() {
seekUpdation(); **//Exception comes here while closing the app**
}
};
public void seekUpdation() {
seek_bar.setProgress(mMediaPlayer.getCurrentPosition());
seekHandler.postDelayed(run, 1000);
}
The problem I am facing is that when the audio is running and user closes the application using device back buttton. I get NullPointerException. The destroy method of activity is:
#Override
protected void onDestroy() {
super.onDestroy();
if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {
mMediaPlayer.stop();
mMediaPlayer.release();
mMediaPlayer = null;
}
}
Remove any queued messages/callbacks from the handler in your onDestroy. My bet is that its running the last message after onDestroy is called.

How can I download mp3 files and play them in my app?

Could someone show me or teach me how I can download 5 or more mp3 in a file and playing them in my app. I've searched about it but all of people how has asked this, nothing explained it well. I don't want to download only one mp3, but multiple mp3s in a file.here is main.java
public class StreamingMp3Player extends Activity implements OnClickListener, OnTouchListener, OnCompletionListener, OnBufferingUpdateListener{
private ImageButton buttonPlayPause;
private SeekBar seekBarProgress;
public EditText editTextSongURL;
private MediaPlayer mediaPlayer;
private int mediaFileLengthInMilliseconds; // this value contains the song duration in milliseconds. Look at getDuration() method in MediaPlayer class
private final Handler handler = new Handler();
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
initView();
}
/** This method initialise all the views in project*/
private void initView() {
buttonPlayPause = (ImageButton)findViewById(R.id.ButtonTestPlayPause);
buttonPlayPause.setOnClickListener(this);
seekBarProgress = (SeekBar)findViewById(R.id.SeekBarTestPlay);
seekBarProgress.setMax(99); // It means 100% .0-99
seekBarProgress.setOnTouchListener(this);
editTextSongURL = (EditText)findViewById(R.id.EditTextSongURL);
editTextSongURL.setText(R.string.testsong_20_sec);
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnBufferingUpdateListener(this);
mediaPlayer.setOnCompletionListener(this);
}
/** Method which updates the SeekBar primary progress by current song playing position*/
private void primarySeekBarProgressUpdater() {
seekBarProgress.setProgress((int)(((float)mediaPlayer.getCurrentPosition()/mediaFileLengthInMilliseconds)*100)); // This math construction give a percentage of "was playing"/"song length"
if (mediaPlayer.isPlaying()) {
Runnable notification = new Runnable() {
public void run() {
primarySeekBarProgressUpdater();
}
};
handler.postDelayed(notification,1000);
}
}
#Override
public void onClick(View v) {
if(v.getId() == R.id.ButtonTestPlayPause){
/** ImageButton onClick event handler. Method which start/pause mediaplayer playing */
try {
mediaPlayer.setDataSource(editTextSongURL.getText().toString()); // setup song from http://www.hrupin.com/wp-content/uploads/mp3/testsong_20_sec.mp3 URL to mediaplayer data source
mediaPlayer.prepare(); // you must call this method after setup the datasource in setDataSource method. After calling prepare() the instance of MediaPlayer starts load data from URL to internal buffer.
} catch (Exception e) {
e.printStackTrace();
}
mediaFileLengthInMilliseconds = mediaPlayer.getDuration(); // gets the song length in milliseconds from URL
if(!mediaPlayer.isPlaying()){
mediaPlayer.start();
buttonPlayPause.setImageResource(R.drawable.button_pause);
}else {
mediaPlayer.pause();
buttonPlayPause.setImageResource(R.drawable.button_play);
}
primarySeekBarProgressUpdater();
}
}
#Override
public boolean onTouch(View v, MotionEvent event) {
if(v.getId() == R.id.SeekBarTestPlay){
/** Seekbar onTouch event handler. Method which seeks MediaPlayer to seekBar primary progress position*/
if(mediaPlayer.isPlaying()){
SeekBar sb = (SeekBar)v;
int playPositionInMillisecconds = (mediaFileLengthInMilliseconds / 100) * sb.getProgress();
mediaPlayer.seekTo(playPositionInMillisecconds);
}
}
return false;
}
#Override
public void onCompletion(MediaPlayer mp) {
/** MediaPlayer onCompletion event handler. Method which calls then song playing is complete*/
buttonPlayPause.setImageResource(R.drawable.button_play);
}
#Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
/** Method which updates the SeekBar secondary progress by current song loading from URL position*/
seekBarProgress.setSecondaryProgress(percent);
}
You'll need to use 3rd party libraries to support MP3 playback, as it is not included in the standard library. See Wikipedia for a list of alternatives.
For the downloading part, use an URLConnection to get an InputStream on the file and write it to a FileOutputStream. This might help, too: Working unbuffered Streams

Categories