Presently I am trying to build a full fledged android music player. I am loading all songs, artists, playlists etc from mediastore whenever the app is loaded and previously not present in ram. This approach though reflects mediastore changes between app loads greatly increases loading time. How should I proceed to get agreeable loading times and also reflect any data changes? Thanks in advance.
How do native android media players make data persistent as well as reflect changes
93 views Asked by Sayan Sarkar At
2
There are 2 answers
2
On
I use a viewpager approach in my app New Playlist Manager, one for all tracks, albums and artists. For each of these I have a Fragment each of which has a custom cursorAdapter. I give you the example of all tracks: set up my columns:
dataColumns= new String[]{
MediaStore.Audio.Media.TRACK,
MediaStore.Audio.Media._ID,
MediaStore.Audio.Media.DATA,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.YEAR,
MediaStore.Audio.Media.DURATION,
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.ALBUM_ID
};
sort_order = MediaStore.Audio.Media.TITLE +" ASC";
To populate my listView I use a LoaderManager in OnViewCreated
getLoaderManager().initLoader(GALLERY_LOADER, null, this);
and
@Override
public Loader<Cursor> onCreateLoader(int loaderID, Bundle bundle) {
switch (loaderID) {
case GALLERY_LOADER:
return new CursorLoader(getActivity(),
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
dataColumns,
null, null,
sort_order);
default:
return null;
}
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
mAdapter.swapCursor(data);
mAdapter.notifyDataSetChanged();
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
mAdapter.swapCursor(null);
}
So when the view has been created, the LoaderManager fetches the necessary cursor which is then fed to the Adapter. So for each of the Fragments, you only fetch the data you need. For Albums my Cursor Loader looks like:
public class showallAlbumsFragment extends Fragment implements
OnItemClickListener, LoaderManager.LoaderCallbacks<Cursor>
dataColumns= new String[]{
BaseColumns._ID,
AlbumColumns.ALBUM,
AlbumColumns.NUMBER_OF_SONGS,
AlbumColumns.FIRST_YEAR,
AlbumColumns.ARTIST };
sort_order = AlbumColumns.ALBUM +" ASC";
@Override
public Loader<Cursor> onCreateLoader(int loaderID, Bundle bundle) {
switch (loaderID) {
case GALLERY_LOADER:
return new CursorLoader(getActivity(),
MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
dataColumns,
null, null,
sort_order);
default:
return null;
}
}
I hope this gets you going
To pass a cursor to recyclerview adapter in, the Fragment implement LoaderManager
In addition, in your adapter, adjust the signature
and add a few methods because you need them from within the Fragment
and in Fragment