I am working on audio streaming android application in this I get song url from server which i am playing using audio streaming application in this when I start playing it starts and it shows buffering also but my problem is when i move seekbar to particular position which is not buffered seekbar handle is moving back.actually I need to start playing song from that position.
see my code and please tell me how to handle this scenario
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("http://instilltech.netii.net/01LECHIPODAMA.mp3");
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);
}
}
Related
I am creating a simple app which can play music from a url. There is no forward or backward button.. Just play and the music will stream from url and will be played..
I need that control in notification when i click play button where in notification a close button also should be show to stop the music and clear the notification.
How could i implement it..
my Code in Music is
/** 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);
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) {
buttonPlayPause.setImageResource(R.drawable.button_pause);
if(v.getId() == R.id.ButtonTestPlayPause){
/** ImageButton onClick event handler. Method which start/pause mediaplayer playing */
try {
mediaPlayer.setDataSource(audioUrl); // setup song from https://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);
}
public class PlayerScreen extends AppCompatActivity implements SeekBar.OnSeekBarChangeListener {
private MediaPlayer mp;
private Button buttonplaypause;
private int count;
private SeekBar seekbar;
private int curpos, prevpos;
private Bundle b;
private String title;
private final Handler handler = new Handler();
private Runnable updatePositionRunnable = new Runnable() {
public void run() {
seekbar.setProgress(mp.getCurrentPosition());
handler.postDelayed(this, 6000);
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_player_screen);
title = b.getString("title");
mp = new MediaPlayer();
try {
Log.d("message", "message");
mp.setDataSource(Environment.getExternalStorageDirectory().getPath()+"/Music/"+title);
mp.prepare();
} catch (IOException e) {
e.printStackTrace();
}
//mp = MediaPlayer.create(this, R.raw.audio);
buttonplaypause = (Button) findViewById(R.id.buttonPlayPause);
seekbar = (SeekBar) findViewById(R.id.seekBar);
seekbar.setMax(mp.getDuration());
buttonplaypause.setBackgroundResource(R.drawable.play);
seekbar.setOnSeekBarChangeListener(this);
handler.postDelayed(updatePositionRunnable, 6000);
}
public void onProgressChanged(SeekBar mySeekBar, int progress, boolean fromUser) {
if (mp.isPlaying()) {
mp.seekTo(progress);
}
}
public void onStartTrackingTouch(SeekBar mySeekBar) {
}
public void onStopTrackingTouch(SeekBar mySeekBar) {
}
public void toPlayPause(View v) {
if (count % 2 == 0) {
buttonplaypause.setBackgroundResource(R.drawable.pause);
curpos = mp.getCurrentPosition();
prevpos = curpos;
mp.seekTo(curpos);
mp.start();
count++;
buttonplaypause.setBackgroundResource(R.drawable.play);
mp.pause();
count++;
}
}
}
What i'm trying to do is build a music player which displays the list of song in one activity in a List View and when the user taps on an item that particular song should be played in another intent (which is provided by play and pause button). The code provided above is the code for the second activity (the first part i.e. listing the songs is done). The first Activity passes the song title in a bundle which is received by this activity. I am new to android and don't know a lot about it. I don't know how to pass the song from one intent to another so that it is played. The problem I think is in the line setDataSource().
When the second Intent (i.e the code provided above) is opened on tapping item in the List View, the seek bar reaches it's end and no song is played
If there is any other, better way to pass the song from one intent to another feel free to describe it in detail.
I am interested in being able to "prebuffer" VideoView A while VideoView B is playing. Is this possible?
I have two instances of a VideoView.
Only one VideoView will be displayed at a given time, taking up the entire screen of the phone.
The purpose is to reduce the "black screen" when switching from VideoView A and VideoView B.
The app plays a list of videos one after another.
Added Below Code on Jan 19, 2015
The code below grabs a reference to each Player's MediaPlayer. When MediaPlayer A begins rendering, MediaPlayer B will call stop(), release(), setDataSource(url), prepareAsync(). When MediaPlayer A completes, Media Player B will call start().
public class PrebufferingActivity extends Activity {
private VideoView player1;
private VideoView player2;
private MediaPlayer mediaPlayer1;
private MediaPlayer mediaPlayer2;
public static final String URL_1 = "sample1.mp4";
public static final String URL_2 = "sample2.mp4";
public boolean FIRST_TIME = true;
#SuppressLint("NewApi")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_prebuffering);
player1 = (VideoView) findViewById(R.id.videoPlayer1);
player2 = (VideoView) findViewById(R.id.videoPlayer2);
player1.setOnTouchListener(new OnTouchListener(){
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
return false;
}
});
player2.setOnTouchListener(new OnTouchListener(){
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
return false;
}
});
player1.setOnCompletionListener(new OnCompletionListener(){
#Override
public void onCompletion(MediaPlayer mp) {
mediaPlayer2.start();
// Toggle visibility. Player1 is completed. Hide Player1. Show Player2.
player2.setVisibility(View.VISIBLE);
player1.setVisibility(View.INVISIBLE);
}
});
player1.setOnInfoListener(new OnInfoListener(){
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra)
{
if(what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START)
{
mediaPlayer2.stop();
mediaPlayer2.release();
try {
mediaPlayer2.setDataSource(URL_2);
mediaPlayer2.prepareAsync();
} catch (Exception e) {
e.printStackTrace();
}
}
return false;
}
});
player1.setOnPreparedListener(new OnPreparedListener(){
#Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer1 = mp;
if(FIRST_TIME == true) {
mediaPlayer1.start();
player1.requestFocus();
FIRST_TIME = false;
}
}
});
player2.setOnCompletionListener(new OnCompletionListener(){
#Override
public void onCompletion(MediaPlayer mp) {
mediaPlayer1.start();
player1.requestFocus();
// Toggle visibility. Player2 is completed. Hide Player2. Show Player1.
player1.setVisibility(View.VISIBLE);
player2.setVisibility(View.INVISIBLE);
}
});
player2.setOnInfoListener(new OnInfoListener(){
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra)
{
if(what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START)
{
// Prepare Player 2
mediaPlayer1.stop();
mediaPlayer1.release();
try {
mediaPlayer1.setDataSource(PrebufferingActivity.URL_1);
mediaPlayer1.prepareAsync();
} catch (Exception e) {
e.printStackTrace();
}
}
return false;
}
});
player2.setOnPreparedListener(new OnPreparedListener(){
#Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer2 = mp;
}
});
// Player 1
player1.setMediaController(new MediaController(this));
player1.setVideoURI(Uri.parse(URL_1));
// Player 2
player2.setMediaController(new MediaController(this));
player2.setVideoURI(Uri.parse(URL_2));
}
Assuming you are using MediaPlayer to handle the playback of your videos within your VideoView, you can use the prepareAsync() method to achive this. The prepareAsync() method essentially performs the same function as prepare(), which is used to buffer and prepare a video, except it can be done asynchronously in the background.
EDIT
I did something similiar but I actually used SurfaceView. To handle another stream, simply create another instance of MediaPlayer. The following example will create two instances of MediaPlayer and buffer the first video. After the first video is prepared, the second video will be asynchronously buffered. The first MediaPlayer is then bound to the SurfaceView and the first video is started. When the first video is finished playing, the corresponding instance of MediaPlayer is released, the secondary instance is attached, and the second video is automatically started. The following example code has been tested and works fine:
public class StreamingActivity extends Activity implements SurfaceHolder.Callback, MediaPlayer.OnPreparedListener, MediaPlayer.OnCompletionListener
{
MediaPlayer mediaPlayerPrimary;
MediaPlayer mediaPlayerSecondary;
SurfaceHolder surfaceHolder;
SurfaceView surfaceView;
String videoSourcePrimary = "videoSourcePrimaryURL";
String videoSourceSecondary = "videoSourceSecondaryURL";
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.streaming_activity_layout);
/** Create SurfaceView */
surfaceView = (SurfaceView) findViewById(R.id.surface_view);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
}
#Override
public void surfaceCreated(SurfaceHolder arg0)
{
try
{
/** Create MediaPlayer(s) */
mediaPlayerPrimary = new MediaPlayer();
mediaPlayerSecondary = new MediaPlayer();
/** Attach primary MediaPlayer to SurfaceView */
mediaPlayerPrimary.setDisplay(surfaceHolder);
/** Set sources */
mediaPlayerPrimary.setDataSource(videoSourcePrimary);
mediaPlayerSecondary.setDataSource(videoSourceSecondary);
/** Prepare MediaPlayer(s) */
mediaPlayerPrimary.prepare();
mediaPlayerSecondary.prepareAsync();
/** Set listeners */
mediaPlayerPrimary.setOnPreparedListener(this);
mediaPlayerPrimary.setOnCompletionListener(this);
mediaPlayerSecondary.setOnPreparedListener(this);
mediaPlayerSecondary.setOnCompletionListener(this);
/** Set audio stream type */
mediaPlayerPrimary.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayerSecondary.setAudioStreamType(AudioManager.STREAM_MUSIC);
}
catch (Exception e)
{
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3)
{
}
#Override
public void surfaceDestroyed(SurfaceHolder arg0)
{
}
#Override
public void onPrepared(MediaPlayer mp)
{
if (mp == mediaPlayerPrimary)
{
/** First video ready, start playback */
mediaPlayerPrimary.start();
}
else if (mp == mediaPlayerSecondary)
{
/** Second video is ready */
}
}
#Override
public void onCompletion(MediaPlayer mp)
{
/** First video is completed, start second video */
mediaPlayerPrimary.release();
mediaPlayerSecondary.setDisplay(surfaceHolder);
mediaPlayerSecondary.start();
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.streaming_activity_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings)
{
return true;
}
return super.onOptionsItemSelected(item);
}
}
I tried various approaches but nothing is solving my problem. Hope someone here can help me.
Simple requirement is I want to show a spinner until media player window is shown. It sounds easy enough but it is not.
I am calling my mediaplayer class on "Listen" click of alertDialog. Here it is:
alertBox.setCancelable(false)
.setNegativeButton("Listen", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog,int id){
dialog.dismiss();
emp = new EasyMediaPlayer(mp3PopupLayout,buttonPlayPause,seekBarProgress,tv_mp3,downloadURL);
emp.startPlayingMP3();
}
}).show();
And startPlaying function calls chooseToStart(true) which in-turn runs the media player. This class is:
public class EasyMediaPlayer implements OnClickListener, OnTouchListener, OnCompletionListener, OnBufferingUpdateListener{
EasyMediaPlayer(View mp3PopupLayout,ImageView buttonPlayPause,SeekBar seekBarProgress,TextView tv_mp3, String MP3URL){
this.mp3PopupLayout = mp3PopupLayout;
this.buttonPlayPause = buttonPlayPause;
this.seekBarProgress = seekBarProgress;
this.tv_mp3 = tv_mp3;
this.MP3URL = MP3URL;
seekBarProgress.setOnTouchListener(this);
buttonPlayPause.setOnClickListener(this);
}
public void startPlayingMP3(){
mediaFileLengthInMilliseconds = 1;
tv_mp3.setText("");
buttonPlayPause.setImageResource(R.drawable.button_play);
buttonPlayPause.setVisibility(View.GONE);
seekBarProgress.setProgress(0);
seekBarProgress.setSecondaryProgress(0);
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnBufferingUpdateListener(this);
mediaPlayer.setOnCompletionListener(this);
mediaPlayer.setOnErrorListener(new OnErrorListener() {
public boolean onError(MediaPlayer mp, int what, int extra) {
tv_mp3.setText("Error in playing file !!");
return true;
}
});
mp3DownloadWindow = new PopupWindow(mp3PopupLayout, LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT, true);
mp3DownloadWindow.showAtLocation(mp3PopupLayout, Gravity.BOTTOM, 30, 0);
chooseToStart(true);
}
public void chooseToStart(boolean startFlag){
if(startFlag){
try {
mediaPlayer.setDataSource(this.MP3URL);
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.
mediaFileLengthInMilliseconds = mediaPlayer.getDuration(); // gets the song length in milliseconds from URL
} catch (Exception e) {
tv_mp3.setText(e.toString() + "\nClose it");
}
if(!mediaPlayer.isPlaying()){
spinner.cancel();
mediaPlayer.start();
buttonPlayPause.setImageResource(R.drawable.button_pause);
}else {
mediaPlayer.pause();
buttonPlayPause.setImageResource(R.drawable.button_play);
}
primarySeekBarProgressUpdater();
}
}
//other stuff
}
I need to know where and how I can use spinner so it will be shown until media player starts playing.
Any help will be appreciated. Thanks
Use prepareAsync() and setOnPreparedListener() instead of prepare().
mediaPlayer.setDataSource(this.MP3URL);
mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
// Hide whatever you need, mediaPlayer is prepared
mp.start();
}
});
// Show whatever you need, mediaPlayer is preparing
mediaPlayer.prepareAsync();
I've got it set up with a random sound playing onCreate and I have to add a seekbar to track the audio, it moves with track but will not go back if seekbar is pulled back to another part in the audio. Any help would be great, only beginner, sorry for being a noob :).
public class player1 extends Activity implements Runnable {
private MediaPlayer mp;
// Handler to update UI timer, progress bar etc,.
private Handler mHandler = new Handler();;
private Utilities utils;
private int seekForwardTime = 5000; // 5000 milliseconds
private int seekBackwardTime = 5000; // 5000 milliseconds
private int currentSongIndex = 0;
private SeekBar songProgressBar;
private ImageButton playicon;
private ImageButton pauseicon;
private TextView songCurrentDurationLabel;
private TextView songTotalDurationLabel;
private final int NUM_SOUND_FILES = 3; //*****REPLACE THIS WITH THE ACTUAL NUMBER OF SOUND FILES YOU HAVE*****
private SeekBar seek;
private int mfile[] = new int[NUM_SOUND_FILES];
private Random rnd = new Random();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.player_1);
songProgressBar = (SeekBar) findViewById(R.id.songProgressBar);
songTotalDurationLabel = (TextView) findViewById(R.id.songTotalDurationLabel);
songCurrentDurationLabel = (TextView) findViewById(R.id.songCurrentDurationLabel);
pauseicon = (ImageButton) findViewById(R.id.pauseicon);
getActionBar().setDisplayHomeAsUpEnabled(true);
mfile[0] = R.raw.sound01; //****REPLACE THESE WITH THE PROPER NAMES OF YOUR SOUND FILES
mfile[1] = R.raw.sound02; //PLACE THE SOUND FILES IN THE /res/raw/ FOLDER IN YOUR PROJECT*****
mfile[2] = R.raw.sound03;
// Listeners
/**
* Play button click event
* plays a song and changes button to pause image
* pauses a song and changes button to play image
* */
try{
mp = MediaPlayer.create(player1.this, mfile[rnd.nextInt(NUM_SOUND_FILES)]);
mp.seekTo(0);
mp.start();
// set Progress bar values
songProgressBar.setProgress(0);
songProgressBar.setMax(mp.getDuration());
new Thread(this).start();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
}
pauseicon.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
if (v.getId() == R.id.pauseicon)
if(mp.isPlaying()){
mp.pause();
ImageButton pauseicon =(ImageButton) findViewById(R.id.pauseicon);
pauseicon.setImageResource(R.drawable.playicon);
} else {
mp.start();
ImageButton pauseicon =(ImageButton) findViewById(R.id.pauseicon);
pauseicon.setImageResource(R.drawable.pauseicon);
}}});
}
public void run() {
int currentPosition= 0;
int total = mp.getDuration();
while (mp!=null && currentPosition<total) {
try {
Thread.sleep(1000);
currentPosition= mp.getCurrentPosition();
} catch (InterruptedException e) {
return;
} catch (Exception e) {
return;
}
songProgressBar.setProgress(currentPosition);
}
}
public void onStartTrackingTouch(SeekBar seekBar) {
}
public void onStopTrackingTouch(SeekBar seekBar) {
}
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
if(fromUser) mp.seekTo(progress);
}
public boolean onOptionsItemSelected(MenuItem item){
Intent myIntent = new Intent(getApplicationContext(), MainActivity.class);
startActivityForResult(myIntent, 0);
return true;
}
}
The run() method is never called. Instead create a Handler object in the main thread (you did already but it is unused), remove the Thread.sleep() from the run method but add a call to postDelayed() method of the Handler at the end of run() (and maybe a condition to call it only while playing).
After starting playback, call run() method once (from main thread). It will then take care about calling itself subsequently with postDelayed().