stop background sound of android audio player - java

I'm playing sound in android audio player activity. when i pause that activity, the sound keep on playing in background. I want to stop that sound when i resume that audio player activity.
here is my code..
can anyone help how i could do this.any help would be much appreciated, thank you :)
public class AndroidBuildingMusicPlayerActivity extends Activity implements
OnCompletionListener, SeekBar.OnSeekBarChangeListener {
private ImageButton btnPlay;
private ImageButton btnForward;
private ImageButton btnBackward;
// private ImageButton btnNext;
// private ImageButton btnPrevious;
// private ImageButton btnPrevious;
private ImageButton btnPlaylist;
private ImageView songimg;
// private ImageButton btnRepeat;
// private ImageButton btnShuffle;
private SeekBar songProgressBar;
private TextView songTitleLabel;
private TextView songCurrentDurationLabel;
private TextView songTotalDurationLabel;
// Media Player
private MediaPlayer mp;
// Handler to update UI timer, progress bar etc,.
private Handler mHandler = new Handler();;
private SongsManager songManager;
private Utilities utils;
private int seekForwardTime = 5000; // 5000 milliseconds
private int seekBackwardTime = 5000; // 5000 milliseconds
private int currentSongIndex = 0;
private boolean isShuffle = false;
private boolean isRepeat = false;
private ArrayList<HashMap<String, String>> songsList = new ArrayList<HashMap<String, String>>();
String[] stringArray = new String[4];
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mediaplayer);
// All player buttons
btnPlay = (ImageButton) findViewById(R.id.btnPlay);
btnForward = (ImageButton) findViewById(R.id.btnForward);
btnBackward = (ImageButton) findViewById(R.id.btnBackward);
// btnNext = (ImageButton) findViewById(R.id.btnNext);
// btnPrevious = (ImageButton) findViewById(R.id.btnPrevious);
btnPlaylist = (ImageButton) findViewById(R.id.btnPlaylist);
songimg = (ImageView) findViewById(R.id.songimg);
// btnShuffle = (ImageButton) findViewById(R.id.btnShuffle);
btnPlaylist = (ImageButton) findViewById(R.id.btnPlaylist);
songProgressBar = (SeekBar) findViewById(R.id.songProgressBar);
songTitleLabel = (TextView) findViewById(R.id.songTitle);
songCurrentDurationLabel = (TextView) findViewById(R.id.songCurrentDurationLabel);
songTotalDurationLabel = (TextView) findViewById(R.id.songTotalDurationLabel);
// Mediaplayer
mp = new MediaPlayer();
songManager = new SongsManager();
utils = new Utilities();
// Listeners
songProgressBar.setOnSeekBarChangeListener(this); // Important
mp.setOnCompletionListener(this); // Important
// Getting all songs list
songsList = songManager.getPlayList();
final String[] stringArray = getIntent().getStringArrayExtra("string-array");
// By default play first song
playSong(stringArray[0]);
songTitleLabel.setText(stringArray[1]);
new DownloadImageTask(songimg).execute(stringArray[2]);
btnPlaylist.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
final String[] option = new String[] {"Share",
"Stop" };
ArrayAdapter<String> adapters = new ArrayAdapter<String>(
AndroidBuildingMusicPlayerActivity.this,
android.R.layout.select_dialog_item, option);
AlertDialog.Builder builder = new AlertDialog.Builder(
AndroidBuildingMusicPlayerActivity.this);
builder.setTitle("Choose Action");
builder.setAdapter(adapters,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
// TODO Auto-generated method stub
if (which == 1) {
mp.stop();
finish();
}
if (which == 0) {
Intent browserIntent = new Intent(
Intent.ACTION_SEND);
browserIntent.setType("text/plain");
browserIntent.putExtra(
android.content.Intent.EXTRA_TEXT,
stringArray[3]);
// ,
// Uri.parse("https://www.youtube.com/watch?v="+ids.get(mPosition)));
startActivity(Intent.createChooser(
browserIntent, "Share Song Link"));
}
}
});
final AlertDialog dialog = builder.create();
dialog.show();
}
});
/**
* Play button click event plays a song and changes button to pause
* image pauses a song and changes button to play image
* */
btnPlay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
// check for already playing
if (mp.isPlaying()) {
if (mp != null) {
mp.pause();
// Changing button image to play button
btnPlay.setImageResource(R.drawable.btn_play);
}
} else {
// Resume song
if (mp != null) {
mp.start();
// Changing button image to pause button
btnPlay.setImageResource(R.drawable.btn_pause);
}
}
}
});
/**
* Forward button click event Forwards song specified seconds
* */
btnForward.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
// get current song position
int currentPosition = mp.getCurrentPosition();
// check if seekForward time is lesser than song duration
if (currentPosition + seekForwardTime <= mp.getDuration()) {
// forward song
mp.seekTo(currentPosition + seekForwardTime);
} else {
// forward to end position
mp.seekTo(mp.getDuration());
}
}
});
/**
* Backward button click event Backward song to specified seconds
* */
btnBackward.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
// get current song position
int currentPosition = mp.getCurrentPosition();
// check if seekBackward time is greater than 0 sec
if (currentPosition - seekBackwardTime >= 0) {
// forward song
mp.seekTo(currentPosition - seekBackwardTime);
} else {
// backward to starting position
mp.seekTo(0);
}
}
});
}
/**
* Receiving song index from playlist view and play the song
* */
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == 100) {
currentSongIndex = data.getExtras().getInt("songIndex");
// play selected song
playSong(stringArray[0]);
}
}
/**
* Function to play a song
*
* #param songIndex
* - index of song
* */
public void playSong(String songpath) {
// Play song
try {
mp.reset();
mp.setDataSource(songpath);
mp.prepare();
mp.start();
// Displaying Song title
// String songTitle = songsList.get(songIndex).get("songTitle");
// songTitleLabel.setText(songTitle);
// Changing Button Image to pause image
btnPlay.setImageResource(R.drawable.btn_pause);
// set Progress bar values
songProgressBar.setProgress(0);
songProgressBar.setMax(100);
// Updating progress bar
updateProgressBar();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Update timer on seekbar
* */
public void updateProgressBar() {
mHandler.postDelayed(mUpdateTimeTask, 100);
}
/**
* Background Runnable thread
* */
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
long totalDuration = mp.getDuration();
long currentDuration = mp.getCurrentPosition();
// Displaying Total Duration time
songTotalDurationLabel.setText(""
+ utils.milliSecondsToTimer(totalDuration));
// Displaying time completed playing
songCurrentDurationLabel.setText(""
+ utils.milliSecondsToTimer(currentDuration));
// Updating progress bar
int progress = (int) (utils.getProgressPercentage(currentDuration,
totalDuration));
// Log.d("Progress", ""+progress);
songProgressBar.setProgress(progress);
// Running this thread after 100 milliseconds
mHandler.postDelayed(this, 100);
}
};
/**
*
* */
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromTouch) {
}
/**
* When user starts moving the progress handler
* */
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// remove message Handler from updating progress bar
mHandler.removeCallbacks(mUpdateTimeTask);
}
/**
* When user stops moving the progress hanlder
* */
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
mHandler.removeCallbacks(mUpdateTimeTask);
int totalDuration = mp.getDuration();
int currentPosition = utils.progressToTimer(seekBar.getProgress(),
totalDuration);
// forward or backward to certain seconds
mp.seekTo(currentPosition);
// update timer progress again
updateProgressBar();
}
/**
* On Song Playing completed if repeat is ON play same song again if shuffle
* is ON play random song
* */
#Override
public void onCompletion(MediaPlayer arg0) {
// check for repeat is ON or OFF
if (isRepeat) {
// repeat is on play same song again
playSong(stringArray[0]);
} else if (isShuffle) {
// shuffle is on - play a random song
Random rand = new Random();
currentSongIndex = rand.nextInt((songsList.size() - 1) - 0 + 1) + 0;
playSong(stringArray[0]);
} else {
// no repeat or shuffle ON - play next song
if (currentSongIndex < (songsList.size() - 1)) {
playSong(stringArray[0]);
currentSongIndex = currentSongIndex + 1;
} else {
// play first song
playSong(stringArray[0]);
currentSongIndex = 0;
}
}
}
#Override
public void onDestroy() {
super.onDestroy();
//mp.stop();
}
class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public DownloadImageTask(ImageView bmImage) {
this.bmImage = bmImage;
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
// pd.show();
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
#Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
// pd.dismiss();
bmImage.setImageBitmap(result);
}
}
}

Try: Override onStop() and onRestart()
#Override
protected void onStop() {
super.onStop();
if (mp.isPlaying()) {
mp.stop();
// or mp.pause();
}
}
#Override
public void onRestart() {
super.onRestart();
if (mp == null) {
//create mp from current song, for example
mp = MediaPlayer.create(AndroidBuildingMusicPlayerActivity.this, currentSong);
}
mp.start();
}
EDIT:
try:
#Override
protected void onPause() {
super.onPause();
try{
if (mp.isPlaying()) {
mp.pause();
}
}catch(Exception we){
we.printStackTrace();
}
}
#Override
protected void onResume() {
super.onResume();
try{
mp.start();
}catch(Exception we){
we.printStackTrace();
}
}

you should use AUDIO FOCUS and onfocuschangelistener it will solve your problem.

Related

Playing Multiple Mediaplayers with OnCompletionListener in Android Studio

help me, I'm a beginner, I'm trying to make an application in which there is audio that needs to be played, I try to use MediaPlayer, so that the audio can be played and paused, I have implemented these 3 mediaplayer with setOnCompletion and array methods when calling the audio folder,like this:
mediaPlayer.setOnCompletionListener(completionListener);
MediaPlayer.OnCompletionListener completionListener = new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
play++;
if (play < playList.length) {
mediaPlayer = MediaPlayer.create(BackGroundSound.this, playList[play]);
mediaPlayer.start();
} else {
play = 0;
mediaPlayer = MediaPlayer.create(BackGroundSound.this, playList[play]);
mediaPlayer.start();
}
}
};
and this array for file MediaPlayer:
int[] playList = new int[3];
playList[0] = R.raw.madtarqiqc1;
playList[1] = R.raw.madtarqiqc2;
playList[2] = R.raw.madtarqiqc3;
but when I clicked button, the program that I made does not work, the medialayer and button no response, what should I add, I have redesigned this code many times but the results remain the same, is there a code or method that was missed?
This is for the full source code that I have:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
MediaPlayer mediaPlayer;
ImageButton btn1, btn2, btn3;
int[] playList;
int play = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn1 = (ImageButton) findViewById(R.id.play_toggle_ratarqiq1);
btn2 = (ImageButton) findViewById(R.id.play_toggle_ratarqiq2);
btn3 = (ImageButton) findViewById(R.id.play_toggle_ratarqiq3);
int[] playList = new int[3];
playList[0] = R.raw.madtarqiqc1;
playList[1] = R.raw.madtarqiqc2;
playList[2] = R.raw.madtarqiqc3;
mediaPlayer = MediaPlayer.create(this, playList[play]);
mediaPlayer.setOnCompletionListener(completionListener);
}
MediaPlayer.OnCompletionListener completionListener = new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
play++;
if (play < playList.length) {
mediaPlayer = MediaPlayer.create(MainActivity.this, playList[play]);
mediaPlayer.start();
} else {
play = 0;
mediaPlayer = MediaPlayer.create(MainActivity.this, playList[play]);
mediaPlayer.start();
}
}
};
#Override
public void onClick(View view) {
switch (view.getId()){
case R.id.play_toggle_ratarqiq1:
playMusic(0);
break;
case R.id.play_toggle_ratarqiq2:
playMusic(1);
break;
case R.id.play_toggle_ratarqiq3:
playMusic(2);
break;
}
}
private void playMusic(int position) {
mediaPlayer.stop();
mediaPlayer = MediaPlayer.create(this, playList[position]);
mediaPlayer.start();
changeView(position);
}
private void changeView(int position) {
if (position == 0) {
btn1.setImageResource(R.drawable.ic_play_circle_outline_black_24dp);
btn2.setImageResource(R.drawable.ic_pause_circle_outline_black_24dp);
btn3.setImageResource(R.drawable.ic_pause_circle_outline_black_24dp);
} else if (position == 1) {
btn1.setImageResource(R.drawable.ic_pause_circle_outline_black_24dp);
btn2.setImageResource(R.drawable.ic_play_circle_outline_black_24dp);
btn3.setImageResource(R.drawable.ic_pause_circle_outline_black_24dp);
} else if (position == 2) {
btn1.setImageResource(R.drawable.ic_pause_circle_outline_black_24dp);
btn2.setImageResource(R.drawable.ic_pause_circle_outline_black_24dp);
btn3.setImageResource(R.drawable.ic_play_circle_outline_black_24dp);
}
}
}
There are few crucial things that you missed :
to set onClickListner() in those Button objects
to reuse the MediaPlayer instance(you created new one everytime you need)
to properly update the play variable which I believe is the index of currently played song
I tried to make it fully readable as I can. Here is the code for MainActivity:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private MediaPlayer mediaPlayer;
private ImageButton btn1, btn2, btn3;
private int[] playList;
// initializing it to -1 so that it is out of bounds of the array playList
private int play = -1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn1 = findViewById(R.id.play_toggle_ratarqiq1);
btn2 = findViewById(R.id.play_toggle_ratarqiq2);
btn3 = findViewById(R.id.play_toggle_ratarqiq3);
// you forgot to setonclicklistener in these buttons thats why they were not reponding
btn1.setOnClickListener(this);
btn2.setOnClickListener(this);
btn3.setOnClickListener(this);
playList = new int[3];
playList[0] = R.raw.madtarqiqc1;
playList[1] = R.raw.madtarqiqc2;
playList[2] = R.raw.madtarqiqc3;
// use constructor to create a mediaplayer object rather than this static create method
// mediaPlayer = MediaPlayer.create(this, playList[play]);
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnCompletionListener(completionListener);
}
MediaPlayer.OnCompletionListener completionListener = new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
play++;
if (play < playList.length) {
// we will not assign mediaPlayer to new instance instead we will only change data source
// and reuse the single instance everywhere in this activity
// mediaPlayer = MediaPlayer.create(MainActivity.this, playList[play]);
try {
mediaPlayer.setDataSource(MainActivity.this, Uri.parse("android.resource://" + getPackageName() + "/res/raw/"
+ getResources().getResourceName(playList[play])));
mediaPlayer.start();
} catch (IOException e) {
// if things goes wrong we will show Toast
Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_LONG).show();
}
} else {
play = 0;
try {
mediaPlayer.setDataSource(MainActivity.this, Uri.parse("android.resource://" + getPackageName() + "/res/raw/"
+ getResources().getResourceName(playList[play])));
mediaPlayer.start();
} catch (IOException e) {
Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_LONG).show();
}
}
}
};
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.play_toggle_ratarqiq1:
// you can check to see if the song that we want to play is already being played
// so that in that case you can pause it and resume on next click later
// but I leave it to you for the implementation
playMusic(0);
break;
case R.id.play_toggle_ratarqiq2:
playMusic(1);
break;
case R.id.play_toggle_ratarqiq3:
playMusic(2);
break;
}
}
private void playMusic(int position) {
// with the code below, for the first time the mediaplayer wouldn't have started playing
// and you would have already called stop() on it.
// mediaPlayer.stop();
// Also, assigning mediaPlayer obj to new instance will wipe out the onCompletionListener
// you set earlier.
// mediaPlayer = MediaPlayer.create(this, playList[position]);
// check to see if mediaplayer is playing to reset it if it is
if (mediaPlayer.isPlaying() || mediaPlayer.)
mediaPlayer.reset();
// now that it is in idle state, set data source in it
try {
mediaPlayer.setDataSource(this, Uri.parse("android.resource://" + getPackageName() + "/res/raw/"
+ getResources().getResourceName(playList[position])));
// start playback and change btn images accordingly
mediaPlayer.start();
changeView(position);
// also you forgot to update play variable to indicate the index of current song
// that is being played
play = position;
} catch (IOException e) {
Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_LONG).show();
}
}
private void changeView(int position) {
// I guess this needs a little bit of modification as
// For eg: if btn1 is clicked, btn1 should show pause img in theory
// same goes for all other buttons
// try to handle it yourself
if (position == 0) {
btn1.setImageResource(R.drawable.ic_play_circle_outline_black_24dp);
btn2.setImageResource(R.drawable.ic_pause_circle_outline_black_24dp);
btn3.setImageResource(R.drawable.ic_pause_circle_outline_black_24dp);
} else if (position == 1) {
btn1.setImageResource(R.drawable.ic_pause_circle_outline_black_24dp);
btn2.setImageResource(R.drawable.ic_play_circle_outline_black_24dp);
btn3.setImageResource(R.drawable.ic_pause_circle_outline_black_24dp);
} else if (position == 2) {
btn1.setImageResource(R.drawable.ic_pause_circle_outline_black_24dp);
btn2.setImageResource(R.drawable.ic_pause_circle_outline_black_24dp);
btn3.setImageResource(R.drawable.ic_play_circle_outline_black_24dp);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
// releasing the mediaplayer is must so that you do not leak resources
if (mediaPlayer != null)
mediaPlayer.release();
}
}

Is there a way to set adapter position of view holder of recycler view programmatically?

Just like a view holder has the method getAdapterPosition(), I want to write my own setAdapterPosition() for the view holder(which doesn't exist).
What am I working on?
Currently, I am working on a project wherein I have to list 10 songs in the form of a recycler view and then play them, if any particular song is clicked. Each list item contains the song name, a seek bar and a play button
I have implemented this part, by adding all the media player contros inside the adapter class.
What do I want?
Currently, this model used mediaPlayer.setLooping(true) so that as soon as a song finished, it kept looping till some other song is clicked for playing.
Now I want to extend this model to an "autoplay" version so that as soon as a song is finished, the next song is played
What is the problem?
The seekBar progress and playButton image transition to a pauseButton image were happening with the call
viewHolder.seekBar.setProgress(...)
viewHolder.playButton.setImageDrawable(...)
Since this was happening on the
viewHolder.itemView.setOnClickListener(...)
as soon as a new song was clicked, the seekBar and playButton image were being updated.
Now, when the song is completed, I don't want the user to click on the next song to play it. I want it to be autoplayed, but I am unable to understand, how do I change myViewHolder position accordingly.
Suppose Song 0 has finished playing and Song 1 has started playing, viewHolder.getAdapterPosition() still returns 0 instead of 1. Hence the seekBar & playButton of song 0 is being updated and not of song 1.
I want to be able to do something like this
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
int nextSongPosition, currentSongPosition;
currentSongPosition = viewHolder.getAdapterPosition();
if(currentSongPosition==(songs.size()-1)){
nextSongPosition = 0;
//do some miracle so that viewHolder.getAdapterPosition() now shows 0 instead of currentSongPosition
}else{
nextSongPosition = currentSongPosition + 1;
//do some miracle so that viewHolder.getAdapterPosition() now shows nextSongPosition instead of the currentSongPosition;
}
}
});
As clear from the question statement, I want to implement something similar to a setAdapterPosition() which doesn't exist.
EDIT 1
onBindViewHolder Code:
#Override
public void onBindViewHolder(#NonNull final ViewHolder viewHolder, int i) {
Song song = songs.get(i);
viewHolder.itemView.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
audioManager = (AudioManager) Objects.requireNonNull(context).getSystemService(Context.AUDIO_SERVICE);
if(mediaPlayer.isPlaying()){
pauseMediaPlayer(viewHolder);
}else{
StorageReference storageRef = FirebaseStorage.getInstance().getReference("Songs");
StorageReference dateRef = storageRef.child(song.getStoredAs());
dateRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
try {
mediaPlayer.setDataSource(uri.toString());
mediaPlayer.prepare();
viewHolder.seekBar.setMax(mediaPlayer.getDuration() / 1000);
mSeekbarUpdateHandler = new Handler();
mUpdateSeekbar = new Runnable() {
#Override
public void run() {
if (viewHolder.seekBar != null && mediaPlayer != null) {
try{
viewHolder.seekBar.setProgress(mediaPlayer.getCurrentPosition() / 1000);
mSeekbarUpdateHandler.postDelayed(this, 50);
} catch(IllegalStateException e){
Log.i("Exception",e.toString());
}
}
}
};
viewHolder.seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser && mediaPlayer != null)
mediaPlayer.seekTo( progress * 1000);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
startMediaPlayer(viewHolder);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Handle any errors
Log.i("Song Loading Error", exception.toString());
}
});
}
}
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
int nextSongPosition, currentSongPosition;
currentSongPosition = viewHolder.getAdapterPosition();
if(currentSongPosition==(songs.size()-1)){
nextSongPosition = 0;
//do some miracle so that viewHolder.getAdapterPosition() now shows 0 instead of currentSongPosition
}else{
nextSongPosition = currentSongPosition + 1;
//do some miracle so that viewHolder.getAdapterPosition() now shows nextSongPosition instead of the currentSongPosition;
}
}
});
}
pauseMediaPlayer(..) & startMediaPlayer(..) Code:
private void pauseMediaPlayer(ViewHolder viewHolder) {
int result = audioManager.requestAudioFocus(this, AudioManager.USE_DEFAULT_STREAM_TYPE, AudioManager.AUDIOFOCUS_GAIN);
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
isSongPlaying = false;
viewHolder.playButton.setImageResource(R.drawable.play_button);
if (mediaPlayer != null) {
mediaPlayer.pause();
}
}
}
private void startMediaPlayer(ViewHolder viewHolder) {
int result = audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
isSongPlaying = true;
viewHolder.playButton.setImageResource(R.drawable.pause_button);
if (mediaPlayer != null) {
//mediaPlayer.setLooping(true);
mediaPlayer.start();
}
mSeekbarUpdateHandler.postDelayed(mUpdateSeekbar, 0);
}
}

MusicPlayer crashes while clicking the back button in android

I made a simple music player which can play some songs in the background. Going to the homescreen and reopening the app through notification works as well. The only Problem I have is that when music playing is complete and if I press the back button(going to parent activity) in the music player activity my app crashes.How can I fix this problem?
playmusic.java
#Override
public void onDestroy() {
currentSongIndex = -1;
mHandler.removeCallbacks(mUpdateTimeTask);
Log.d("Player Service", "Player Service Stopped");
if (mp != null) {
if (mp.isPlaying()) {
mp.stop();
}
mp.release();
}
if (phoneStateListener != null) {
telephonyManager.listen(phoneStateListener,
PhoneStateListener.LISTEN_NONE);
}
// --Unregister headsetReceiver
unregisterReceiver(headsetReceiver);
super.onDestroy();
}
playerservice
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
if (!PlayerService.mp.isPlaying()) {
stopService(playerService);
}
super.onDestroy();
}
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.kaveh.googleplay2, PID: 29453
java.lang.RuntimeException: Unable to start service com.example.kaveh.googleplay2.PlayerService#527b4da4 with null: java.lang.NullPointerException
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2705)
at android.app.ActivityThread.access$2100(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1293)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.example.kaveh.googleplay2.PlayerService.initUI(PlayerService.java:311)
at com.example.kaveh.googleplay2.PlayerService.onStartCommand(PlayerService.java:142)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2688)
at android.app.ActivityThread.access$2100(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1293)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
08-25 13:37:06.274 543-29470/system_process D/dalvikvm: GC_FOR_ALLOC freed 1760K, 28% free 10140K/14056K, paused 10ms, total 10ms
08-25 13:37:07.326 543-590/system_process D/MobileDataStateTracker: default: setPolicyDataEnable(enabled=true)
08-25 13:37:07.694 29453-29453/com.example.kaveh.googleplay2 I/Process: Sending signal. PID: 29453 SIG: 9
08-25 13:37:07.694 543-590/system_process D/MobileDataStateTracker: default: setPolicyDataEnable(enabled=true)
EDIT
PlayerService.java
public class PlayerService extends Service implements
OnClickListener, MediaPlayer.OnInfoListener,
SeekBar.OnSeekBarChangeListener, MediaPlayer.OnBufferingUpdateListener
, OnPreparedListener, MediaPlayer.OnErrorListener, MediaPlayer.OnSeekCompleteListener
, MediaPlayer.OnCompletionListener {
private WeakReference<ImageView> btnPlay, btnForward, btnBackward;
private WeakReference<SeekBar> songProgressBar;
private WeakReference<TextView> songCurrentDurationLabel;
private WeakReference<TextView> songTotalDurationLabel;
public static MediaPlayer mp;
// Handler to update UI timer, progress bar etc,.
static Handler mHandler = new Handler();
// private SongsManager songManager;
private Utility utils;
private int seekForwardTime = 5000; // 5000 milliseconds
private int seekBackwardTime = 5000; // 5000 milliseconds
public static int currentSongIndex = -1;
public static int songindexForPause = 0;
// Set up broadcast identifier and intent
public static final String BROADCAST_BUFFER = "com.9android.net.broadcastbuffer";
Intent bufferIntent;
private boolean isPausedInCall = false;
private PhoneStateListener phoneStateListener;
private TelephonyManager telephonyManager;
private static final String TAG = "TELEPHONESERVICE";
Notification status;
private final String LOG_TAG = "NotificationService";
/**
* 29 * The BroadCast Receiver is used to listen system broadcast intent when
* 30 * headsets gets unplugged. If headset gets unplugged, stop music and
* 31 * service.
* 32
*/
private int headsetSwitch = 1;
private BroadcastReceiver headsetReceiver = new BroadcastReceiver() {
private boolean headsetConnected = false;
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
// Log.v(TAG, "ACTION_HEADSET_PLUG Intent received");
if (intent.hasExtra("state")) {
if (headsetConnected && intent.getIntExtra("state", 0) == 0) {
headsetConnected = false;
headsetSwitch = 0;
} else if (!headsetConnected
&& intent.getIntExtra("state", 0) == 1) {
headsetConnected = true;
headsetSwitch = 1;
}
}
switch (headsetSwitch) {
case (0):
headsetDisconnected();
break;
case (1):
break;
}
}
};
#Override
public void onCreate() {
// TODO Auto-generated method stub
mp = new MediaPlayer();
mp.setOnCompletionListener(this);
mp.setOnErrorListener(this);
mp.setOnPreparedListener(this);
mp.setOnBufferingUpdateListener(this);
mp.setOnSeekCompleteListener(this);
mp.setOnInfoListener(this);
mp.reset();
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);//
utils = new Utility();
// Instantiate bufferIntent to communicate with Activity for progress
// dialogue
bufferIntent = new Intent(BROADCAST_BUFFER);
// Register headset receiver
registerReceiver(headsetReceiver, new IntentFilter(
Intent.ACTION_HEADSET_PLUG));
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
initUI();
Bundle extera = intent.getExtras();
if (extera != null) {
String songLink = extera.getString("songLink");
Log.d("SongLink", "SongLink = " + songLink);
if (songLink.compareTo("") != 0)
playSong(songLink);
telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
phoneStateListener = new PhoneStateListener() {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
Log.v(TAG, "Starting CallStateChange");
switch (state) {
case TelephonyManager.CALL_STATE_OFFHOOK:
case TelephonyManager.CALL_STATE_RINGING:// incoming call
if (mp != null) {
pauseMedia();
isPausedInCall = true;
}
break;
case TelephonyManager.CALL_STATE_IDLE:// call finish
if (mp != null) {
if (isPausedInCall) {
isPausedInCall = false;
playMedia();
}
}
break;
}
}
};
telephonyManager.listen(phoneStateListener,
PhoneStateListener.LISTEN_CALL_STATE);
if (intent.getAction().equals(Constants.ACTION.STARTFOREGROUND_ACTION)) {
showNotification();
Toast.makeText(this, "Service Started", Toast.LENGTH_SHORT).show();
}
} else {
if (intent.getAction().equals(Constants.ACTION.PREV_ACTION)) {
Toast.makeText(this, "Clicked Previous", Toast.LENGTH_SHORT).show();
Log.i(LOG_TAG, "Clicked Previous");
} else if (intent.getAction().equals(Constants.ACTION.PLAY_ACTION)) {
Toast.makeText(this, "Clicked Play", Toast.LENGTH_SHORT).show();
Log.i(LOG_TAG, "Clicked Play");
if (mp.isPlaying()) {
if (mp != null) {
mp.pause();
btnPlay.get().setImageResource(R.drawable.play);
Log.d("Player Service", "Pause");
}
} else {
// Resume song
if (mp != null) {
mp.start();
RemoteViews views = new RemoteViews(getPackageName(),
R.layout.status_bar);
RemoteViews bigViews = new RemoteViews(getPackageName(),
R.layout.status_bar_expanded);
views.setImageViewResource(R.id.status_bar_play,
R.drawable.apollo_holo_dark_play);
bigViews.setImageViewResource(R.id.status_bar_play,
R.drawable.apollo_holo_dark_play);
// Changing button image to pause button
btnPlay.get().setImageResource(R.drawable.pause);
}
}
}
// else if (intent.getAction().equals(Constants.ACTION.NEXT_ACTION)) {
// Toast.makeText(this, "Clicked Next", Toast.LENGTH_SHORT).show();
// Log.i(LOG_TAG, "Clicked Next");
// }
else if (intent.getAction().equals(
Constants.ACTION.STOPFOREGROUND_ACTION)) {
Log.i(LOG_TAG, "Received Stop Foreground Intent");
Toast.makeText(this, "Service Stoped", Toast.LENGTH_SHORT).show();
stopForeground(true);
stopSelf();
}
} String songLink = intent.getExtras().getString("songLink");
Log.d("SongLink", "SongLink = " + songLink);
if (songLink.compareTo("") != 0)
playSong(songLink);
// Manage incoming phone calls during playback. Pause mp on incoming,
// resume on hangup.
// Get the telephony manager
telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
phoneStateListener = new PhoneStateListener() {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
// String stateString = "N/A";
Log.v(TAG, "Starting CallStateChange");
switch (state) {
case TelephonyManager.CALL_STATE_OFFHOOK:
case TelephonyManager.CALL_STATE_RINGING:// incoming call
if (mp != null) {
pauseMedia();
isPausedInCall = true;
} break;
case TelephonyManager.CALL_STATE_IDLE:// call finish
// Phone idle. Start playing.
if (mp != null) {
if (isPausedInCall) {
isPausedInCall = false;
playMedia();
}
}
break;
}
}
};
// Register the listener with the telephony manager
telephonyManager.listen(phoneStateListener,
PhoneStateListener.LISTEN_CALL_STATE);
super.onStart(intent, startId);
return START_STICKY;
}
/**
* 131 * #author 9Android.net
* 132
*/
private void initUI() {
songCurrentDurationLabel = new WeakReference(
PlayMusic.songCurrentDurationLabel);
songTotalDurationLabel = new WeakReference(
PlayMusic.songTotalDurationLabel);
btnPlay = new WeakReference(PlayMusic.btnPlay);
btnForward = new WeakReference(PlayMusic.btnForward);
btnBackward = new WeakReference(PlayMusic.btnBackward);
btnPlay.get().setOnClickListener(this);
btnForward.get().setOnClickListener(this);
btnBackward.get().setOnClickListener(this);
songProgressBar = new WeakReference(
PlayMusic.songProgressBar);
songProgressBar.get().setOnSeekBarChangeListener(this);
}
// Send a message to Activity that audio is being prepared and buffering
// started.
private void sendBufferingBroadcast() {
// Log.v(TAG, "BufferStartedSent");
bufferIntent.putExtra("buffering", "1");
sendBroadcast(bufferIntent);
}
// Send a message to Activity that audio is prepared and ready to start
// playing.
private void sendBufferCompleteBroadcast() {
bufferIntent.putExtra("buffering", "0");
sendBroadcast(bufferIntent);
}
// -------------------------------------------------------------------------//
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.btn_play:
if (mp.isPlaying()) {
if (mp != null) {
mp.pause();
// Changing button image to play button
btnPlay.get().setImageResource(R.drawable.play);
Log.d("Player Service", "Pause");
}
} else {
// Resume song
if (mp != null) {
mp.start();
// Changing button image to pause button
btnPlay.get().setImageResource(R.drawable.pause);
}
}
break;
case R.id.btn_forward:
// get current song position
int currentPosition = mp.getCurrentPosition();
// check if seekForward time is lesser than song duration
if (currentPosition + seekForwardTime <= mp.getDuration()) { // forward song mp.seekTo(currentPosition + seekForwardTime); } else { // forward to end position mp.seekTo(mp.getDuration()); } break; case R.id.btn_backward: // get current song position int currentPosition2 = mp.getCurrentPosition(); // check if seekBackward time is greater than 0 sec if (currentPosition2 - seekBackwardTime >= 0) {
// forward song
mp.seekTo(currentPosition + seekBackwardTime);
} else {
// backward to starting position
mp.seekTo(0);
}
break;
}
}
// -------------------------------------------------------------//
public void playSong(String songPath) {
mHandler.removeCallbacks(mUpdateTimeTask);
mp.reset();
if (!mp.isPlaying()) {
try {
mp.setDataSource(songPath);
// Send message to Activity to display progress dialogue
sendBufferingBroadcast();
mp.prepareAsync();
// Changing Button Image to pause image
btnPlay.get().setImageResource(R.drawable.pause);
// set Progress bar values
songProgressBar.get().setProgress(0);
songProgressBar.get().setMax(100);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// Called when the media file is ready for playback.--------------------//
public void onPrepared(MediaPlayer mp) {
// Send a message to activity to end progress dialogue
sendBufferCompleteBroadcast();
playMedia();
}
public void playMedia() {
if (!mp.isPlaying()) {
mp.start();
updateProgressBar();
}
}
// Add for Telephony Manager
public void pauseMedia() {
// Log.v(TAG, "Pause Media");
if (mp.isPlaying()) {
mp.pause();
}
}
public void stopMedia() {
if (mp.isPlaying()) {
mp.stop();
}
}
/**
* 264 * Update timer on seekbar
* 265 *
*/
public void updateProgressBar() {
mHandler.postDelayed(mUpdateTimeTask, 100);
}
/**
* 271 * Background Runnable thread
* 272 *
*/
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
long totalDuration = 0;
try {
totalDuration = mp.getDuration();
} catch (IllegalStateException e) {
e.printStackTrace();
}
long currentDuration = 0;
try {
currentDuration = mp.getCurrentPosition();
} catch (IllegalStateException e) {
e.printStackTrace();
}
songTotalDurationLabel.get().setText(
"" + utils.milliSecondsToTimer(totalDuration));
songCurrentDurationLabel.get().setText(
"" + utils.milliSecondsToTimer(currentDuration));
// Updating progress bar
int progress = (int) (utils.getProgressPercentage(currentDuration,
totalDuration));
// Log.d("Progress", ""+progress);
songProgressBar.get().setProgress(progress);
// Running this thread after 100 milliseconds
mHandler.postDelayed(this, 100);
}
};
/**
* 306 * onProgressChanged
* 307
*/
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromTouch) {
}
/**
* 314 * When user starts moving the progress handler
* 315 *
*/
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// remove message Handler from updating progress bar
mHandler.removeCallbacks(mUpdateTimeTask);
}
/**
* 323 * When user stops moving the progress hanlder
* 324 *
*/
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
mHandler.removeCallbacks(mUpdateTimeTask);
int totalDuration = mp.getDuration();
int currentPosition = utils.progressToTimer(seekBar.getProgress(),
totalDuration);
// forward or backward to certain seconds
mp.seekTo(currentPosition);
// update timer progress again
updateProgressBar();
}
/**
* 339 * On Song Playing completed if repeat is ON play same song again if shuffle
* 340 * is ON play random song
* 341 *
*/
#Override
public void onCompletion(MediaPlayer arg0) {
mp.stop();
mp.release();
}
#Override
public void onDestroy() {
currentSongIndex = -1;
mHandler.removeCallbacks(mUpdateTimeTask);
Log.d("Player Service", "Player Service Stopped");
if (mp != null) {
if (mp.isPlaying()) {
mp.stop();
}
mp.release();
}
if (phoneStateListener != null) {
telephonyManager.listen(phoneStateListener,
PhoneStateListener.LISTEN_NONE);
}
// --Unregister headsetReceiver
unregisterReceiver(headsetReceiver);
super.onDestroy();
}
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
return false;
}
#Override
public void onSeekComplete(MediaPlayer mp) {
}
#Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
}
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
return false;
}
private void headsetDisconnected() {
pauseMedia();
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
private void showNotification() {
// Using RemoteViews to bind custom layouts into Notification
RemoteViews views = new RemoteViews(getPackageName(),
R.layout.status_bar);
RemoteViews bigViews = new RemoteViews(getPackageName(),
R.layout.status_bar_expanded);
// showing default album image
views.setViewVisibility(R.id.status_bar_icon, View.VISIBLE);
views.setViewVisibility(R.id.status_bar_album_art, View.GONE);
bigViews.setImageViewBitmap(R.id.status_bar_album_art,
Constants.getDefaultAlbumArt(this));
Intent notificationIntent = new Intent(this, PlayMusic.class);
notificationIntent.setAction(Constants.ACTION.MAIN_ACTION);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
// Intent previousIntent = new Intent(this, PlayerService.class);
// previousIntent.setAction(Constants.ACTION.PREV_ACTION);
// PendingIntent ppreviousIntent = PendingIntent.getService(this, 0,
// previousIntent, 0);
Intent playIntent = new Intent(this, PlayerService.class);
playIntent.setAction(Constants.ACTION.PLAY_ACTION);
PendingIntent pplayIntent = PendingIntent.getService(this, 0,
playIntent, 0);
Intent nextIntent = new Intent(this, PlayerService.class);
nextIntent.setAction(Constants.ACTION.NEXT_ACTION);
PendingIntent pnextIntent = PendingIntent.getService(this, 0,
nextIntent, 0);
Intent closeIntent = new Intent(this, PlayerService.class);
closeIntent.setAction(Constants.ACTION.STOPFOREGROUND_ACTION);
PendingIntent pcloseIntent = PendingIntent.getService(this, 0,
closeIntent, 0);
views.setOnClickPendingIntent(R.id.status_bar_play, pplayIntent);
bigViews.setOnClickPendingIntent(R.id.status_bar_play, pplayIntent);
views.setOnClickPendingIntent(R.id.status_bar_next, pnextIntent);
bigViews.setOnClickPendingIntent(R.id.status_bar_next, pnextIntent);
// views.setOnClickPendingIntent(R.id.status_bar_prev, ppreviousIntent);
// bigViews.setOnClickPendingIntent(R.id.status_bar_prev, ppreviousIntent);
views.setOnClickPendingIntent(R.id.status_bar_collapse, pcloseIntent);
bigViews.setOnClickPendingIntent(R.id.status_bar_collapse, pcloseIntent);
views.setImageViewResource(R.id.status_bar_play,
R.drawable.apollo_holo_dark_pause);
bigViews.setImageViewResource(R.id.status_bar_play,
R.drawable.apollo_holo_dark_pause);
// views.setTextViewText(R.id.status_bar_artist_name, "Artist Name");
// bigViews.setTextViewText(R.id.status_bar_artist_name, "Artist Name");
//
// bigViews.setTextViewText(R.id.status_bar_album_name, "Album Name");
status = new Notification.Builder(this).build();
status.contentView = views;
status.bigContentView = bigViews;
status.flags = Notification.FLAG_ONGOING_EVENT;
status.icon = R.drawable.ic_launcher;
status.contentIntent = pendingIntent;
startForeground(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE, status);
}
}

Android - SeekBar and MediaPlayer

I needed to connect my SeekBar with my MediaPlayer in my App.
I set up the SeekBar via xml like this:
<SeekBar
android:id="#+id/song_seekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"/>
and followed this SO answer to implement it.
This is my code:
public class Song_main extends AppCompatActivity {
private final int SONG_REQUEST_CODE = 1;
private Uri song;
private TextView selectSong;
private SeekBar seekBar;
private Handler handler;
private MediaPlayer mediaPlayer;
private boolean repeatPressedTwice = false;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.app_bar_song_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.song_main_toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
seekBar = (SeekBar) findViewById(R.id.song_seekbar);
handler = new Handler();
notSelected();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.song, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.song_plus) {
Intent selectIntent = new Intent(Intent.ACTION_GET_CONTENT);
selectIntent.setType("audio/*");
startActivityForResult(selectIntent, SONG_REQUEST_CODE);
}
return true;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == SONG_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
if ((data != null) && (data.getData()!=null)) {
song = data.getData();
setup();
}
}
}
private void notSelected() {
selectSong = (TextView) findViewById(R.id.select_song_textview);
selectSong.setText(getResources().getString(R.string.song_not_selected));
}
public void onPlayButtonClicked(View v) {
ImageButton pb = (ImageButton) findViewById(R.id.song_play_button);
if (!mediaPlayer.isPlaying()) {
mediaPlayer.start();
pb.setImageResource(R.drawable.pause);
updateSeekBar();
} else {
mediaPlayer.pause();
pb.setImageResource(R.drawable.ic_play_arrow_white_24dp);
}
}
public void onControlsClicked(View v) {
if (v.getId() == R.id.fast_forward) {
int pos = mediaPlayer.getCurrentPosition();
pos += 1500;
mediaPlayer.seekTo(pos);
}
else if (v.getId() == R.id.fast_backward) {
int pos = mediaPlayer.getCurrentPosition();
pos -= 1500;
mediaPlayer.seekTo(pos);
}
else if (v.getId() == R.id.skip_backward) {
mediaPlayer.seekTo(0);
}
}
public void onRepeatClicked(View v) {
if (!repeatPressedTwice) {
// TODO: change visual color of repeat button
mediaPlayer.setLooping(true);
Toast.makeText(this, "repeat enabled", Toast.LENGTH_SHORT).show();
repeatPressedTwice = true;
} else {
mediaPlayer.setLooping(false);
}
}
private void setup() {
/* the song has been select setup the interface */
/* displays song name in title */
TextView titleView = (TextView) findViewById(R.id.song_appbar_title);
String songName;
ContentResolver contentResolver = this.getContentResolver();
Cursor cursor = contentResolver.query(song, null, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
songName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
titleView.setText(songName);
}
/* removes the notSelected String */
selectSong.setVisibility(View.GONE);
/* setup media player */
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mediaPlayer.setDataSource(getApplicationContext(), song);
mediaPlayer.prepareAsync();
} catch (IOException e) {
Toast.makeText(this, "file not found", Toast.LENGTH_SHORT).show();
}
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
/* show media player layout */
RelativeLayout mpl = (RelativeLayout) findViewById(R.id.media_player_layout);
mpl.setVisibility(View.VISIBLE);
mediaPlayer.start();
ImageButton pb = (ImageButton) findViewById(R.id.song_play_button);
pb.setImageResource(R.drawable.pause);
}
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
ImageButton pb = (ImageButton) findViewById(R.id.song_play_button);
pb.setImageResource(R.drawable.ic_play_arrow_white_24dp);
}
});
seekBar = (SeekBar) findViewById(R.id.song_seekbar);
seekBar.setMax(mediaPlayer.getDuration());
updateSeekBar();
}
private void updateSeekBar() {
seekBar.setProgress(mediaPlayer.getCurrentPosition()/1000);
handler.postDelayed(runnable, 1000);
}
Runnable runnable = new Runnable() {
#Override
public void run() {
updateSeekBar();
}
};
#Override
public void onStop() {
super.onStop();
if (mediaPlayer!=null)
mediaPlayer.stop();
}
}
The process starts from the onOptionsItemSelected method.
The seekBar behaves correctly, it increments every second. The problem now is that it finishes way before the song finishes.
I tried adding
seekBar.setMax(mediaPlayer.getDuration());
in the setup method, but that causes the bar not to move at all.
You need to define separate Runnable and trigger it every x miliseconds (depends on you) once MediaPlayer starts.
Define a function updateSeekbar like,
private void updateSeekBar() {
audioSeek.setProgress(player.getCurrentPosition());
txtCurrentTime.setText(milliSecondsToTimer(player.getCurrentPosition()));
seekHandler.postDelayed(runnable, 50);
}
And Runnable
Runnable runnable = new Runnable() {
#Override
public void run() {
updateSeekBar();
}
};
Now you just have to call updateSeekbar once when playing starts. In your case:
public void onPlayButtonClicked(View v) {
ImageButton pb = (ImageButton) findViewById(R.id.song_play_button);
if (!mediaPlayer.isPlaying()) {
mediaPlayer.start();
pb.setImageResource(R.drawable.pause);
updateSeekBar();
} else {
mediaPlayer.pause();
pb.setImageResource(R.drawable.ic_play_arrow_white_24dp);
}
}
FYI
Function milliSecondsToTimer works as follows
private 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;
}
UPDATE
You have called setMax at the wrong place. Update setup() function as follows
private void setup() {
/* the song has been select setup the interface */
/* displays song name in title */
TextView titleView = (TextView) findViewById(R.id.song_appbar_title);
String songName;
ContentResolver contentResolver = this.getContentResolver();
Cursor cursor = contentResolver.query(song, null, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
songName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
titleView.setText(songName);
}
/* removes the notSelected String */
selectSong.setVisibility(View.GONE);
/* setup media player */
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mediaPlayer.setDataSource(getApplicationContext(), song);
mediaPlayer.prepareAsync();
} catch (IOException e) {
Toast.makeText(this, "file not found", Toast.LENGTH_SHORT).show();
}
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
/* show media player layout */
seekBar.setMax(mediaPlayer.getDuration());
RelativeLayout mpl = (RelativeLayout) findViewById(R.id.media_player_layout);
mpl.setVisibility(View.VISIBLE);
mediaPlayer.start();
updateSeekBar();
ImageButton pb = (ImageButton) findViewById(R.id.song_play_button);
pb.setImageResource(R.drawable.pause);
}
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
ImageButton pb = (ImageButton) findViewById(R.id.song_play_button);
pb.setImageResource(R.drawable.ic_play_arrow_white_24dp);
}
});
}
You have implement OnSeekBarChangeListener and in onCreate() add the below line:-
seekBar = (SeekBar) findViewById(R.id.seekBar);
And override the onProgressChanged() method , in this method you can set the progress in the seekbar using the below line:
mPlayer.seekTo(progress);
seekBar.setProgress(progress);
or
After you initialise your MediaPlayer and for example press the play button, you should create an handler and post runnable so you can update your SeekBar (in the UI thread itself) with the current position of your MediaPlayer like this :
private Handler mHandler = new Handler();
//Make sure you update Seekbar on UI thread
MainActivity.this.runOnUiThread(new Runnable(){
#Override
public void run() {
if(mMediaPlayer != null){
int mCurrentPosition = mMediaPlayer.getCurrentPosition() / 1000;
mSeekBar.setProgress(mCurrentPosition);
}
mHandler.postDelayed(this, 1000);
}
});
and update that value every second.
If you need to update the MediaPlayer's position while user drag your SeekBar you should add OnSeekBarChangeListener to your SeekBar and do it there :
mSeekBar.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(mMediaPlayer != null && fromUser){
mMediaPlayer.seekTo(progress * 1000);
}
}
});
you need to update your Seek bar when you play a song
public void updateProgressBar() {
runOnUiThread(new Runnable() {
#Override
public void run() {
mHandler.postDelayed(mUpdateTimeTask, 100);
}
});
}
Below Runnable method to update seekbar
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
if (MusicService.isRunning()) {
duration = MusicService.getDur();
long currSongPosition = MusicService.getPosn();
totTime.setText(Utility.milliSecondsToTimer(duration));
fromTime.setText(Utility.milliSecondsToTimer(currSongPosition));
int progress = Utility.getProgressPercentage(currSongPosition, duration);
songProgressBar.setProgress(progress);
updateProgressBar();
}
}
};
Using this below function you can get progress percentage from song current position and song duration
public static int getProgressPercentage(long currentDuration, long totalDuration) {
Double percentage;
long currentSeconds = (int) (currentDuration / 1000);
long totalSeconds = (int) (totalDuration / 1000);
percentage = (((double) currentSeconds) / totalSeconds) * 100;
return percentage.intValue();
}

Sending videolink from listview to videoview in same activity

I have a videoview and listview/gridview in my playvideo activity.
One video is already playing in the videoview. But now i want to play the other video which are showing in the listview/gridview how can i do that?
Playvideo Activity
public class playvideoactivity extends Activity {
GridViewWithHeaderAndFooter grid;
String videourl="http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4";
private static final String url = "http://dakwf.org/api/bd_english.json";
private List<ChannelItem> chanellist = new ArrayList<ChannelItem>();
private static final String TAG = MainActivity.class.getSimpleName();
public static VideoView player;
public static ImageButton btnPlayPause;
private ImageView btnFullscreen;
private ProgressBar spinner;
private RelativeLayout mediaController;
private Handler btnHandler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
spinner = (ProgressBar) findViewById(R.id.progressBar);
player=(VideoView) findViewById(R.id.player);
mediaController=(RelativeLayout) findViewById(R.id.media_controller);
spinner.setVisibility(View.VISIBLE);
mediaController.setVisibility(View.INVISIBLE);
btnPlayPause=(ImageButton) findViewById(R.id.btn_playpause);
btnFullscreen=(ImageView) findViewById(R.id.btn_fullscreen);
final CustomGridviewadapter customGridview= new CustomGridviewadapter(this,chanellist);
grid = (GridViewWithHeaderAndFooter) findViewById(R.id.grid_view);
setGridViewHeaderAndFooter();
grid.setAdapter(customGridview);
//----------- Creating volley request obj--------------------
JsonArrayRequest movieReq = new JsonArrayRequest(url,new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
// Parsing json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
ChannelItem item = new ChannelItem();
item.setTitle(obj.getString("title"));
item.setThumbnailUrl(obj.getString("image"));
// adding movie to movies array
chanellist.add(item);
} catch (JSONException e) {
e.printStackTrace();
}
}
// notifying list adapter about data changes
// so that it renders the list view with updated data
customGridview.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(movieReq);
//------------------- Mediacontroller Visiblity-------------------------------------
player.setOnTouchListener(new View.OnTouchListener()
{
public boolean onTouch(final View paramAnonymousView, MotionEvent paramAnonymousMotionEvent)
{
if (paramAnonymousMotionEvent.getAction() == 0){
if (MainActivity.this.mediaController.getVisibility() != View.INVISIBLE) {
}
MainActivity.this.mediaController.setVisibility(View.VISIBLE);
MainActivity.this.btnHandler.postDelayed(new Runnable(){
public void run(){
MainActivity.this.mediaController.setVisibility(View.INVISIBLE);
}
}, 2000L);
}
for (;;){
return true;
}
}
});
//------FullScreen Button -----
btnFullscreen.setOnClickListener(new View.OnClickListener(){
public void onClick(View paramAnonymousView) {
Intent i = new Intent(MainActivity.this, FullScreenView.class);
startActivity(i);
}
});
//------Play Pause Button ----------
btnPlayPause.setOnClickListener(new View.OnClickListener() {
public void onClick(View paramAnonymousView){
if ( (player != null) && (MainActivity.this.player.isPlaying()) ){
MainActivity.this.player.pause();
MainActivity.this.btnPlayPause.setBackgroundResource(R.drawable.btn_play);
return;
}
MainActivity.this.player.start();
MainActivity.this.btnPlayPause.setBackgroundResource(R.drawable.btn_pause);
return;
}
});
//----------------------------------------
try {
MediaController mController = new MediaController(MainActivity.this);
mController.setAnchorView(player);
Uri video = Uri.parse(videourl);
player.setMediaController(mController);
player.setVideoURI(video);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
player.setMediaController(null);
player.requestFocus();
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer arg0) {
player.start();
hidespinner();
}
});
}
// ------------ Header Gridview ----------------
#SuppressLint({"InflateParams", "SetTextI18n"})
private void setGridViewHeaderAndFooter() {
LayoutInflater layoutInflater = LayoutInflater.from(this);
View headerView = layoutInflater.inflate(R.layout.grid_header, null, false);
//locate views
TextView headerText = (TextView)headerView.findViewById(R.id.textViewheader);
headerText.setText("Suggestion");
headerView.setOnClickListener(onClickListener(0));
grid.addHeaderView(headerView);
}
private View.OnClickListener onClickListener(final int i) {
return new View.OnClickListener() {
#Override
public void onClick(View v) {
if (i == 0) {
// Toast.makeText(MainActivity.this, "Header Clicked!", Toast.LENGTH_SHORT).show();
} else {
// Toast.makeText(MainActivity.this, "Footer Clicked!", Toast.LENGTH_SHORT).show();
}
}
};
}
#Override
public void onDestroy() {
super.onDestroy();
hidespinner();
}
private void hidespinner() {
if (spinner != null) {
spinner.setVisibility(View.INVISIBLE);
spinner = null;
}
}
}
When opening starting the app you need to get the data and store on a variable or into database.
Create a ChannelList type List (List<ChannelList>) and store ChannelList data into it.
List<ChannelList> list = new ArrayList<>(); // containing all data
You can store Title, VideoUrl, iconUrl and add it to the list.
When clicking on a List Item you will get the position by using setOnItemClickListener.
And then use the position to get the clicked ChannelList position.
Suppose your list type variable is channelList.
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
ChannelList channelList= list.get(position);
// now you have all data of clicked ChannelList
// do whatever you like
//channelList.getVideoUrl(); etc as your getter method
}
}
});
For more about List, you can check it Here

Categories