Android: How to stop media (mp3) in playing when specific milliseconds come? - android

I have an mp3 file and I want to play a specific word in it. I have a start time (6889 ms) and end time (7254 ms).
I have these codes:
package com.example.playword;
import java.io.IOException;
import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.widget.TextView;
public class PlayWord extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final TextView tv = new TextView(this);
tv.setText("Playing...");
setContentView(tv);
final MediaPlayer mPlayer = MediaPlayer.create(this, R.raw.nicholas);
try {
mPlayer.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mPlayer.seekTo(6889); //this is the start time
mPlayer.start();
//how can I end it at 7254 ms?
}
}

The best approach is to use a Handler to time the stopping of the playback. Start the player and then use the Handler's postDelayed to schedule the execution of a Runnable that will stop the player. You should also start the player only after the initial seek completes. Something like this:
public class PlayWord extends Activity implements MediaPlayer.OnSeekCompleteListener {
Handler mHandler;
MediaPlayer mPlayer;
int mStartTime = 6889;
int mEndTime = 7254;
final Runnable mStopAction = new Runnable() {
#Override
public void run() {
mPlayer.stop();
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final TextView tv = new TextView(this);
tv.setText("Playing...");
setContentView(tv);
mHandler = new Handler();
mPlayer = MediaPlayer.create(this, R.raw.nicholas);
mPlayer.setOnSeekCompleteListener(this);
mPlayer.seekTo(mStartTime);
}
#Override
public void onDestroy() {
mPlayer.release();
}
#Override
public void onSeekComplete (MediaPlayer mp) {
mPlayer.start();
mHandler.postDelayed(mStopAction, mEndTime - mStartTime);
}
}
Note also that the MediaPlayer.create method you are using returns a MediaPlayer that has already been prepared and prepare should not be called again like you are doing in your code.on the screen. I also added a call to release() when the activity exits.
Also, if you want to update the UI when the seek completes, be aware that this method is usually called from a non-UI thread. You will have to use the handler to post any UI-related actions.

In Oncreate Method ,use the below 4 lines code:
MediaPlayer mPlayer = MediaPlayer.create(this, R.raw.nicholas);
mPlayer.start();
mPlayer.seekTo(startTime);
updatePlayerPostion();
private Handler handler=new Handler(){
#Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
updatePlayerPostion();
}
};
updatePlayerPostion()
{
handler.removeCallbacks(r);
if(player.getCurrentPosition==7254)
player.stop();
else
handler.postDelayed(r, 1); //1 millisecond
}
Runnable r=new Runnable(){
#Override
public void run() {
// TODO Auto-generated method stub
updatePlayerPostion()
}
};

Related

Android student asks questions about seekbar applied to MediaPlayer but the seekbar doesn't move

I want to use mediaplayer and seekbar to make a player, it can start, pause, stop, turn back and skip, also, we can pull seekbar to change mediaplayer
Other functions are ok , the mediaplayer can play, but seekbar doesn't move
Maybe it's because the int progress hasn't changed.
I sincerely hope you can help me solve this problem.
thank you for your help
package com.example.user.lab2_leemingchak;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ProgressBar;
import android.widget.SeekBar;
public class MainActivity extends AppCompatActivity implements MediaPlayer.OnPreparedListener,
MediaPlayer.OnCompletionListener {
private MediaPlayer mediaplayer;
private SeekBar seekbar;
private Runnable runnable;
private Handler handble;
private int i;
ImageButton playbtn, stopbtn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//initialize button UIs
playbtn = (ImageButton) findViewById(R.id.playBtn);
stopbtn = (ImageButton) findViewById(R.id.stopBtn);
seekbar = (SeekBar) findViewById(R.id.seekBar);
//convert String url to Uri format using .parse()
Uri path = Uri.parse("android.resource://" + //set the music file in res/raw as default
getPackageName() + "/" + R.raw.enm);
//disable the Play and Stop buttons using .setEnabled()
playbtn.setEnabled(false);
stopbtn.setEnabled(false);
//new a MediaPlayer object
mediaplayer = new MediaPlayer();
//set OnPreparedListener() and OnCompletionListener() to the MediaPlayer object
mediaplayer.setOnPreparedListener(this);
mediaplayer.setOnCompletionListener(this);
seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
i = progress;
if (fromUser) {
mediaplayer.seekTo(progress);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
//prepare and download the audio file, onPrepared() method will be run when ready to play
try {
mediaplayer.reset();
mediaplayer.setDataSource(this, path);
mediaplayer.setAudioStreamType(AudioManager.STREAM_MUSIC); //in streaming mode
mediaplayer.prepareAsync();
} catch (Exception e) {
e.printStackTrace();
}
}
// when Play/Pause button is clicked
// check whether the MediaPlayer is playing or not, start playing if not, otherwise, pause the playback
public void onPlayUrlClick(View view) {
if (mediaplayer.isPlaying()) {
mediaplayer.pause();
playbtn.setEnabled(true);
stopbtn.setEnabled(true);
playbtn.setImageResource(R.drawable.play);
} else {
mediaplayer.start();
playbtn.setEnabled(true);
stopbtn.setEnabled(true);
playbtn.setImageResource(R.drawable.puase);
}
}
// when Stop button is clicked
public void onStopClick(View view) {
mediaplayer.seekTo(0);
playbtn.setEnabled(true);
stopbtn.setEnabled(true);
}
#Override
//when the audio file is ready to play
//enable the Play button and disable the Stop button
public void onPrepared(MediaPlayer mediaplayer) {
seekbar.setMax(mediaplayer.getDuration());
changeSeekbar();
playbtn.setEnabled(true);
stopbtn.setEnabled(false);
}
private void changeSeekbar() {
seekbar.setProgress(mediaplayer.getCurrentPosition());
if (mediaplayer.isPlaying()) {
handble = new Handler();
runnable = new Runnable() {
#Override
public void run() {
changeSeekbar();
}
};
handble.postDelayed(runnable, 1000);
}
};
#Override
//when the audio file plays to the end
public void onCompletion(MediaPlayer mediaplayer) {
mediaplayer.seekTo(0);
}
public void onbackClick(View view) {
i = i - 5;
mediaplayer.seekTo(i);
}
public void onskipClick(View view) {
i = i + 5;
mediaplayer.seekTo(i);
}
}
You didn't give a Looper to your Handler that means it will call changeSeekbar on a random thread. Since UI updates need to happen on the main thread, you should pass the main looper to the handler:
handble = new Handler(Looper.getMainLooper());
runnable = new Runnable() {
#Override
public void run() {
changeSeekbar();
}
};
handble.postDelayed(runnable, 1000);

Interrupt a postdelayed from a handler inside a OnCompletionListener

I have several different Activitys each with a MediaPlayer and a OnCompletionListener to start other activities after the current file has stopped playing. There also is a delay built in the OnCompletion Listener which i achieve through a Handler with postDelayed and it looks like this:
public void onCompletion(MediaPlayer mp) {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
try {
Intent stopplay;
stopplay = new Intent(actualActivity, Class
.forName(nextView));
actualActivity.startActivity(stopplay);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, stopTime);
}
The problem with this is, when i call my SettingsActivity, sometimes it just switches to the Activity that would have come next. So i assume it's hanging in the postDelayd's wait...
How could i get around this?
I also do this in the onStop, onPause and onDestroy of these Activities:
if (mPlayer != null) {
mPlayer.stop();
mPlayer.release();
mPlayer = null;
}
You have to cancel your handler's callback when you don't want it to be executed.
Define your handler at your activity scope(because you have to reach it). Something like this:
public class MainActivity extends Activity {
Handler handler = new Handler();
Runnable myRunnable;
...
}
and define your runnable inside your activity(maybe inside you onCreate method)
myRunnable = new Runnable() {
#Override
public void run() {
try {
Intent stopplay;
stopplay = new Intent(actualActivity, Class
.forName(nextView));
actualActivity.startActivity(stopplay);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
Change your code:
handler.removeCallbacks(myRunnable);
handler.postDelayed(myRunnable, stopTime);
And if you want to cancel it try this:
handler.removeCallbacks(myRunnable);

Play Sound on after activity appears

I use media player to play sounds on my application. It works just fine.
I am playing sound on a separated thread. Even thought, part of the sound plays before activity appear.
I tried to play sound onCreate method. it didn't work. onStart and
onResume. it has some problems. it plays every time activity resumed.
sometimes while I am not even touching the device!
What is the best way to play sound after activity appears?
public boolean played = false;
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
if (!played)
Settings.playSound(dvd.titleImageName.replace("png", "mp3"), this);
played = true;
}
public static MediaPlayer mp = null;
public static void playSound(String fileName, Context c)
{
//MediaPlayer mp = MediaPlayer.create(c, resId);
if (mp!=null)
{
mp.stop(); //error
mp.reset();
mp.release();
}
mp = new MediaPlayer();
AssetFileDescriptor descriptor;
try {
descriptor = c.getResources().getAssets().openFd("sounds/" + fileName);
mp.setDataSource(descriptor.getFileDescriptor(), descriptor.getStartOffset(), descriptor.getLength());
descriptor.close();
mp.prepare();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (mp == null) return;
mp.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
}
});
mp.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
// TODO Auto-generated method stub
}
});
mp.setOnVideoSizeChangedListener(new OnVideoSizeChangedListener() {
#Override
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
// TODO Auto-generated method stub
}
});
new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
mp.start();
}
}).start();
}
Your played variable only works while activity is alive. If it gets killed, played doesn't retain. For example, rotate your device an you'll hear sound playing again.
save state (played) in onSavedInstanceState bundle and restore it in onCreate
Play in in OnCreate or onResume

Mediaplayer service not responding

The activity is calling for the service to play but it does not start. It should prompt the user for the time and then play for that amount of time. I dont have any errors in the logcat.
public class Ship extends Activity implements View.OnClickListener {
public static final Integer[] TIME_IN_MINUTES = { 30, 45, 60, 180, 360 };
public MediaPlayer mediaPlayer;
public Handler handler = new Handler();
public Button button2;
public Spinner spinner2;
public PowerManager.WakeLock wl;
// Initialize the activity
#Override
public void onCreate(Bundle savedInstanceState) {
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Howaya");
super.onCreate(savedInstanceState);
wl.acquire();
setContentView(R.layout.ship);
button2 = (Button) findViewById(R.id.btn2);
button2.setOnClickListener(this);
spinner2 = (Spinner) findViewById(R.id.spinner2);
ArrayAdapter<Integer> adapter = new ArrayAdapter<Integer>(this,
android.R.layout.simple_spinner_item, TIME_IN_MINUTES);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner2.setAdapter(adapter);
}
// Play the sound and start the timer
private void playSound(int resourceId) {
// Cleanup any previous sound files
cleanup();
// Create a new media player instance and start it
// Create the timer to stop the sound after x number of milliseconds
int selectedTime = TIME_IN_MINUTES[spinner2.getSelectedItemPosition()];
handler.postDelayed(runnable, selectedTime * 60 * 1000);
}
// Handle button callback
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn2:
startService(new Intent(this, Shipservice.class));
break;
}
}
protected void onDestroy() {
cleanup();
super.onDestroy();
}
// Stop the sound and cleanup the media player
public void cleanup() {
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
}
// Cancel any previously running tasks
handler.removeCallbacks(runnable);
}
// Runnable task used by the handler to stop the sound
public Runnable runnable = new Runnable() {
public void run() {
cleanup();
}
};
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
wl.release();
}
}
Here is the service class that should be playing.
public class Shipservice extends Service {
static final String TAG=Shipservice.class.getSimpleName();
MediaPlayer player;
#Override
public IBinder onBind(Intent intent) {
return null;
// TODO Auto-generated method stub
}
#Override
public void onCreate() {
// TODO Auto-generated method stub
player = MediaPlayer.create(this, R.raw.ocean_ship);
player.setLooping(false);
Log.d(TAG, "onCreate'd");
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.d(TAG, "onDestroy'd");
}
#Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
Log.d(TAG, "onStart'd");
}
class ship extends Thread{
#Override
public void run() {
// TODO Auto-generated method stub
super.run();
}
}
}
You didn't write code for playing media file.
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(//path to file);
mediaPlayer.prepare();
mediaPlayer.start();
write above code in onStartCommand() method in the service class if you want to play media using service. Note - media played by service will continue to play even if your activity is in background until system kills it. See this guide on how to use services. And consider this guide , how to use mediaplayer.

How to stop Audio?

Here is my problem, when I start the Activity the Music start like I want it to, but when I leave the Activity (by pressing the back button) the Application crashes and "stopped unexpectedly" :( All I want to do is have the audio STOP and go to another activity without the unexpected stop. How can I do this?
public class Run extends Activity {
/** The OpenGL View */
private GLSurfaceView glSurface;
private MediaPlayer mPlayer;
/**
* Initiate the OpenGL View and set our own
*/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Create an Instance with this Activity
glSurface = new GLSurfaceView(this);
//Set our own Renderer and hand the renderer this Activity Context
glSurface.setRenderer(new Lesson06(this));
//Set the GLSurface as View to this Activity
setContentView(glSurface);
new Thread(new Runnable() {
public void run() {
try{
MediaPlayer mPlayer = MediaPlayer.create(Run.this, R.drawable.theygonelovemeformyambition);
mPlayer.setLooping(true);
mPlayer.start();
while(mPlayer.isPlaying()){
android.os.SystemClock.sleep(100);
}
}catch(Exception e){
String TAG = null;
Log.d(TAG,"ERROR PLAYING");
e.printStackTrace();
}
}}).start();
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
mPlayer.release();
}
}
hi before you have to release media player resources. You should stop media player like below.
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
if(mPlayer.isPlaying())
mPlayer.stop();
mPlayer.release();
super.onDestroy();
}
You dont have innitialized the mPlayer
In the public void run() you are just creating a new MediaPlayer
and so when you are trying mPlayer.release(); you are reffering to the null mPlayer and so you get a nullPointerExceptionerror (i guess)

Categories

Resources