I am writing a code for playing a song which is near about 3 min long in background and at the same time I want to show a slideshow of images in the front. There are two problems I am facing:
1. The song stops after 15 seconds.
2. the slideshow of images starts only after song stops.
Please help..thanks in advance...
My code is like this:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mygame);
final Handler mHandler = new Handler();
try {
AssetFileDescriptor afd = getAssets().openFd("AudioFile.mp3");
MediaPlayer player = new MediaPlayer();
player.setDataSource(afd.getFileDescriptor());
player.prepare();
player.start();
} catch (Exception e) {
e.printStackTrace();
}
final Runnable mUpdateResults = new Runnable() {
public void run() {
animateandSlideShow();
}
};
int delay = 15000;
int period = 20000;
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
mHandler.post(mUpdateResults);
}
}, delay, period);
}
Related
I work with MediaPlayer and want to show ProgressBar before calling method mediaPlayer.prepare() (it can take up some time). I tried AsynkTast, Thread, Handler but it is show progressBar only after all operations at the end of clickPlayButton method. What I do wrong?
Thanks!
ProgressBar declaration:
<ProgressBar
android:id="#+id/progressBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="invisible"/>
clickPlayButton method
public void clickPlayButton(View view) {
Thread t = new Thread(new Runnable() {
public void run() {
h.post(updateProgress);
}
});
t.start();
// progressBar.setVisibility(ProgressBar.VISIBLE);
// new ProgressTask().execute();
mTimer = new Timer();
mMyTimerTask = new MyTimerTask();
if(!mediaPlayer.isPlaying()){
btnPlay.setImageResource(R.drawable.player_stop);
try {
mediaPlayer.setDataSource(DATA_HTTP);
mediaPlayer.prepare();
}
catch (Exception e) { e.printStackTrace(); }
mediaPlayer.start();
mTimer.schedule(mMyTimerTask, 10, 5000);
}
else {
btnPlay.setImageResource(R.drawable.player_play);
mediaPlayer.pause();
mTimer.cancel();
}
// progressBar.setVisibility(ProgressBar.INVISIBLE);
}
Handler h = new Handler();
Runnable updateProgress = new Runnable() {
public void run() {
progressBar.setVisibility(View.VISIBLE);
}
};
I am working on an app with recorder and player. I am using mediaplayer to play the recorded .wav file and meantime I want to update to a seekbar. Everything is working fine But my problem is mediaplayer progress updation to seekbar is not happening smoothly, If we are playig a small file, thumb of the seekbar jumps in seconds or between.
Can anyone help me with a workaround to make it smooth seeking of the progress in seekbar. My code is shown below.I am totlay stuck here.
mediaPlayerIntiate();
mediaPlayerSetSource();
mMediaPlayer.start();
task = new TimerTask() {
#Override
public void run() {
Graphbar.post(new Runnable() {
#Override
public void run() {
if (mMediaPlayer != null) {
if (playButtonState == MediaMode.PLAY) {
if (mMediaPlayer.isPlaying()) {
Graphbar.setProgress(mMediaPlayer
.getCurrentPosition());
mediaPlayerUpdateTimer(mMediaPlayer
.getCurrentPosition());
enableRewindandForward();
}
}
}
}
});
}
};
timer = new Timer();
timer.schedule(task, 0, 8);
mMediaPlayer.getCurrentPosition() Return current Time in millisecond and you are updating this to Seekbar which maximum capacity is 100. Make one formula to with length of file and 100. try this function
MediaPlayer mMediaPlayer = new MediaPlayer();
final SeekBar mSeelBar = new SeekBar(this);
final int duration = mMediaPlayer.getDuration();
final int amoungToupdate = duration / 100;
Timer mTimer = new Timer();
mTimer.schedule(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
if (!(amoungToupdate * mSeelBar.getProgress() >= duration)) {
int p = mSeelBar.getProgress();
p += 1;
mSeelBar.setProgress(p);
}
}
});
};
}, amoungToupdate);
And this process should be called when Media player start playing. inside
mediaPlayer.setOnPreparedListener(new OnPreparedListener(){
#Override
public void onPrepared(MediaPlayer mp) {
**// call here**
}
});
Update
Update 125 times in seconds is not something you should do. Please increase your interval for updating SeekBar. I adding this after reading comments of NullPointer
seekbar.setProgress() only accepts int. Hence, most of us tend to pass the elapsed percentage to this method. However, if you need much smoother progression, then you can use the duration in milliseconds as the MAX. Then we get to update the progression of the seekbar every millisecond. Below is an example and I have updated it every 15th millisecond as almost every android phone comes with a refresh rate of 60 fps (frames per second).
try{
mediaPlayer.start();
seekbar.setProgress(0);
seekbar.setMax(mediaPlayer.getDuration());
// Updating progress bar
seekHandler.postDelayed(updateSeekBar, 15);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
}
/**
* Background Runnable thread
* */
private Runnable updateSeekBar = new Runnable() {
public void run() {
long totalDuration = mediaPlayer.getDuration();
long currentDuration = mediaPlayer.getCurrentPosition();
// Displaying Total Duration time
remaining.setText(""+ milliSecondsToTimer(totalDuration-currentDuration));
// Displaying time completed playing
elapsed.setText(""+ milliSecondsToTimer(currentDuration));
// Updating progress bar
seekbar.setProgress((int)currentDuration);
// Call this thread again after 15 milliseconds => ~ 1000/60fps
seekHandler.postDelayed(this, 15);
}
};
/**
* Function to convert milliseconds time to
* Timer Format
* Hours:Minutes:Seconds
* */
public String milliSecondsToTimer(long milliseconds){
String finalTimerString = "";
String secondsString = "";
// Convert total duration into time
int hours = (int)( milliseconds / (1000*60*60));
int minutes = (int)(milliseconds % (1000*60*60)) / (1000*60);
int seconds = (int) ((milliseconds % (1000*60*60)) % (1000*60) / 1000);
// Add hours if there
if(hours > 0){
finalTimerString = hours + ":";
}
// Prepending 0 to seconds if it is one digit
if(seconds < 10) {
secondsString = "0" + seconds;
}else {
secondsString = "" + seconds;
}
finalTimerString = finalTimerString + minutes + ":" + secondsString;
// return timer string
return finalTimerString;
}
Here is how i handle the seekbar;
mediaPlayer.setOnPreparedListener(new OnPreparedListener(){
#Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer.start();
new SeekBarHandler().execute();
});
Now i have an Async Task called SeekBarHandler that handles the seekbar like this:
public class SeekBarHandler extends AsyncTask<Void, Void, Void> {
#Override
protected void onPostExecute(Void result) {
Log.d("##########Seek Bar Handler ################","###################Destroyed##################");
super.onPostExecute(result);
}
#Override
protected void onProgressUpdate(Void... values) {
seekBar.setProgress(mediaPlayer.getCurrentPosition());
super.onProgressUpdate(values);
}
#Override
protected Void doInBackground(Void... arg0) {
while(mediaPlayer.isPlaying()&&isViewOn==true) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
onProgressUpdate();
}
return null;
}
}
Now in my onPause, i terminate the AsyncTask as it doesnt make sense to keep the thread going when the user is not able to see the seekbar
protected void onPause() {
isViewOn=false;
super.onPause();
}
And on onResume i start the AsyncTaskAgain like this
protected void onResume() {
isViewOn=true;
new SeekBarHandler().execute();
super.onResume();
}
As you can see i use a boolean flag isViewOn to check whether the view is on or not to handle the seekbar.
player.prepare(); // or start()
ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
service.scheduleWithFixedDelay(new Runnable()
{
#Override
public void run()
{
progressBar.setProgress(player.getCurrentPosition());
}
}, 1, 1, TimeUnit.MICROSECONDS);
The problem you're experiencing has to do with the way Android's SeekBar is designed/implemented. While it functions very well, you're limited by a combination of segments used (i.e. seekbar.setMax(int)) and the delay time of your Handler.
That being said, I subclassed SeekBar to make my own SmoothSeekBar that uses ViewPropertyAnimators instead of a Handler.
Check it out here: https://github.com/Indatus/Android-SmoothSeekBar
private void startPlaying() {
mediaPlayer = new MediaPlayer();
try {
mediaPlayer.reset();
mediaPlayer.setDataSource(audioPlayerName);
mediaPlayer.prepare();
mediaPlayer.start();
setAudioProgress(); //call method
} catch (Exception e) {
e.printStackTrace();
}
}
public void setAudioProgress() {
total_duration = mediaPlayer.getDuration();
binding.total.setText(timeConversion((long) total_duration));
binding.current.setText(timeConversion((long) current_pos));
binding.seekbar.setMax((int) total_duration);
runnable = new Runnable() {
#Override
public void run() {
try {
current_pos = mediaPlayer.getCurrentPosition();
binding.current.setText(timeConversion((long) current_pos));
binding.seekbar.setProgress((int) current_pos);
handlerProgressBar.postDelayed(this, 1000);
Log.e(LOG_TAG, "11111");
} catch (IllegalStateException ed) {
ed.printStackTrace();
}
}
};
handlerProgressBar.postDelayed(runnable, 1000);
}
I am attempting to play a notification sound once every two seconds. My code is as follows:
final Handler myHandler = new Handler();
mMediaPlayer = new MediaPlayer();
final Runnable mMyRunnable = new Runnable()
{
#Override
public void run()
{
try
{
mMediaPlayer.setDataSource(getBaseContext(), getAlarmUri(alarm_number));
final AudioManager audioManager = (AudioManager) getBaseContext().getSystemService(Context.AUDIO_SERVICE);
if (audioManager.getStreamVolume(AudioManager.STREAM_ALARM) != 0)
{
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
mMediaPlayer.prepare();
mMediaPlayer.start();
}
}
catch (IOException e)
{
}
}
};
mMediaPlayer.setOnCompletionListener(new OnCompletionListener()
{
#Override
public void onCompletion(MediaPlayer mp)
{
myHandler.postDelayed(mMyRunnable, 2000);
}
});
myHandler.post(mMyRunnable);
When the code executes, the notification sound plays once and then I get an IllegalStateException at the line mMediaPlayer.setDataSource(...
I have no idea why.
NO! You should use a Timer which will execute a TimerTask for a repeat rate that you choose:
Timer timer = new Timer();
TimerTask task = new TimerTask()
{
#Override
public void run()
{
// Do your work here
}
};
timer.schedule(task, 'DELAY_FOR_EXECUTION', 'TIME_TO_WAIT');
example:
`//timer.schedule(task, 0, 5000);`
This will run immediatly, every 5 secs
I am working on Android , I am creating a player for audio songs. I want to play a song only for just 30 seconds. After that, player must be closed. It should be start again, if I press START button again.
This is the code for creating a media player:
MediaPlayer mediaPlayer = new MediaPlayer();
public void songPreview(String songURL){
try{
mediaPlayer=new MediaPlayer();
mediaPlayer.setDataSource(songURL);
mediaPlayer.prepare();
mediaPlayer.start();
} catch(Exception ex){
ex.printStackTrace();
}
}
Please suggest me what code should I use to play my song only for 30 seconds after that it will stop, and if I want to play again then I have to press start button.
Note: Please provide me logic to stop media player after 30 second.
Thank you in advance.
use countdownTimer to complete your goal in which you can set countdown timer till 30 second manually. when countdown finish process it will go to finish method and execute finish method code
::
CountDownTimer cntr_aCounter = new CountDownTimer(3000, 1000) {
public void onTick(long millisUntilFinished) {
mp_xmPlayer2.start();
}
public void onFinish() {
//code fire after finish
mp_xmPlayer2.stop();
}
};cntr_aCounter.start();
private void playSoundForXSeconds(final Uri soundUri, int seconds) {
if(soundUri!=null) {
final MediaPlayer mp = new MediaPlayer();
try {
mp.setDataSource(Settings.this, soundUri);
mp.prepare();
mp.start();
}catch(Exception e) {
e.printStackTrace();
}
Handler mHandler = new Handler();
mHandler.postDelayed(new Runnable() {
public void run() {
try {
mp.stop();
}catch(Exception e) {
e.printStackTrace();
}
}
}, seconds * 1000);
}
}
This method jumps to the end of the track after a given time and allows the native onCompleted callback do its work. You'd obviously need to expand the code to handle any pause events fired before the playback completes.
private static void startMedia(final MediaPlayer mediaPlayer, #Nullable Integer previewDuration) {
mediaPlayer.start();
if( previewDuration != null) {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
mediaPlayer.seekTo(mediaPlayer.getDuration());
}
}, previewDuration);
}
}
Scenario
I have a problem that starts to drive me nuts. In one activity I have the following scenario. On create:
- create a GPS Listner
- create a Location Listener
- Start GPS listner and location listener
- Start a asyncTask that downloads a map from the web / or load it from cache
- play a wav file which is a raw resource, very small (around 63 Kilo) which is short, basically it says: "Let's head to the start point" and it makes visible a textview for 10 seconds.
Problem
Rarely the sound gets play fully. Sometimes I hear only "Let's head", sometimes "Let's head to the star", sometimes no play at all. It's like something else is blocking the sound. I moved the sound in its own thread but still no success:
Code
private void ShowTextPlayVoice(String message, int soundResId)
{
txtProceed.setText(message);
txtProceed.setVisibility(View.VISIBLE);
final int soundId = soundResId;
Handler splashHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
txtProceed.setVisibility(View.INVISIBLE);
break;
}
super.handleMessage(msg);
}
};
Message msg = new Message();
msg.what = 0;
splashHandler.sendMessageDelayed(msg, 10000);
Thread thread = new Thread() {
public void run() {
MediaPlayer mp = MediaPlayer.create(ctx, soundId);
mp.start();
mp.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
mp.release();
}
});
}
};
thread.start();
}
Thank you all for help.
After some tries, here is a working solution
private MediaPlayer mediaPlayer = new MediaPlayer();
private void ShowTextPlayVoice(String message, int soundResId)
{
txtProceed.setText(message);
txtProceed.setVisibility(View.VISIBLE);
Handler splashHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
txtProceed.setVisibility(View.INVISIBLE);
break;
}
super.handleMessage(msg);
}
};
Message msg = new Message();
msg.what = 0;
splashHandler.sendMessageDelayed(msg, 10000);
new SoundTask().execute(soundResId);
}
protected class SoundTask extends AsyncTask<Integer, Void, Void>
{
#Override
protected Void doInBackground(Integer... params)
{
AssetFileDescriptor afd = ctx.getResources().openRawResourceFd(params[0]);
try
{
//final MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.reset();
mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getDeclaredLength());
mediaPlayer.prepare();
mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
public void onPrepared(MediaPlayer arg0) {
mediaPlayer.seekTo(0);
mediaPlayer.start();
});
}
});
afd.close();
}
catch (Exception e) {
}
return null;
}
}