Cleaned up MediaStore loaders, preparing for album art loading directly from the file

This commit is contained in:
Karim Abou Zeid 2015-07-09 16:37:45 +02:00
commit da92636180
23 changed files with 271 additions and 374 deletions

View file

@ -3,6 +3,7 @@ package com.kabouzeid.gramophone;
import android.app.Application;
import com.crashlytics.android.Crashlytics;
import com.kabouzeid.gramophone.imageloader.PhonographImageDownloader;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.utils.L;
@ -24,7 +25,9 @@ public class App extends Application {
if (!BuildConfig.DEBUG) Fabric.with(this, new Crashlytics());
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this).build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this)
.imageDownloader(new PhonographImageDownloader(this))
.build();
ImageLoader.getInstance().init(config);
L.writeLogs(false); // turns off UILs annoying LogCat output
}

View file

@ -9,7 +9,6 @@ import android.view.View;
import com.afollestad.materialdialogs.MaterialDialog;
import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.loader.SongLoader;
import com.kabouzeid.gramophone.model.Song;
import com.kabouzeid.gramophone.util.MusicUtil;
@ -17,10 +16,10 @@ import com.kabouzeid.gramophone.util.MusicUtil;
* @author Karim Abou Zeid (kabouzeid)
*/
public class SongShareDialog extends DialogFragment {
public static SongShareDialog create(final int songId) {
public static SongShareDialog create(final Song song) {
final SongShareDialog dialog = new SongShareDialog();
final Bundle args = new Bundle();
args.putInt("song_id", songId);
args.putSerializable("song", song);
dialog.setArguments(args);
return dialog;
}
@ -28,8 +27,7 @@ public class SongShareDialog extends DialogFragment {
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final int songId = getArguments().getInt("song_id");
final Song song = SongLoader.getSong(getActivity(), songId);
final Song song = (Song) getArguments().getSerializable("song");
final String currentlyListening = getString(R.string.currently_listening_to_x_by_x, song.title, song.artistName);
return new MaterialDialog.Builder(getActivity())
.title(R.string.what_do_you_want_to_share)
@ -39,7 +37,7 @@ public class SongShareDialog extends DialogFragment {
public void onSelection(MaterialDialog materialDialog, View view, int i, CharSequence charSequence) {
switch (i) {
case 0:
startActivity(Intent.createChooser(MusicUtil.createShareSongFileIntent(getActivity(), songId), null));
startActivity(Intent.createChooser(MusicUtil.createShareSongFileIntent(song), null));
break;
case 1:
getActivity().startActivity(

View file

@ -14,7 +14,6 @@ import com.kabouzeid.gramophone.dialogs.RenamePlaylistDialog;
import com.kabouzeid.gramophone.dialogs.SongDetailDialog;
import com.kabouzeid.gramophone.interfaces.PaletteColorHolder;
import com.kabouzeid.gramophone.loader.PlaylistSongLoader;
import com.kabouzeid.gramophone.loader.SongFilePathLoader;
import com.kabouzeid.gramophone.model.Playlist;
import com.kabouzeid.gramophone.model.Song;
import com.kabouzeid.gramophone.model.smartplaylist.AbsSmartPlaylist;
@ -38,7 +37,7 @@ public class MenuItemClickHelper {
MusicUtil.setRingtone(activity, song.id);
return true;
case R.id.action_share:
activity.startActivity(Intent.createChooser(MusicUtil.createShareSongFileIntent(activity, song.id), null));
activity.startActivity(Intent.createChooser(MusicUtil.createShareSongFileIntent(song), null));
return true;
case R.id.action_delete_from_disk:
DeleteSongsDialog.create(song).show(activity.getSupportFragmentManager(), "DELETE_SONGS");
@ -60,8 +59,7 @@ public class MenuItemClickHelper {
activity.startActivity(tagEditorIntent);
return true;
case R.id.action_details:
String songFilePath = SongFilePathLoader.getSongFilePath(activity, song.id);
File songFile = new File(songFilePath);
File songFile = new File(song.data);
SongDetailDialog.create(songFile).show(activity.getSupportFragmentManager(), "SONG_DETAILS");
return true;
case R.id.action_go_to_album:

View file

@ -0,0 +1,35 @@
package com.kabouzeid.gramophone.imageloader;
import android.content.Context;
import com.kabouzeid.gramophone.util.MusicUtil;
import com.nostra13.universalimageloader.core.download.BaseImageDownloader;
import java.io.IOException;
import java.io.InputStream;
/**
* @author Karim Abou Zeid (kabouzeid)
*/
public class PhonographImageDownloader extends BaseImageDownloader {
public static final String SCHEME_ALBUM = "album://";
public static final String SCHEME_SONG = "song://";
public PhonographImageDownloader(Context context) {
super(context);
}
@Override
protected InputStream getStreamFromOtherSource(String imageUri, Object extra) throws IOException {
if (imageUri.startsWith(SCHEME_ALBUM)) {
try {
int id = Integer.valueOf(imageUri.substring(SCHEME_ALBUM.length()));
return getStream(MusicUtil.getAlbumArtUri(id).toString(), extra);
} catch (NumberFormatException e) {
return super.getStreamFromOtherSource(imageUri, extra);
}
} else {
return super.getStreamFromOtherSource(imageUri, extra);
}
}
}

View file

@ -2,48 +2,42 @@ package com.kabouzeid.gramophone.loader;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.BaseColumns;
import android.provider.MediaStore;
import android.provider.MediaStore.Audio.AlbumColumns;
import android.provider.MediaStore.Audio.AudioColumns;
import com.kabouzeid.gramophone.model.Album;
import com.kabouzeid.gramophone.util.PreferenceUtils;
import java.util.ArrayList;
import java.util.List;
/**
* @author Karim Abou Zeid (kabouzeid)
*/
public class AlbumLoader {
public static List<Album> getAllAlbums(Context context) {
public static ArrayList<Album> getAllAlbums(final Context context) {
Cursor cursor = makeAlbumCursor(context, null, null);
return getAlbums(cursor);
}
public static List<Album> getAlbums(Context context, String query) {
Cursor cursor = makeAlbumCursor(context, MediaStore.Audio.AlbumColumns.ALBUM + " LIKE ?", new String[]{"%" + query + "%"});
public static ArrayList<Album> getAlbums(final Context context, String query) {
Cursor cursor = makeAlbumCursor(context, AlbumColumns.ALBUM + " LIKE ?", new String[]{"%" + query + "%"});
return getAlbums(cursor);
}
public static Album getAlbum(Context context, int albumId) {
public static Album getAlbum(final Context context, int albumId) {
Cursor cursor = makeAlbumCursor(context, BaseColumns._ID + "=?", new String[]{String.valueOf(albumId)});
return getAlbum(cursor);
}
public static List<Album> getAlbums(Cursor cursor) {
List<Album> albums = new ArrayList<>();
public static ArrayList<Album> getAlbums(final Cursor cursor) {
ArrayList<Album> albums = new ArrayList<>();
if (cursor != null && cursor.moveToFirst()) {
do {
final String albumName = cursor.getString(1);
final int id = cursor.getInt(0);
final String artist = cursor.getString(2);
final int artistId = cursor.getInt(3);
final int songCount = cursor.getInt(4);
final int year = cursor.getInt(5);
final Album album = new Album(id, albumName, artist, artistId, songCount, year);
albums.add(album);
albums.add(getAlbumFromCursorImpl(cursor));
} while (cursor.moveToNext());
}
if (cursor != null) {
@ -52,17 +46,10 @@ public class AlbumLoader {
return albums;
}
public static Album getAlbum(Cursor cursor) {
public static Album getAlbum(final Cursor cursor) {
Album album = new Album();
if (cursor != null && cursor.moveToFirst()) {
final int id = cursor.getInt(0);
final String albumName = cursor.getString(1);
final String artist = cursor.getString(2);
final int artistId = cursor.getInt(3);
final int songCount = cursor.getInt(4);
final int year = cursor.getInt(5);
album = new Album(id, albumName, artist, artistId, songCount, year);
album = getAlbumFromCursorImpl(cursor);
}
if (cursor != null) {
@ -71,21 +58,40 @@ public class AlbumLoader {
return album;
}
private static Album getAlbumFromCursorImpl(final Cursor cursor) {
final int id = cursor.getInt(0);
final String albumName = cursor.getString(1);
final String artist = cursor.getString(2);
final int artistId = cursor.getInt(3);
final int songCount = cursor.getInt(4);
final int year = cursor.getInt(5);
return new Album(id, albumName, artist, artistId, songCount, year);
}
public static Cursor makeAlbumCursor(final Context context, final String selection, final String[] values) {
return context.getContentResolver().query(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
return makeAlbumCursor(context, selection, values, PreferenceUtils.getInstance(context).getAlbumSortOrder());
}
public static Cursor makeAlbumCursor(final Context context, final String selection, final String[] values, final String sortOrder) {
return makeAlbumCursor(context, MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, selection, values, sortOrder);
}
public static Cursor makeAlbumCursor(final Context context, final Uri contentUri, final String selection, final String[] values, final String sortOrder) {
return context.getContentResolver().query(contentUri,
new String[]{
/* 0 */
BaseColumns._ID,
/* 1 */
MediaStore.Audio.AlbumColumns.ALBUM,
AlbumColumns.ALBUM,
/* 2 */
MediaStore.Audio.AlbumColumns.ARTIST,
AlbumColumns.ARTIST,
/* 3 */
MediaStore.Audio.Media.ARTIST_ID,
AudioColumns.ARTIST_ID,
/* 4 */
MediaStore.Audio.AlbumColumns.NUMBER_OF_SONGS,
AlbumColumns.NUMBER_OF_SONGS,
/* 5 */
MediaStore.Audio.AlbumColumns.FIRST_YEAR,
}, selection, values, PreferenceUtils.getInstance(context).getAlbumSortOrder());
AlbumColumns.FIRST_YEAR,
}, selection, values, sortOrder);
}
}

View file

@ -2,7 +2,6 @@ package com.kabouzeid.gramophone.loader;
import android.content.Context;
import android.database.Cursor;
import android.provider.BaseColumns;
import android.provider.MediaStore;
import com.kabouzeid.gramophone.model.Song;
@ -16,47 +15,17 @@ import java.util.ArrayList;
public class AlbumSongLoader {
public static ArrayList<Song> getAlbumSongList(final Context context, final int albumId) {
Cursor cursor = makeAlbumSongCursor(context, albumId);
ArrayList<Song> songs = new ArrayList<>();
if (cursor != null && cursor.moveToFirst()) {
do {
final int id = cursor.getInt(0);
final String songName = cursor.getString(1);
final String artist = cursor.getString(2);
final String album = cursor.getString(3);
final long duration = cursor.getLong(4);
final int trackNumber = cursor.getInt(5);
final int artistId = cursor.getInt(6);
final Song song = new Song(id, albumId, artistId, songName, artist, album, duration, trackNumber);
songs.add(song);
} while (cursor.moveToNext());
}
if (cursor != null)
cursor.close();
return songs;
return SongLoader.getSongs(makeAlbumSongCursor(context, albumId));
}
public static Cursor makeAlbumSongCursor(final Context context, final int albumId) {
return context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
return SongLoader.makeSongCursor(
context,
MediaStore.Audio.AudioColumns.ALBUM_ID + "=?",
new String[]{
/* 0 */
BaseColumns._ID,
/* 1 */
MediaStore.Audio.AudioColumns.TITLE,
/* 2 */
MediaStore.Audio.AudioColumns.ARTIST,
/* 3 */
MediaStore.Audio.AudioColumns.ALBUM,
/* 4 */
MediaStore.Audio.AudioColumns.DURATION,
/* 5 */
MediaStore.Audio.AudioColumns.TRACK,
/* 6 */
MediaStore.Audio.AudioColumns.ARTIST_ID
}, (MediaStore.Audio.AudioColumns.IS_MUSIC + "=1") + " AND " +
MediaStore.Audio.AudioColumns.TITLE + " != ''" + " AND " +
MediaStore.Audio.AudioColumns.ALBUM_ID + "=" + albumId, null,
PreferenceUtils.getInstance(context).getAlbumSongSortOrder());
String.valueOf(albumId)
},
PreferenceUtils.getInstance(context).getAlbumSongSortOrder()
);
}
}

View file

@ -2,7 +2,6 @@ package com.kabouzeid.gramophone.loader;
import android.content.Context;
import android.database.Cursor;
import android.provider.BaseColumns;
import android.provider.MediaStore;
import com.kabouzeid.gramophone.model.Album;
@ -16,39 +15,15 @@ import java.util.ArrayList;
public class ArtistAlbumLoader {
public static ArrayList<Album> getArtistAlbumList(final Context context, final int artistId) {
Cursor cursor = makeArtistAlbumCursor(context, artistId);
ArrayList<Album> albums = new ArrayList<>();
if (cursor != null && cursor.moveToFirst()) {
do {
final int id = cursor.getInt(0);
final String albumName = cursor.getString(1);
final String artist = cursor.getString(2);
final int songCount = cursor.getInt(3);
final int year = cursor.getInt(4);
final Album album = new Album(id, albumName, artist, artistId, songCount, year);
albums.add(album);
} while (cursor.moveToNext());
}
if (cursor != null)
cursor.close();
return albums;
return AlbumLoader.getAlbums(makeArtistAlbumCursor(context, artistId));
}
public static Cursor makeArtistAlbumCursor(final Context context, final int artistId) {
if (artistId == -1) return null;
return context.getContentResolver().query(
MediaStore.Audio.Artists.Albums.getContentUri("external", artistId), new String[]{
/* 0 */
BaseColumns._ID,
/* 1 */
MediaStore.Audio.AlbumColumns.ALBUM,
/* 2 */
MediaStore.Audio.AlbumColumns.ARTIST,
/* 3 */
MediaStore.Audio.AlbumColumns.NUMBER_OF_SONGS,
/* 4 */
MediaStore.Audio.AlbumColumns.FIRST_YEAR,
}, null, null, PreferenceUtils.getInstance(context).getArtistAlbumSortOrder());
return AlbumLoader.makeAlbumCursor(context,
MediaStore.Audio.Artists.Albums.getContentUri("external", artistId),
null,
null,
PreferenceUtils.getInstance(context).getArtistAlbumSortOrder()
);
}
}

View file

@ -4,25 +4,25 @@ import android.content.Context;
import android.database.Cursor;
import android.provider.BaseColumns;
import android.provider.MediaStore;
import android.provider.MediaStore.Audio.ArtistColumns;
import com.kabouzeid.gramophone.model.Artist;
import com.kabouzeid.gramophone.util.PreferenceUtils;
import java.util.ArrayList;
import java.util.List;
/**
* @author Karim Abou Zeid (kabouzeid)
*/
public class ArtistLoader {
public static List<Artist> getAllArtists(Context context) {
public static ArrayList<Artist> getAllArtists(Context context) {
Cursor cursor = makeArtistCursor(context, null, null);
return getArtists(cursor);
}
public static List<Artist> getArtists(Context context, String query) {
Cursor cursor = makeArtistCursor(context, MediaStore.Audio.ArtistColumns.ARTIST + " LIKE ?", new String[]{"%" + query + "%"});
public static ArrayList<Artist> getArtists(Context context, String query) {
Cursor cursor = makeArtistCursor(context, ArtistColumns.ARTIST + " LIKE ?", new String[]{"%" + query + "%"});
return getArtists(cursor);
}
@ -31,17 +31,11 @@ public class ArtistLoader {
return getArtist(cursor);
}
public static List<Artist> getArtists(Cursor cursor) {
List<Artist> artists = new ArrayList<>();
public static ArrayList<Artist> getArtists(Cursor cursor) {
ArrayList<Artist> artists = new ArrayList<>();
if (cursor != null && cursor.moveToFirst()) {
do {
final String artistName = cursor.getString(1);
final int id = cursor.getInt(0);
final int albumCount = cursor.getInt(2);
final int songCount = cursor.getInt(3);
final Artist artist = new Artist(id, artistName, albumCount, songCount);
artists.add(artist);
artists.add(getArtistFromCursorImpl(cursor));
} while (cursor.moveToNext());
}
@ -54,12 +48,7 @@ public class ArtistLoader {
public static Artist getArtist(Cursor cursor) {
Artist artist = new Artist();
if (cursor != null && cursor.moveToFirst()) {
final int id = cursor.getInt(0);
final String artistName = cursor.getString(1);
final int albumCount = cursor.getInt(2);
final int songCount = cursor.getInt(3);
artist = new Artist(id, artistName, albumCount, songCount);
artist = getArtistFromCursorImpl(cursor);
}
if (cursor != null) {
@ -68,17 +57,26 @@ public class ArtistLoader {
return artist;
}
private static Artist getArtistFromCursorImpl(Cursor cursor) {
final int id = cursor.getInt(0);
final String artistName = cursor.getString(1);
final int albumCount = cursor.getInt(2);
final int songCount = cursor.getInt(3);
return new Artist(id, artistName, albumCount, songCount);
}
public static Cursor makeArtistCursor(final Context context, final String selection, final String[] values) {
return context.getContentResolver().query(MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI,
new String[]{
/* 0 */
BaseColumns._ID,
/* 1 */
MediaStore.Audio.ArtistColumns.ARTIST,
ArtistColumns.ARTIST,
/* 2 */
MediaStore.Audio.ArtistColumns.NUMBER_OF_ALBUMS,
ArtistColumns.NUMBER_OF_ALBUMS,
/* 3 */
MediaStore.Audio.ArtistColumns.NUMBER_OF_TRACKS
ArtistColumns.NUMBER_OF_TRACKS
}, selection, values, PreferenceUtils.getInstance(context).getArtistSortOrder());
}
}

View file

@ -2,7 +2,6 @@ package com.kabouzeid.gramophone.loader;
import android.content.Context;
import android.database.Cursor;
import android.provider.BaseColumns;
import android.provider.MediaStore;
import com.kabouzeid.gramophone.model.Song;
@ -16,47 +15,17 @@ import java.util.ArrayList;
public class ArtistSongLoader {
public static ArrayList<Song> getArtistSongList(final Context context, final int artistId) {
Cursor cursor = makeArtistSongCursor(context, artistId);
ArrayList<Song> songs = new ArrayList<>();
if (cursor != null && cursor.moveToFirst()) {
do {
final int id = cursor.getInt(0);
final String songName = cursor.getString(1);
final String artist = cursor.getString(2);
final String album = cursor.getString(3);
final long duration = cursor.getLong(4);
final int trackNumber = cursor.getInt(5);
final int albumId = cursor.getInt(6);
final Song song = new Song(id, albumId, artistId, songName, artist, album, duration, trackNumber);
songs.add(song);
} while (cursor.moveToNext());
}
if (cursor != null)
cursor.close();
return songs;
return SongLoader.getSongs(makeArtistSongCursor(context, artistId));
}
public static Cursor makeArtistSongCursor(final Context context, final int artistId) {
return context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
return SongLoader.makeSongCursor(
context,
MediaStore.Audio.AudioColumns.ARTIST_ID + "=?",
new String[]{
/* 0 */
BaseColumns._ID,
/* 1 */
MediaStore.Audio.AudioColumns.TITLE,
/* 2 */
MediaStore.Audio.AudioColumns.ARTIST,
/* 3 */
MediaStore.Audio.AudioColumns.ALBUM,
/* 4 */
MediaStore.Audio.AudioColumns.DURATION,
/* 5 */
MediaStore.Audio.AudioColumns.TRACK,
/* 6 */
MediaStore.Audio.AudioColumns.ALBUM_ID
}, (MediaStore.Audio.AudioColumns.IS_MUSIC + "=1") + " AND " +
MediaStore.Audio.AudioColumns.TITLE + " != ''" + " AND " +
MediaStore.Audio.AudioColumns.ARTIST_ID + "=" + artistId, null,
PreferenceUtils.getInstance(context).getArtistSongSortOrder());
String.valueOf(artistId)
},
PreferenceUtils.getInstance(context).getArtistSongSortOrder()
);
}
}

View file

@ -2,9 +2,7 @@ package com.kabouzeid.gramophone.loader;
import android.content.Context;
import android.database.Cursor;
import android.provider.BaseColumns;
import android.provider.MediaStore;
import android.provider.MediaStore.Audio.AudioColumns;
import com.kabouzeid.gramophone.model.Song;
import com.kabouzeid.gramophone.util.PreferenceUtils;
@ -25,31 +23,10 @@ public class LastAddedLoader {
cutoff = fourWeeksAgo;
}
//noinspection StringBufferReplaceableByString
final StringBuilder selection = new StringBuilder();
selection.append(AudioColumns.IS_MUSIC + "=1");
selection.append(" AND " + AudioColumns.TITLE + " != ''");
selection.append(" AND " + MediaStore.Audio.Media.DATE_ADDED + ">");
selection.append(cutoff);
return context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
new String[]{
/* 0 */
BaseColumns._ID,
/* 1 */
MediaStore.Audio.AudioColumns.TITLE,
/* 2 */
MediaStore.Audio.AudioColumns.ARTIST,
/* 3 */
MediaStore.Audio.AudioColumns.ALBUM,
/* 4 */
MediaStore.Audio.AudioColumns.DURATION,
/* 5 */
MediaStore.Audio.AudioColumns.TRACK,
/* 6 */
MediaStore.Audio.AudioColumns.ARTIST_ID,
/* 7 */
MediaStore.Audio.AudioColumns.ALBUM_ID
}, selection.toString(), null, MediaStore.Audio.Media.DATE_ADDED + " DESC");
return SongLoader.makeSongCursor(
context,
MediaStore.Audio.Media.DATE_ADDED + ">",
new String[]{String.valueOf(cutoff)},
MediaStore.Audio.Media.DATE_ADDED + " DESC");
}
}

View file

@ -13,44 +13,47 @@ import java.util.List;
public class PlaylistLoader {
public static Playlist getPlaylist(final Context context, final int playlistId) {
Playlist playlist = new Playlist();
Cursor cursor = makePlaylistCursor(context, BaseColumns._ID + "=?", new String[]{String.valueOf(playlistId)});
if (cursor != null && cursor.moveToFirst()) {
final int id = cursor.getInt(0);
final String name = cursor.getString(1);
playlist = new Playlist(id, name);
public static List<Playlist> getAllPlaylists(final Context context) {
return getAllPlaylists(makePlaylistCursor(context, null, null));
}
if (cursor != null)
cursor.close();
return playlist;
public static Playlist getPlaylist(final Context context, final int playlistId) {
return getPlaylist(makePlaylistCursor(
context,
BaseColumns._ID + "=?",
new String[]{
String.valueOf(playlistId)
}
));
}
public static Playlist getPlaylist(final Context context, final String playlistName) {
return getPlaylist(makePlaylistCursor(
context,
PlaylistsColumns.NAME + "=?",
new String[]{
playlistName
}
));
}
public static Playlist getPlaylist(final Cursor cursor) {
Playlist playlist = new Playlist();
Cursor cursor = makePlaylistCursor(context, PlaylistsColumns.NAME + "=?", new String[]{playlistName});
if (cursor != null && cursor.moveToFirst()) {
final int id = cursor.getInt(0);
final String name = cursor.getString(1);
playlist = new Playlist(id, name);
playlist = getPlaylistFromCursorImpl(cursor);
}
if (cursor != null)
cursor.close();
return playlist;
}
public static List<Playlist> getAllPlaylists(final Context context) {
public static List<Playlist> getAllPlaylists(final Cursor cursor) {
List<Playlist> playlists = new ArrayList<>();
Cursor cursor = makePlaylistCursor(context, null, null);
if (cursor != null && cursor.moveToFirst()) {
do {
final int id = cursor.getInt(0);
final String name = cursor.getString(1);
final Playlist playlist = new Playlist(id, name);
playlists.add(playlist);
playlists.add(getPlaylistFromCursorImpl(cursor));
} while (cursor.moveToNext());
}
if (cursor != null)
@ -58,6 +61,12 @@ public class PlaylistLoader {
return playlists;
}
private static Playlist getPlaylistFromCursorImpl(final Cursor cursor) {
final int id = cursor.getInt(0);
final String name = cursor.getString(1);
return new Playlist(id, name);
}
public static Cursor makePlaylistCursor(final Context context, final String selection, final String[] values) {
return context.getContentResolver().query(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI,
new String[]{

View file

@ -11,25 +11,13 @@ import java.util.ArrayList;
public class PlaylistSongLoader {
public static ArrayList<PlaylistSong> getPlaylistSongList(final Context context, final int playlistID) {
public static ArrayList<PlaylistSong> getPlaylistSongList(final Context context, final int playlistId) {
ArrayList<PlaylistSong> songs = new ArrayList<>();
Cursor cursor = makePlaylistSongCursor(context, playlistID);
Cursor cursor = makePlaylistSongCursor(context, playlistId);
if (cursor != null && cursor.moveToFirst()) {
do {
final int id = cursor.getInt(0);
final String songName = cursor.getString(1);
final String artist = cursor.getString(2);
final String album = cursor.getString(3);
final long duration = cursor.getLong(4);
final int trackNumber = cursor.getInt(5);
final int albumId = cursor.getInt(6);
final int artistId = cursor.getInt(7);
final int idInPlaylist = cursor.getInt(8);
final PlaylistSong song = new PlaylistSong(id, albumId, artistId, songName, artist, album, duration, trackNumber, playlistID, idInPlaylist);
songs.add(song);
songs.add(getPlaylistSongFromCursorImpl(cursor));
} while (cursor.moveToNext());
}
if (cursor != null) {
@ -38,9 +26,25 @@ public class PlaylistSongLoader {
return songs;
}
public static Cursor makePlaylistSongCursor(final Context context, final int playlistID) {
private static PlaylistSong getPlaylistSongFromCursorImpl(Cursor cursor) {
final int id = cursor.getInt(0);
final String songName = cursor.getString(1);
final String artist = cursor.getString(2);
final String album = cursor.getString(3);
final long duration = cursor.getLong(4);
final int trackNumber = cursor.getInt(5);
final int albumId = cursor.getInt(6);
final int artistId = cursor.getInt(7);
final String data = cursor.getString(8);
final int idInPlaylist = cursor.getInt(9);
final int playlistId = cursor.getInt(10);
return new PlaylistSong(id, albumId, artistId, songName, artist, album, duration, trackNumber, data, playlistId, idInPlaylist);
}
public static Cursor makePlaylistSongCursor(final Context context, final int playlistId) {
return context.getContentResolver().query(
MediaStore.Audio.Playlists.Members.getContentUri("external", playlistID),
MediaStore.Audio.Playlists.Members.getContentUri("external", playlistId),
new String[]{
/* 0 */
MediaStore.Audio.Playlists.Members.AUDIO_ID,
@ -59,8 +63,12 @@ public class PlaylistSongLoader {
/* 7 */
AudioColumns.ARTIST_ID,
/* 8 */
AudioColumns.DATA,
/* 9 */
MediaStore.Audio.Playlists.Members.PLAYLIST_ID,
/* 10 */
MediaStore.Audio.Playlists.Members._ID
}, (AudioColumns.IS_MUSIC + "=1") + " AND " + AudioColumns.TITLE + " != ''", null,
}, SongLoader.BASE_SELECTION, null,
MediaStore.Audio.Playlists.Members.DEFAULT_SORT_ORDER);
}
}

View file

@ -1,60 +0,0 @@
package com.kabouzeid.gramophone.loader;
import android.content.Context;
import android.database.Cursor;
import android.provider.BaseColumns;
import android.provider.MediaStore;
import java.util.ArrayList;
import java.util.List;
/**
* @author Karim Abou Zeid (kabouzeid)
*/
public class SongFilePathLoader {
public static final String TAG = SongFilePathLoader.class.getSimpleName();
public static List<String> getSongFilePaths(Context context, int[] queryIds) {
StringBuilder selectionBuilder = new StringBuilder();
selectionBuilder.append(BaseColumns._ID).append(" IN(");
for (int i = 0; i < queryIds.length; i++) {
selectionBuilder.append(queryIds[i]);
if (i < queryIds.length - 1) {
selectionBuilder.append(",");
}
}
selectionBuilder.append(")");
Cursor cursor = makeSongFilePathCursor(context, selectionBuilder.toString());
List<String> songFiles = new ArrayList<>();
if (cursor != null && cursor.moveToFirst()) {
do {
songFiles.add(cursor.getString(0));
} while (cursor.moveToNext());
}
if (cursor != null) {
cursor.close();
}
return songFiles;
}
public static String getSongFilePath(Context context, int queryId) {
try {
return getSongFilePaths(context, new int[]{queryId}).get(0);
} catch (Exception e) {
return "";
}
}
public static Cursor makeSongFilePathCursor(final Context context) {
return makeSongFilePathCursor(context, null);
}
public static Cursor makeSongFilePathCursor(final Context context, String selection) {
return context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
new String[]{
/* 0 */
MediaStore.Audio.AudioColumns.DATA,
}, selection, null, null);
}
}

View file

@ -4,6 +4,7 @@ import android.content.Context;
import android.database.Cursor;
import android.provider.BaseColumns;
import android.provider.MediaStore;
import android.provider.MediaStore.Audio.AudioColumns;
import com.kabouzeid.gramophone.model.Song;
import com.kabouzeid.gramophone.util.PreferenceUtils;
@ -14,7 +15,7 @@ import java.util.ArrayList;
* @author Karim Abou Zeid (kabouzeid)
*/
public class SongLoader {
private static final String BASE_SELECTION = MediaStore.Audio.AudioColumns.IS_MUSIC + "=1" + " AND " + MediaStore.Audio.AudioColumns.TITLE + " != ''";
protected static final String BASE_SELECTION = AudioColumns.IS_MUSIC + "=1" + " AND " + AudioColumns.TITLE + " != ''";
public static ArrayList<Song> getAllSongs(Context context) {
Cursor cursor = makeSongCursor(context, null, null);
@ -22,12 +23,12 @@ public class SongLoader {
}
public static ArrayList<Song> getSongs(final Context context, final String query) {
Cursor cursor = makeSongCursor(context, MediaStore.Audio.AudioColumns.TITLE + " LIKE ?", new String[]{"%" + query + "%"});
Cursor cursor = makeSongCursor(context, AudioColumns.TITLE + " LIKE ?", new String[]{"%" + query + "%"});
return getSongs(cursor);
}
public static Song getSong(final Context context, final int queryId) {
Cursor cursor = makeSongCursor(context, MediaStore.Audio.AudioColumns._ID + "=?", new String[]{String.valueOf(queryId)});
Cursor cursor = makeSongCursor(context, AudioColumns._ID + "=?", new String[]{String.valueOf(queryId)});
return getSong(cursor);
}
@ -35,17 +36,7 @@ public class SongLoader {
ArrayList<Song> songs = new ArrayList<>();
if (cursor != null && cursor.moveToFirst()) {
do {
final String songName = cursor.getString(1);
final int id = cursor.getInt(0);
final String artist = cursor.getString(2);
final String album = cursor.getString(3);
final long duration = cursor.getLong(4);
final int trackNumber = cursor.getInt(5);
final int artistId = cursor.getInt(6);
final int albumId = cursor.getInt(7);
final Song song = new Song(id, albumId, artistId, songName, artist, album, duration, trackNumber);
songs.add(song);
songs.add(getSongFromCursorImpl(cursor));
} while (cursor.moveToNext());
}
@ -57,6 +48,15 @@ public class SongLoader {
public static Song getSong(Cursor cursor) {
Song song = new Song();
if (cursor != null && cursor.moveToFirst()) {
song = getSongFromCursorImpl(cursor);
}
if (cursor != null) {
cursor.close();
}
return song;
}
private static Song getSongFromCursorImpl(Cursor cursor) {
final int id = cursor.getInt(0);
final String songName = cursor.getString(1);
final String artist = cursor.getString(2);
@ -65,15 +65,15 @@ public class SongLoader {
final int trackNumber = cursor.getInt(5);
final int artistId = cursor.getInt(6);
final int albumId = cursor.getInt(7);
song = new Song(id, albumId, artistId, songName, artist, album, duration, trackNumber);
}
if (cursor != null) {
cursor.close();
}
return song;
final String data = cursor.getString(8);
return new Song(id, albumId, artistId, songName, artist, album, duration, trackNumber, data);
}
public static Cursor makeSongCursor(final Context context, final String selection, final String[] values) {
return makeSongCursor(context, selection, values, PreferenceUtils.getInstance(context).getSongSortOrder());
}
public static Cursor makeSongCursor(final Context context, final String selection, final String[] values, final String sortOrder) {
String baseSelection = BASE_SELECTION;
if (selection != null && !selection.trim().equals("")) {
baseSelection += " AND " + selection;
@ -84,19 +84,21 @@ public class SongLoader {
/* 0 */
BaseColumns._ID,
/* 1 */
MediaStore.Audio.AudioColumns.TITLE,
AudioColumns.TITLE,
/* 2 */
MediaStore.Audio.AudioColumns.ARTIST,
AudioColumns.ARTIST,
/* 3 */
MediaStore.Audio.AudioColumns.ALBUM,
AudioColumns.ALBUM,
/* 4 */
MediaStore.Audio.AudioColumns.DURATION,
AudioColumns.DURATION,
/* 5 */
MediaStore.Audio.AudioColumns.TRACK,
AudioColumns.TRACK,
/* 6 */
MediaStore.Audio.AudioColumns.ARTIST_ID,
AudioColumns.ARTIST_ID,
/* 7 */
MediaStore.Audio.AudioColumns.ALBUM_ID
}, baseSelection, values, PreferenceUtils.getInstance(context).getSongSortOrder());
AudioColumns.ALBUM_ID,
/* 8 */
AudioColumns.DATA
}, baseSelection, values, sortOrder);
}
}

View file

@ -8,8 +8,8 @@ public class PlaylistSong extends Song {
public final int idInPlayList;
public PlaylistSong(final int id, final int albumId, final int artistId, final String title, final String artistName,
final String albumName, final long duration, final int trackNumber, final int playlistId, final int idInPlayList) {
super(id, albumId, artistId, title, artistName, albumName, duration, trackNumber);
final String albumName, final long duration, final int trackNumber, final String data, final int playlistId, final int idInPlayList) {
super(id, albumId, artistId, title, artistName, albumName, duration, trackNumber, data);
this.playlistId = playlistId;
this.idInPlayList = idInPlayList;
}

View file

@ -19,9 +19,10 @@ public class Song implements Serializable {
public final String albumName;
public final long duration;
public final int trackNumber;
public final String data;
public Song(final int id, final int albumId, final int artistId, final String title, final String artistName,
final String albumName, final long duration, final int trackNumber) {
final String albumName, final long duration, final int trackNumber, final String data) {
this.id = id;
this.albumId = albumId;
this.artistId = artistId;
@ -30,6 +31,7 @@ public class Song implements Serializable {
this.albumName = albumName;
this.duration = duration;
this.trackNumber = trackNumber;
this.data = data;
}
public Song() {
@ -41,6 +43,7 @@ public class Song implements Serializable {
this.albumName = "";
this.duration = -1;
this.trackNumber = -1;
this.data = "";
}
@Override

View file

@ -21,7 +21,7 @@ import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.provider.BaseColumns;
import android.provider.MediaStore;
import android.provider.MediaStore.Audio.AudioColumns;
import com.kabouzeid.gramophone.loader.SongLoader;
import com.kabouzeid.gramophone.model.Song;
@ -38,7 +38,7 @@ public class MusicPlaybackQueueStore extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "music_playback_state.db";
public static final String PLAYING_QUEUE_TABLE_NAME = "playing_queue";
public static final String ORIGINAL_PLAYING_QUEUE_TABLE_NAME = "original_playing_queue";
private static final int VERSION = 1;
private static final int VERSION = 2;
/**
* Constructor of <code>MusicPlaybackState</code>
@ -65,26 +65,29 @@ public class MusicPlaybackQueueStore extends SQLiteOpenHelper {
builder.append(BaseColumns._ID);
builder.append(" INT NOT NULL,");
builder.append(MediaStore.Audio.AudioColumns.TITLE);
builder.append(AudioColumns.TITLE);
builder.append(" STRING NOT NULL,");
builder.append(MediaStore.Audio.AudioColumns.ARTIST);
builder.append(AudioColumns.ARTIST);
builder.append(" STRING NOT NULL,");
builder.append(MediaStore.Audio.AudioColumns.ALBUM);
builder.append(AudioColumns.ALBUM);
builder.append(" STRING NOT NULL,");
builder.append(MediaStore.Audio.AudioColumns.DURATION);
builder.append(AudioColumns.DURATION);
builder.append(" LONG NOT NULL,");
builder.append(MediaStore.Audio.AudioColumns.TRACK);
builder.append(AudioColumns.TRACK);
builder.append(" INT NOT NULL,");
builder.append(MediaStore.Audio.AudioColumns.ARTIST_ID);
builder.append(AudioColumns.ARTIST_ID);
builder.append(" INT NOT NULL,");
builder.append(MediaStore.Audio.AudioColumns.ALBUM_ID);
builder.append(" INT NOT NULL);");
builder.append(AudioColumns.ALBUM_ID);
builder.append(" INT NOT NULL,");
builder.append(AudioColumns.DATA);
builder.append(" STRING NOT NULL);");
db.execSQL(builder.toString());
}
@ -92,6 +95,9 @@ public class MusicPlaybackQueueStore extends SQLiteOpenHelper {
@Override
public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) {
// not necessary yet
db.execSQL("DROP TABLE IF EXISTS " + PLAYING_QUEUE_TABLE_NAME);
db.execSQL("DROP TABLE IF EXISTS " + ORIGINAL_PLAYING_QUEUE_TABLE_NAME);
onCreate(db);
}
@Override
@ -145,13 +151,14 @@ public class MusicPlaybackQueueStore extends SQLiteOpenHelper {
ContentValues values = new ContentValues(4);
values.put(BaseColumns._ID, song.id);
values.put(MediaStore.Audio.AudioColumns.TITLE, song.title);
values.put(MediaStore.Audio.AudioColumns.ARTIST, song.artistName);
values.put(MediaStore.Audio.AudioColumns.ALBUM, song.albumName);
values.put(MediaStore.Audio.AudioColumns.DURATION, song.duration);
values.put(MediaStore.Audio.AudioColumns.TRACK, song.trackNumber);
values.put(MediaStore.Audio.AudioColumns.ARTIST_ID, song.artistId);
values.put(MediaStore.Audio.AudioColumns.ALBUM_ID, song.albumId);
values.put(AudioColumns.TITLE, song.title);
values.put(AudioColumns.ARTIST, song.artistName);
values.put(AudioColumns.ALBUM, song.albumName);
values.put(AudioColumns.DURATION, song.duration);
values.put(AudioColumns.TRACK, song.trackNumber);
values.put(AudioColumns.ARTIST_ID, song.artistId);
values.put(AudioColumns.ALBUM_ID, song.albumId);
values.put(AudioColumns.DATA, song.data);
database.insert(tableName, null, values);
}

View file

@ -42,7 +42,8 @@ public class RecentlyPlayedStore extends SQLiteOpenHelper {
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// nothing to do here yet
db.execSQL("DROP TABLE IF EXISTS " + RecentStoreColumns.NAME);
onCreate(db);
}
@Override

View file

@ -96,7 +96,8 @@ public class SongPlayCountStore extends SQLiteOpenHelper {
@Override
public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) {
// No upgrade path needed yet
db.execSQL("DROP TABLE IF EXISTS " + SongPlayCountColumns.NAME);
onCreate(db);
}
@Override

View file

@ -42,7 +42,6 @@ import com.kabouzeid.gramophone.dialogs.SongDetailDialog;
import com.kabouzeid.gramophone.dialogs.SongShareDialog;
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
import com.kabouzeid.gramophone.helper.bitmapblur.StackBlurManager;
import com.kabouzeid.gramophone.loader.SongFilePathLoader;
import com.kabouzeid.gramophone.misc.SmallTransitionListener;
import com.kabouzeid.gramophone.model.Song;
import com.kabouzeid.gramophone.service.MusicService;
@ -641,7 +640,7 @@ public class MusicControllerActivity extends AbsFabActivity {
invalidateOptionsMenu();
return true;
case R.id.action_share:
SongShareDialog.create(song.id).show(getSupportFragmentManager(), "SHARE_SONG");
SongShareDialog.create(song).show(getSupportFragmentManager(), "SHARE_SONG");
return true;
case R.id.action_equalizer:
NavigationUtil.openEqualizer(this);
@ -664,8 +663,7 @@ public class MusicControllerActivity extends AbsFabActivity {
startActivity(intent);
return true;
case R.id.action_details:
String songFilePath = SongFilePathLoader.getSongFilePath(this, song.id);
File songFile = new File(songFilePath);
File songFile = new File(song.data);
SongDetailDialog.create(songFile).show(getSupportFragmentManager(), "SONG_DETAIL");
return true;
case R.id.action_go_to_album:

View file

@ -15,7 +15,6 @@ import com.kabouzeid.gramophone.lastfm.rest.LastFMRestClient;
import com.kabouzeid.gramophone.lastfm.rest.model.albuminfo.AlbumInfo;
import com.kabouzeid.gramophone.lastfm.rest.model.albuminfo.Image;
import com.kabouzeid.gramophone.loader.AlbumSongLoader;
import com.kabouzeid.gramophone.loader.SongFilePathLoader;
import com.kabouzeid.gramophone.model.Song;
import com.kabouzeid.gramophone.util.MusicUtil;
import com.nostra13.universalimageloader.core.ImageLoader;
@ -190,12 +189,12 @@ public class AlbumTagEditorActivity extends AbsTagEditorActivity implements Text
@Override
protected List<String> getSongPaths() {
List<Song> songs = AlbumSongLoader.getAlbumSongList(this, getId());
int[] songIds = new int[songs.size()];
for (int i = 0; i < songs.size(); i++) {
songIds[i] = songs.get(i).id;
ArrayList<Song> songs = AlbumSongLoader.getAlbumSongList(this, getId());
ArrayList<String> paths = new ArrayList<>(songs.size());
for (Song song : songs) {
paths.add(song.data);
}
return SongFilePathLoader.getSongFilePaths(this, songIds);
return paths;
}
@Override

View file

@ -7,10 +7,11 @@ import android.text.TextWatcher;
import android.widget.EditText;
import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.loader.SongFilePathLoader;
import com.kabouzeid.gramophone.loader.SongLoader;
import org.jaudiotagger.tag.FieldKey;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
@ -107,7 +108,9 @@ public class SongTagEditorActivity extends AbsTagEditorActivity implements TextW
@Override
protected List<String> getSongPaths() {
return SongFilePathLoader.getSongFilePaths(this, new int[]{getId()});
ArrayList<String> paths = new ArrayList<>(1);
paths.add(SongLoader.getSong(this, getId()).data);
return paths;
}
@Override

View file

@ -18,7 +18,6 @@ import com.kabouzeid.gramophone.App;
import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
import com.kabouzeid.gramophone.loader.PlaylistLoader;
import com.kabouzeid.gramophone.loader.SongFilePathLoader;
import com.kabouzeid.gramophone.loader.SongLoader;
import com.kabouzeid.gramophone.model.Artist;
import com.kabouzeid.gramophone.model.DataBaseChangedEvent;
@ -46,10 +45,10 @@ public class MusicUtil {
return ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, songId);
}
public static Intent createShareSongFileIntent(final Context context, int songId) {
public static Intent createShareSongFileIntent(final Song song) {
return new Intent()
.setAction(Intent.ACTION_SEND)
.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + SongFilePathLoader.getSongFilePath(context, songId)))
.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + song.data))
.setType("audio/*");
}
@ -80,7 +79,6 @@ public class MusicUtil {
} finally {
if (cursor != null) {
cursor.close();
cursor = null;
}
}
}