This is my music adapter file and this is logcat error
at com.example.apna_music.MusicListAdapter$1.onClick(MusicListAdapter.java:57)
at android.view.View.performClick(View.java:7570)
at android.view.View.performClickInternal(View.java:7525)
at android.view.View.access$3900(View.java:836)
at android.view.View$PerformClick.run(View.java:28680)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:254)
at android.app.ActivityThread.main(ActivityThread.java:8243)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:612)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1006)
MUSIC ADAPTER
package com.example.apna_music;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
public class MusicListAdapter extends RecyclerView.Adapter<MusicListAdapter.ViewHolder>{
ArrayList<Audio_Model> songsList;
Context context;
private ViewHolder holder;
public MusicListAdapter(ArrayList<Audio_Model> songsList, Context context) {
this.songsList = songsList;
this.context = context;
}
@Override
public ViewHolder onCreateViewHolder( ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.recycler_item,parent,false);
return new MusicListAdapter.ViewHolder(view);
}
@Override
public void onBindViewHolder(MusicListAdapter.ViewHolder holder, @SuppressLint("RecyclerView") int position) {
this.holder = holder;
Audio_Model songData = songsList.get(position);
holder.titleTextView.setText(songData.getTitle());
if(MyMediaPlayer.currentIndex==position){
holder.titleTextView.setTextColor(Color.parseColor("#FF0000"));
}else{
holder.titleTextView.setTextColor(Color.parseColor("#000000"));
}
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//navigate to another acitivty
MyMediaPlayer.getInstance().reset();
MyMediaPlayer.currentIndex = position;
Intent intent = new Intent(context,MusicPlayerActivity.class);
intent.putExtra("LIST",songsList);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
});
}
@Override
public int getItemCount() {
return songsList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
TextView titleTextView;
ImageView iconImageView;
public ViewHolder(View itemView) {
super(itemView);
titleTextView = itemView.findViewById(R.id.music_title_text);
iconImageView = itemView.findViewById(R.id.icon_view);
}
}
}
Main activity java file
package com.example.apna_music;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.Manifest;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
TextView noMusicTextView;
ArrayList<Audio_Model> songsList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recycler_view);
noMusicTextView = findViewById(R.id.nosongtext);
if(checkPermission() == false){
requestPermission();
return;
}
String[] projection = {
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.DATA,
MediaStore.Audio.Media.DURATION
};
String selection = MediaStore.Audio.Media.IS_MUSIC +" != 0";
Cursor cursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,projection,selection,null,null);
while(cursor.moveToNext()){
Audio_Model songData = new Audio_Model(cursor.getString(1),cursor.getString(0),cursor.getString(2));
if(new File(songData.getPath()).exists())
songsList.add(songData);
}
if(songsList.size()==0){
noMusicTextView.setVisibility(View.VISIBLE);
}else{
//recyclerview
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(new MusicListAdapter(songsList,getApplicationContext()));
}
}
boolean checkPermission(){
int result = ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE);
if(result == PackageManager.PERMISSION_GRANTED){
return true;
}else{
return false;
}
}
void requestPermission(){
if(ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,Manifest.permission.READ_EXTERNAL_STORAGE)){
Toast.makeText(MainActivity.this,"READ PERMISSION IS REQUIRED,PLEASE ALLOW FROM SETTTINGS",Toast.LENGTH_SHORT).show();
}else
ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},123);
}
@Override
protected void onResume() {
super.onResume();
if(recyclerView!=null){
recyclerView.setAdapter(new MusicListAdapter(songsList,getApplicationContext()));
}
}
}
Main activity xml file
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/holo_blue_bright"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/songtitle"
android:text=" MY SONGS "
android:textStyle="bold"
android:padding="10dp"
android:textSize="23dp"
android:layout_centerHorizontal="true"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/nosongtext"
android:text=" MY SONGS "
android:textStyle="bold"
android:padding="10dp"
android:textSize="23dp"
android:layout_centerHorizontal="true"
/>
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/songtitle"
android:id="@+id/recycler_view"
>
</androidx.recyclerview.widget.RecyclerView>
</RelativeLayout>
Music Player Activity Java
package com.example.apna_music;
import androidx.appcompat.app.AppCompatActivity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;
import java.io.IOException;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
public class MusicPlayerActivity extends AppCompatActivity {
TextView titleTv,currentTimeTv,totalTimeTv;
SeekBar seekBar;
ImageView pausePlay,nextBtn,previousBtn,musicIcon;
ArrayList<Audio_Model> songsList;
Audio_Model currentSong;
MediaPlayer mediaPlayer = MyMediaPlayer.getInstance();
int x=0;
ArrayList<Audio_Model> songslist;
Audio_Model currentsong;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_music_player);
titleTv = findViewById(R.id.song_title);
currentTimeTv = findViewById(R.id.current_time);
totalTimeTv = findViewById(R.id.total_time);
seekBar = findViewById(R.id.seek_bar);
pausePlay = findViewById(R.id.pause_play);
nextBtn = findViewById(R.id.next);
previousBtn = findViewById(R.id.previous);
musicIcon = findViewById(R.id.music_icon_big);
titleTv.setSelected(true);
songsList = (ArrayList<Audio_Model>) getIntent().getSerializableExtra("LIST");
setResourcesWithMusic();
MusicPlayerActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
if(mediaPlayer!=null){
seekBar.setProgress(mediaPlayer.getCurrentPosition());
currentTimeTv.setText(convertToMMSS(mediaPlayer.getCurrentPosition()+""));
if(mediaPlayer.isPlaying()){
pausePlay.setImageResource(R.drawable.pause);
musicIcon.setRotation(x++);
}else{
pausePlay.setImageResource(R.drawable.play);
musicIcon.setRotation(0);
}
}
new Handler().postDelayed(this,100);
}
});
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if(mediaPlayer!=null && fromUser){
mediaPlayer.seekTo(progress);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
void setResourcesWithMusic(){
currentSong = songsList.get(MyMediaPlayer.currentIndex);
titleTv.setText(currentSong.getTitle());
totalTimeTv.setText(convertToMMSS(currentSong.getDuration()));
pausePlay.setOnClickListener(v-> pausePlay());
nextBtn.setOnClickListener(v-> playNextSong());
previousBtn.setOnClickListener(v-> playPreviousSong());
playMusic();
}
private void playMusic(){
mediaPlayer.reset();
try {
mediaPlayer.setDataSource(currentsong.getPath());
mediaPlayer.prepare();
mediaPlayer.start();
seekBar.setProgress(0);
seekBar.setMax(mediaPlayer.getDuration());
} catch (IOException e) {
e.printStackTrace();
}
}
private void playNextSong(){
if(MyMediaPlayer.currentIndex== songslist.size()-1)
return;
MyMediaPlayer.currentIndex +=1;
mediaPlayer.reset();
setResourcesWithMusic();
}
private void playPreviousSong(){
if(MyMediaPlayer.currentIndex== 0)
return;
MyMediaPlayer.currentIndex -=1;
mediaPlayer.reset();
setResourcesWithMusic();
}
private void pausePlay(){
if(mediaPlayer.isPlaying())
mediaPlayer.pause();
else
mediaPlayer.start();
}
public static String convertToMMSS(String duration){
Long millis = Long.parseLong(duration);
return String.format("%02d:%02d",
TimeUnit.MILLISECONDS.toMinutes(millis) % TimeUnit.HOURS.toMinutes(1),
TimeUnit.MILLISECONDS.toSeconds(millis) % TimeUnit.MINUTES.toSeconds(1));
}
}
Music Player Activity 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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:background="@android:color/holo_blue_light"
android:layout_height="match_parent"
tools:context=".MusicPlayerActivity">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Title of the Song"
android:id="@+id/song_title"
android:singleLine="true"
android:ellipsize="marquee"
android:textSize="20dp"
android:textColor="@color/white"
android:layout_margin="20dp"
android:padding="20dp"/>
<ImageView
android:layout_width="240dp"
android:layout_height="240dp"
android:id="@+id/music_icon_big"
android:layout_centerHorizontal="true"
android:padding="20dp"
android:layout_above="@id/controls"
android:src="@drawable/music"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:id="@+id/controls"
android:padding="48dp">
<SeekBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/seek_bar"
android:layout_margin="10dp"
android:backgroundTint="@color/white"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/current_time"
android:text="0.00"
android:layout_below="@id/seek_bar"
android:layout_alignParentStart="true"
android:textColor="@color/white"
android:layout_margin="20dp"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/total_time"
android:text="0.00"
android:layout_below="@id/seek_bar"
android:layout_alignParentEnd="true"
android:textColor="@color/white"
android:layout_margin="20dp"
/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/total_time"
android:padding="20dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_baseline_skip_previous_24"
android:layout_centerVertical="true"
android:layout_alignParentStart="true"
android:id="@+id/previous"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/skip_next"
android:layout_centerVertical="true"
android:layout_alignParentEnd="true"
android:id="@+id/next"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/pause"
android:layout_centerVertical="true"
android:layout_centerInParent="true"
android:id="@+id/pause_play"/>
</RelativeLayout>
</RelativeLayout>
</RelativeLayout>
MY MEDIA PLAYER
package com.example.apna_music;
import android.media.MediaPlayer;
public class MyMediaPlayer {
static MediaPlayer instance;
public static MediaPlayer getInstance(){
if(instance==null){
instance=new MediaPlayer();
}
return instance;
}
public static int currentIndex=-1;
}
AUDIO MODEL
package com.example.apna_music;
public class Audio_Model {
String path;
String title;
String duration;
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDuration() {
return duration;
}
public void setDuration(String duration) {
this.duration = duration;
}
public Audio_Model(String path, String title, String duration) {
this.path = path;
this.title = title;
this.duration = duration;
}
}
Your Audio_Model class has not implemented Serializable interface. Make sure to implement it with Serializable Interface.
class Audio_Model implements Serializable {
String path;
String title;
String duration;
public Audio_Model(String path, String title, String duration) {
this.path = path;
this.title = title;
this.duration = duration;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDuration() {
return duration;
}
public void setDuration(String duration) {
this.duration = duration;
}
}