2

I have several activities and fragments that displays songs from SD card and when I click on any of them, it plays. The problem is I have to create a new instance of media player in each of these activities and fragments. So, if I play a song in one activity and play another in another activity, both the songs are played simultaneously. I read about singleton class and making media player static but I need more information. Below is my code.

public class ArtistSongAlbumSong extends AppCompatActivity {

ArrayList<SongInfoModel> ArtistSongAlbumSongList = new ArrayList<>();

RecyclerView recyclerView_artistalbumsongs;

ArtistSongAlbumSongAdapter artistSongAlbumSongAdapter;

private static MediaPlayer player = new  MediaPlayer();

Context isContext;

private int currentIndex;


@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_artistsongallsong);

    recyclerView_artistalbumsongs = findViewById(R.id.recyclerView_artistSongAllSong);

    isContext = ArtistSongAlbumSong.this;

    Long albumid = getIntent().getExtras().getLong("album_id");

    LinearLayoutManager aslinearLayoutManager = new LinearLayoutManager(getApplicationContext());
    recyclerView_artistalbumsongs.setLayoutManager(aslinearLayoutManager);


    Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;

    String selection = MediaStore.Audio.Media.IS_MUSIC + "!=0";
    Cursor cursor = getApplicationContext().getContentResolver().query(uri, null, selection, null, null);
    if (cursor != null) {
        if (cursor.moveToFirst()) {
            do {
                String name = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE));
                String nameArtist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));
                String data = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));
                Long duration = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION));
                Long newAlbumId = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
                Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart");
                Uri albumArtUri = ContentUris.withAppendedId(sArtworkUri, albumid);

                if (newAlbumId.equals(albumid)) {

                    SongInfoModel s6 = new SongInfoModel(name, nameArtist, duration, data, albumArtUri);
                    ArtistSongAlbumSongList.add(s6);
                }

            } while (cursor.moveToNext());
        }


        cursor.close();

        Collections.sort(ArtistSongAlbumSongList, new Comparator<SongInfoModel>() {
            @Override
            public int compare(SongInfoModel lhs, SongInfoModel rhs) {
                return lhs.getSongName().compareTo(rhs.getSongName());
            }
        });


    }





    artistSongAlbumSongAdapter = new ArtistSongAlbumSongAdapter(getApplicationContext(), ArtistSongAlbumSongList);

    artistSongAlbumSongAdapter.onItemClickListener(new ArtistSongAlbumSongAdapter.ArtistSongAlbumSongListener() {
        @Override
        public void onClickListener(SongInfoModel songInfoModel, int position, RelativeLayout relativeLayout, View view) {
            MainActivity.setsongText(songInfoModel);
            MainActivity.ButtonPlay();
            MainActivity.PauseImage();

            changeSelectedSong(position);
            prepareSong(songInfoModel);

        }

        @Override
        public void onLongClickListener(SongInfoModel songInfoModel, int position, RelativeLayout relativeLayout, View view) {

        }
    });

    recyclerView_artistalbumsongs.setAdapter(artistSongAlbumSongAdapter);


    player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(MediaPlayer mediaPlayer) {

            togglePlay(mediaPlayer);

        }
    });

    player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mediaPlayer) {
            onSongCompletion1(mediaPlayer);
        }
    });




}



public void prepareSong(SongInfoModel song) {

    player.reset();


    try {
        player.setDataSource(song.getData());
        player.prepareAsync();
    } catch (IOException e) {
        e.printStackTrace();
    }

}


private void togglePlay(MediaPlayer mp) {

    if (mp.isPlaying()) {
        mp.stop();
        mp.reset();

    } else {

        mp.start();


        MainActivity.Handler(mp);


    }


}

private void changeSelectedSong(int index){
  //  artistSongAlbumSongAdapter.notifyItemChanged(artistSongAlbumSongAdapter.getSelectedPosition());
    currentIndex = index;
    artistSongAlbumSongAdapter.setSelectedPosition(currentIndex);
  //  artistSongAlbumSongAdapter.notifyItemChanged(currentIndex);

}




private void onSongCompletion1(MediaPlayer mediaPlayer) {


    if(currentIndex + 1 < ArtistSongAlbumSongList.size()){
        SongInfoModel next  = ArtistSongAlbumSongList.get(currentIndex +1);
        changeSelectedSong(currentIndex + 1);
        prepareSong(next);
        MainActivity.setsongText(next);
    }else{

        SongInfoModel next1  = ArtistSongAlbumSongList.get(0);
        changeSelectedSong(0);
        prepareSong(ArtistSongAlbumSongList.get(0));
        MainActivity.setsongText(next1);
    }

}

Singleton class:

public class MyMediaPlayer extends MediaPlayer  {

private static MyMediaPlayer mpclass ;




private MyMediaPlayer() {

}

public static MyMediaPlayer getInstance() {
    if (mpclass == null) {
        synchronized (MyMediaPlayer.class) {
            if (mpclass == null) {
                mpclass = new MyMediaPlayer();
            }
        }
    }

    return mpclass;
}
Community
  • 1
  • 1
Rektirino
  • 582
  • 5
  • 24

1 Answers1

0

you need to follow below steps

1) Create a service to play audio and create Media Player instance here 2) Bind that in activity (It can be your base activity) 3) Use service reeference in activity to get media player instance and done. Use this instance from the activity across all the fragment

Abdul Waheed
  • 4,540
  • 6
  • 35
  • 58
  • I'm not planning on using a service tbh. Is that bad? And can you tell me the another solution , simpler than service? – Rektirino Oct 29 '17 at 12:29
  • Yes, it can be done without service as well. Create instance if media player in your base activity. you will be able to access that instance across all activities in fragment as well – Abdul Waheed Oct 29 '17 at 12:30
  • I created a singleton class for media player. Code posted above. But the problem is I have implemented setOnCompletionListeners() in all the activiites and fragments but only the latest implemented setOnCompletionListener() works. I don't know why – Rektirino Oct 29 '17 at 12:33
  • Do the samething in base class and provide call backs to (using overriding methods) child classes. Then you will be able to get what you wnt :) – Abdul Waheed Oct 29 '17 at 12:35
  • But if I implement the setOnCompletionListeners() in base class how will I pass the arrayList, object and all other stuffs to it? – Rektirino Oct 29 '17 at 12:39
  • By overriding base class methods :) – Abdul Waheed Oct 29 '17 at 12:39
  • User power of inheritance – Abdul Waheed Oct 29 '17 at 12:40
  • Can you help me with my singleton class? Everything is working fine except the setOnCompletionListener() – Rektirino Oct 29 '17 at 12:45
  • [here](https://stackoverflow.com/a/30743865/7948109) is the answer which also explains the same using service with code – Rahul Gaur May 19 '21 at 04:48