Issue
I have a ListView activity showing a list of songs from my raw file, when I click on one of the ListView it will play the song accordingly but if I click for the second time it would just replay the same song again. How do I pause and resume again on the same track? Below are the codes I have done so far.
MainActivity.java
package com.example.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
public class MainActivity extends AppCompatActivity {
private ListView musicListView;
private Trackmodel[] tracklist;
private TrackAdapter adapter;
private MediaPlayer mediaPlayer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
musicListView = findViewById(R.id.musicListView);
loadTracks();
musicListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
loadTracks();
Trackmodel track = tracklist[i];
if (mediaPlayer != null) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
mediaPlayer.reset();
track.setPlaying(false);
}
}
try {
mediaPlayer = MediaPlayer.create(MainActivity.this, track.getId());
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
mediaPlayer.reset();
track.setPlaying(false);
} else {
mediaPlayer.start();
track.setPlaying(true);
}
} catch (Exception e) {
Log.e("Exception", e.getMessage());
}
}
});
}
public void loadTracks() {
tracklist = new Trackmodel[]{
new Trackmodel(R.raw.decode, "Paramore - Decode", false),
new Trackmodel(R.raw.thats_what_you_get, "Paramore - That's What You Get", false),
new Trackmodel(R.raw.starstrukk, "30H!3 - Starstrukk", false),
new Trackmodel(R.raw.we_are_young, "30H!3 - We Are Young", false)
};
adapter = new TrackAdapter(MainActivity.this, tracklist);
musicListView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mediaPlayer != null) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
mediaPlayer.reset();
}
}
}}
TrackModel.java
package com.example.myapplication;
public class Trackmodel {
private int id;
private String name;
private boolean isPlaying;
public Trackmodel(int id, String name, boolean isPlaying) {
this.id = id;
this.name = name;
this.isPlaying = isPlaying;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isPlaying() {
return isPlaying;
}
public void setPlaying(boolean playing) { isPlaying = playing; }
}
TrackAdapter.java
package com.example.myapplication;
import android.content.Context;
import android.view.ContentInfo;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class TrackAdapter extends BaseAdapter {
private Context context;
private Trackmodel[] tracks;
TrackAdapter(Context context, Trackmodel[] tracks) {
this.context = context;
this.tracks = tracks;
}
@Override
public int getCount() {
return tracks.length;
}
@Override
public Object getItem(int i) {
return tracks[i];
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
Trackmodel track = (Trackmodel) getItem(i);
ViewHolder holder;
if (view == null) {
view = LayoutInflater.from(context).inflate(R.layout.track_item, viewGroup, false);
holder = new ViewHolder();
holder.trackImage = view.findViewById(R.id.track_image);
holder.titleText = view.findViewById(R.id.track_title);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
holder.titleText.setText(track.getName());
if (track.isPlaying()) {
holder.trackImage.setImageResource(R.drawable.ic_baseline_pause_circle);
} else {
holder.trackImage.setImageResource(R.drawable.ic_baseline_play_circle);
}
return view;
}
static class ViewHolder {
ImageView trackImage;
TextView titleText;
}
}
track_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/sound_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="16sp"
android:paddingTop="10dp"
android:paddingRight="16sp">
<ImageView
android:id="@+id/track_image"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerVertical="true"
android:padding="5dp"
app:tint="@android:color/black" />
<TextView
android:id="@+id/track_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="56dp"
android:textAppearance="@style/TextAppearance.AppCompat.Body2" />
</RelativeLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<ListView
android:id="@+id/musicListView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Solution
In your item click, you stop the MediaPlayer
but after that, you create a new instance every time.
You have one if check, which checks if MediaPlayer
is playing and stops it. After that, you create a new MediaPlayer
and perform the same check again. So what is happening when you click the first time? First if
check is not executing because your mediaplayer
is null, it creates a new mediaplayer
and starts to play.
After clicking the second time your first if
check is executing, because your MediaPlayer is not null and isPlaying
is true. You stop it, create a new instance of MediaPlayer
and play it again. That's why after clicking all the next times you just replay the song. Because on click you stop the song, create a new instance and play it.
So what you need here, I assume you have different tracks in your list and when you click on another track you need to stop the previous track and start that new one. But if you click on the same track you want to pause it.
In this case, you need the current track id which is playing/played. After clicking next time if the track id is the same which was playing, you just pause it. If it's another track, stop it and start that new track. Here's the below code, you can make changes accordingly and apply it to your code.
int currentTrackId = -1;
musicListView.setOnItemClickListener(
(AdapterView.OnItemClickListener) (adapterView, view, i, l) -> {
loadTracks();
Trackmodel track = tracklist[i];
if (currentTrackId != -1 && track.getId() == currentTrackId) {
// That was the same song, just pause it.
if (mediaPlayer != null) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
track.setPlaying(false);
} else {
mediaPlayer.start();
track.setPlaying(true);
}
}
} else {
// That's another song, stop the previous one and start the new one
currentTrackId = track.getId();
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.reset();
}
try {
mediaPlayer = MediaPlayer.create(MainActivity.this, track.getId());
mediaPlayer.start();
track.setPlaying(true);
} catch (Exception e) {
Log.e("Exception", e.getMessage());
}
}
});
Answered By - Hayk Mkrtchyan
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.