Fix and improve downloading song
* Fixed issue downloading all songs from an artist * Added download option for songs in songslistfragment * Created UIUtils.downloadSongs(...) to reduce code duplication * Refactored downloading of songs on host/artist/album levels All levels now use song display artist as artist and album display artist. This prevents downloading songs multiple times when downloading same song on different levels.
This commit is contained in:
parent
49a253af34
commit
b7b1470484
|
@ -817,6 +817,8 @@ public class MediaProvider extends ContentProvider {
|
|||
MediaDatabase.Tables.ALBUMS + "." + MediaContract.Albums.YEAR;
|
||||
String ALBUMS_THUMBNAIL =
|
||||
MediaDatabase.Tables.ALBUMS + "." + MediaContract.Albums.THUMBNAIL;
|
||||
String ALBUMS_DISPLAYARTIST =
|
||||
MediaDatabase.Tables.ALBUMS + "." + MediaContract.Albums.DISPLAYARTIST;
|
||||
String ALBUM_ARTISTS_HOST_ID =
|
||||
MediaDatabase.Tables.ALBUM_ARTISTS + "." + MediaContract.AlbumArtists.HOST_ID;
|
||||
String ALBUM_ARTISTS_ARTISTID =
|
||||
|
|
|
@ -60,7 +60,6 @@ import org.xbmc.kore.jsonrpc.method.Player;
|
|||
import org.xbmc.kore.jsonrpc.method.Playlist;
|
||||
import org.xbmc.kore.jsonrpc.type.PlaylistType;
|
||||
import org.xbmc.kore.provider.MediaContract;
|
||||
import org.xbmc.kore.provider.MediaDatabase;
|
||||
import org.xbmc.kore.utils.FileDownloadHelper;
|
||||
import org.xbmc.kore.utils.LogUtils;
|
||||
import org.xbmc.kore.utils.UIUtils;
|
||||
|
@ -107,7 +106,7 @@ public class AlbumDetailsFragment extends AbstractDetailsFragment
|
|||
// Album information
|
||||
private String albumDisplayArtist;
|
||||
private String albumTitle;
|
||||
private List<FileDownloadHelper.SongInfo> songInfoList = null;
|
||||
private ArrayList<FileDownloadHelper.SongInfo> songInfoList = null;
|
||||
|
||||
@InjectView(R.id.exit_transition_view) View exitTransitionView;
|
||||
// Buttons
|
||||
|
@ -339,61 +338,7 @@ public class AlbumDetailsFragment extends AbstractDetailsFragment
|
|||
|
||||
@Override
|
||||
protected void onDownload() {
|
||||
if ((albumTitle == null) || (albumDisplayArtist == null) ||
|
||||
(songInfoList == null) || (songInfoList.isEmpty())) {
|
||||
// Nothing to download
|
||||
Toast.makeText(getActivity(), R.string.no_files_to_download, Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
DialogInterface.OnClickListener noopClickListener =
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) { }
|
||||
};
|
||||
|
||||
// Check if the directory exists and whether to overwrite it
|
||||
File file = new File(songInfoList.get(0).getAbsoluteDirectoryPath());
|
||||
if (file.exists()) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
builder.setTitle(R.string.download)
|
||||
.setMessage(R.string.download_dir_exists)
|
||||
.setPositiveButton(R.string.overwrite,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
FileDownloadHelper.downloadFiles(getActivity(), hostInfo,
|
||||
songInfoList, FileDownloadHelper.OVERWRITE_FILES,
|
||||
callbackHandler);
|
||||
}
|
||||
})
|
||||
.setNeutralButton(R.string.download_with_new_name,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
FileDownloadHelper.downloadFiles(getActivity(), hostInfo,
|
||||
songInfoList, FileDownloadHelper.DOWNLOAD_WITH_NEW_NAME,
|
||||
callbackHandler);
|
||||
}
|
||||
})
|
||||
.setNegativeButton(android.R.string.cancel, noopClickListener)
|
||||
.show();
|
||||
} else {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
builder.setTitle(R.string.download)
|
||||
.setMessage(R.string.confirm_album_download)
|
||||
.setPositiveButton(android.R.string.ok,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
FileDownloadHelper.downloadFiles(getActivity(), hostInfo,
|
||||
songInfoList, FileDownloadHelper.OVERWRITE_FILES,
|
||||
callbackHandler);
|
||||
}
|
||||
})
|
||||
.setNegativeButton(android.R.string.cancel, noopClickListener)
|
||||
.show();
|
||||
}
|
||||
UIUtils.downloadSongs(getActivity(), songInfoList, hostInfo, callbackHandler);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -595,41 +540,10 @@ public class AlbumDetailsFragment extends AbstractDetailsFragment
|
|||
addToPlaylist(TYPE_SONG, songId);
|
||||
return true;
|
||||
case R.id.download:
|
||||
// Check if the file exists and whether to overwrite it
|
||||
File file = new File(songInfo.getAbsoluteFilePath());
|
||||
if (file.exists()) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
builder.setTitle(R.string.download)
|
||||
.setMessage(R.string.download_file_exists)
|
||||
.setPositiveButton(R.string.overwrite,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
FileDownloadHelper.downloadFiles(getActivity(), hostInfo,
|
||||
songInfo, FileDownloadHelper.OVERWRITE_FILES,
|
||||
callbackHandler);
|
||||
}
|
||||
})
|
||||
.setNeutralButton(R.string.download_with_new_name,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
FileDownloadHelper.downloadFiles(getActivity(), hostInfo,
|
||||
songInfo, FileDownloadHelper.DOWNLOAD_WITH_NEW_NAME,
|
||||
callbackHandler);
|
||||
}
|
||||
})
|
||||
.setNegativeButton(android.R.string.cancel,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) { }
|
||||
})
|
||||
.show();
|
||||
} else {
|
||||
FileDownloadHelper.downloadFiles(getActivity(), hostInfo,
|
||||
songInfo, FileDownloadHelper.DOWNLOAD_WITH_NEW_NAME,
|
||||
callbackHandler);
|
||||
}
|
||||
ArrayList<FileDownloadHelper.SongInfo> songInfoList = new ArrayList<>();
|
||||
songInfoList.add(songInfo);
|
||||
UIUtils.downloadSongs(getActivity(), songInfoList,
|
||||
hostInfo, callbackHandler);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -655,9 +569,11 @@ public class AlbumDetailsFragment extends AbstractDetailsFragment
|
|||
TextView details = (TextView)songView.findViewById(R.id.details);
|
||||
ImageView contextMenu = (ImageView)songView.findViewById(R.id.list_context_menu);
|
||||
|
||||
String artist = cursor.getString(AlbumSongsListQuery.ARTIST);
|
||||
|
||||
// Add this song to the list
|
||||
FileDownloadHelper.SongInfo songInfo = new FileDownloadHelper.SongInfo(
|
||||
albumDisplayArtist,
|
||||
artist,
|
||||
albumTitle,
|
||||
cursor.getInt(AlbumSongsListQuery.SONGID),
|
||||
cursor.getInt(AlbumSongsListQuery.TRACK),
|
||||
|
@ -670,7 +586,6 @@ public class AlbumDetailsFragment extends AbstractDetailsFragment
|
|||
|
||||
trackNumber.setText(String.valueOf(songInfo.track));
|
||||
|
||||
String artist = cursor.getString(AlbumSongsListQuery.ARTIST);
|
||||
String duration = UIUtils.formatTime(cursor.getInt(AlbumSongsListQuery.DURATION));
|
||||
String detailsText = TextUtils.isEmpty(artist) ? duration : duration + " | " + artist;
|
||||
details.setText(detailsText);
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
package org.xbmc.kore.ui;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.res.Resources;
|
||||
import android.database.Cursor;
|
||||
|
@ -55,15 +54,14 @@ import org.xbmc.kore.jsonrpc.method.Player;
|
|||
import org.xbmc.kore.jsonrpc.type.PlaylistType;
|
||||
import org.xbmc.kore.provider.MediaContract;
|
||||
import org.xbmc.kore.provider.MediaDatabase;
|
||||
import org.xbmc.kore.provider.MediaProvider;
|
||||
import org.xbmc.kore.utils.FileDownloadHelper;
|
||||
import org.xbmc.kore.utils.LogUtils;
|
||||
import org.xbmc.kore.utils.MediaPlayerUtils;
|
||||
import org.xbmc.kore.utils.UIUtils;
|
||||
import org.xbmc.kore.utils.Utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.InjectView;
|
||||
|
@ -83,8 +81,7 @@ public class ArtistOverviewFragment extends AbstractDetailsFragment
|
|||
|
||||
// Loader IDs
|
||||
private static final int LOADER_ARTIST = 0,
|
||||
LOADER_ALBUMS = 1,
|
||||
LOADER_SONGS = 2;
|
||||
LOADER_SONGS = 1;
|
||||
|
||||
private HostManager hostManager;
|
||||
private HostInfo hostInfo;
|
||||
|
@ -97,9 +94,7 @@ public class ArtistOverviewFragment extends AbstractDetailsFragment
|
|||
private int artistId = -1;
|
||||
|
||||
private String artistTitle;
|
||||
|
||||
private HashMap<Integer, String> albumTitles = new HashMap<>();
|
||||
|
||||
|
||||
@InjectView(R.id.exit_transition_view) View exitTransitionView;
|
||||
// Buttons
|
||||
@InjectView(R.id.fab) ImageButton fabButton;
|
||||
|
@ -180,7 +175,7 @@ public class ArtistOverviewFragment extends AbstractDetailsFragment
|
|||
|
||||
@Override
|
||||
protected void onDownload() {
|
||||
getLoaderManager().initLoader(LOADER_ALBUMS, null, this);
|
||||
getLoaderManager().initLoader(LOADER_SONGS, null, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -200,7 +195,6 @@ public class ArtistOverviewFragment extends AbstractDetailsFragment
|
|||
public void onPause() {
|
||||
//Make sure loader is not reloaded for albums and songs when we return
|
||||
//These loaders should only be activated by the user pressing the download button
|
||||
getLoaderManager().destroyLoader(LOADER_ALBUMS);
|
||||
getLoaderManager().destroyLoader(LOADER_SONGS);
|
||||
super.onPause();
|
||||
}
|
||||
|
@ -222,10 +216,6 @@ public class ArtistOverviewFragment extends AbstractDetailsFragment
|
|||
uri = MediaContract.Artists.buildArtistUri(hostInfo.getId(), artistId);
|
||||
return new CursorLoader(getActivity(), uri,
|
||||
DetailsQuery.PROJECTION, null, null, null);
|
||||
case LOADER_ALBUMS:
|
||||
uri = MediaContract.AlbumArtists.buildAlbumsForArtistListUri(hostInfo.getId(), artistId);
|
||||
return new CursorLoader(getActivity(), uri,
|
||||
AlbumListQuery.PROJECTION, null, null, null);
|
||||
case LOADER_SONGS:
|
||||
uri = MediaContract.Songs.buildArtistSongsListUri(hostInfo.getId(), artistId);
|
||||
return new CursorLoader(getActivity(), uri,
|
||||
|
@ -243,10 +233,6 @@ public class ArtistOverviewFragment extends AbstractDetailsFragment
|
|||
case LOADER_ARTIST:
|
||||
displayArtistDetails(cursor);
|
||||
break;
|
||||
case LOADER_ALBUMS:
|
||||
createAlbumList(cursor);
|
||||
getLoaderManager().initLoader(LOADER_SONGS, null, this);
|
||||
break;
|
||||
case LOADER_SONGS:
|
||||
downloadSongs(cursor);
|
||||
}
|
||||
|
@ -298,27 +284,13 @@ public class ArtistOverviewFragment extends AbstractDetailsFragment
|
|||
}
|
||||
|
||||
private FileDownloadHelper.SongInfo createSongInfo(Cursor cursor) {
|
||||
FileDownloadHelper.SongInfo songInfo = null;
|
||||
String albumTitle = albumTitles.get(cursor.getInt(SongsListQuery.ALBUMID));
|
||||
if (albumTitle != null) {
|
||||
// Add this song to the list
|
||||
songInfo = new FileDownloadHelper.SongInfo(
|
||||
artistTitle,
|
||||
albumTitle,
|
||||
cursor.getInt(SongsListQuery.SONGID),
|
||||
cursor.getInt(SongsListQuery.TRACK),
|
||||
cursor.getString(SongsListQuery.TITLE),
|
||||
cursor.getString(SongsListQuery.FILE));
|
||||
}
|
||||
return songInfo;
|
||||
}
|
||||
|
||||
private void createAlbumList(Cursor cursor) {
|
||||
if (cursor.moveToFirst()) {
|
||||
do {
|
||||
albumTitles.put(cursor.getInt(AlbumListQuery.ALBUMID), cursor.getString(AlbumListQuery.TITLE));
|
||||
} while(cursor.moveToNext());
|
||||
}
|
||||
return new FileDownloadHelper.SongInfo(
|
||||
cursor.getString(SongsListQuery.DISPLAYARTIST),
|
||||
cursor.getString(SongsListQuery.ALBUMTITLE),
|
||||
cursor.getInt(SongsListQuery.SONGID),
|
||||
cursor.getInt(SongsListQuery.TRACK),
|
||||
cursor.getString(SongsListQuery.TITLE),
|
||||
cursor.getString(SongsListQuery.FILE));
|
||||
}
|
||||
|
||||
private void downloadSongs(Cursor cursor) {
|
||||
|
@ -338,53 +310,7 @@ public class ArtistOverviewFragment extends AbstractDetailsFragment
|
|||
} while (cursor.moveToNext());
|
||||
}
|
||||
|
||||
if (songInfoList.size() == 0) {
|
||||
Toast.makeText(getActivity(), R.string.no_songs_to_download, Toast.LENGTH_LONG);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the directory exists and whether to overwrite it
|
||||
File file = new File(songInfoList.get(0).getAbsoluteDirectoryPath());
|
||||
if (file.exists()) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
builder.setTitle(R.string.download)
|
||||
.setMessage(R.string.download_dir_exists)
|
||||
.setPositiveButton(R.string.overwrite,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
FileDownloadHelper.downloadFiles(getActivity(), hostInfo,
|
||||
songInfoList, FileDownloadHelper.OVERWRITE_FILES,
|
||||
callbackHandler);
|
||||
}
|
||||
})
|
||||
.setNeutralButton(R.string.download_with_new_name,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
FileDownloadHelper.downloadFiles(getActivity(), hostInfo,
|
||||
songInfoList, FileDownloadHelper.DOWNLOAD_WITH_NEW_NAME,
|
||||
callbackHandler);
|
||||
}
|
||||
})
|
||||
.setNegativeButton(android.R.string.cancel, noopClickListener)
|
||||
.show();
|
||||
} else {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
builder.setTitle(R.string.download)
|
||||
.setMessage(R.string.confirm_artist_download)
|
||||
.setPositiveButton(android.R.string.ok,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
FileDownloadHelper.downloadFiles(getActivity(), hostInfo,
|
||||
songInfoList, FileDownloadHelper.OVERWRITE_FILES,
|
||||
callbackHandler);
|
||||
}
|
||||
})
|
||||
.setNegativeButton(android.R.string.cancel, noopClickListener)
|
||||
.show();
|
||||
}
|
||||
UIUtils.downloadSongs(getActivity(), songInfoList, hostInfo, callbackHandler);
|
||||
}
|
||||
|
||||
private void displayArtistDetails(Cursor cursor) {
|
||||
|
@ -447,30 +373,20 @@ public class ArtistOverviewFragment extends AbstractDetailsFragment
|
|||
int FANART = 6;
|
||||
}
|
||||
|
||||
private interface AlbumListQuery {
|
||||
String[] PROJECTION = {
|
||||
BaseColumns._ID,
|
||||
MediaContract.Albums.ALBUMID,
|
||||
MediaContract.Albums.TITLE,
|
||||
};
|
||||
|
||||
int ID = 0;
|
||||
int ALBUMID = 1;
|
||||
int TITLE = 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Song list query parameters.
|
||||
*/
|
||||
private interface SongsListQuery {
|
||||
String[] PROJECTION = {
|
||||
MediaDatabase.Tables.SONGS + "." + BaseColumns._ID,
|
||||
MediaDatabase.Tables.SONGS + "." + MediaContract.Songs.TITLE,
|
||||
MediaDatabase.Tables.SONGS + "." + MediaContract.Songs.TRACK,
|
||||
MediaDatabase.Tables.SONGS + "." + MediaContract.Songs.DURATION,
|
||||
MediaDatabase.Tables.SONGS + "." + MediaContract.Songs.FILE,
|
||||
MediaDatabase.Tables.SONGS + "." + MediaContract.Songs.SONGID,
|
||||
MediaDatabase.Tables.SONGS + "." + MediaContract.Songs.ALBUMID,
|
||||
MediaProvider.Qualified.SONGS_TITLE,
|
||||
MediaProvider.Qualified.SONGS_TRACK,
|
||||
MediaProvider.Qualified.SONGS_DURATION,
|
||||
MediaProvider.Qualified.SONGS_FILE,
|
||||
MediaProvider.Qualified.SONGS_SONGID,
|
||||
MediaProvider.Qualified.SONGS_ALBUMID,
|
||||
MediaProvider.Qualified.ALBUMS_TITLE,
|
||||
MediaProvider.Qualified.SONGS_DISPLAYARTIST
|
||||
};
|
||||
|
||||
String SORT = MediaContract.Songs.TRACK + " ASC";
|
||||
|
@ -482,5 +398,7 @@ public class ArtistOverviewFragment extends AbstractDetailsFragment
|
|||
int FILE = 4;
|
||||
int SONGID = 5;
|
||||
int ALBUMID = 6;
|
||||
int ALBUMTITLE = 7;
|
||||
int DISPLAYARTIST = 8;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ import android.content.res.Resources;
|
|||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.provider.BaseColumns;
|
||||
import android.os.Handler;
|
||||
import android.support.v4.content.CursorLoader;
|
||||
import android.support.v4.view.MenuItemCompat;
|
||||
import android.support.v7.widget.SearchView;
|
||||
|
@ -46,10 +46,12 @@ import org.xbmc.kore.provider.MediaContract;
|
|||
import org.xbmc.kore.provider.MediaDatabase;
|
||||
import org.xbmc.kore.provider.MediaProvider;
|
||||
import org.xbmc.kore.service.library.LibrarySyncService;
|
||||
import org.xbmc.kore.utils.FileDownloadHelper;
|
||||
import org.xbmc.kore.utils.LogUtils;
|
||||
import org.xbmc.kore.utils.MediaPlayerUtils;
|
||||
import org.xbmc.kore.utils.UIUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
|
@ -62,6 +64,8 @@ public class SongsListFragment extends AbstractCursorListFragment {
|
|||
|
||||
private int artistId = -1;
|
||||
|
||||
private Handler callbackHandler = new Handler();
|
||||
|
||||
@Override
|
||||
protected String getListSyncType() { return LibrarySyncService.SYNC_ALL_MUSIC; }
|
||||
|
||||
|
@ -158,7 +162,7 @@ public class SongsListFragment extends AbstractCursorListFragment {
|
|||
int DURATION = 3;
|
||||
int FILE = 4;
|
||||
int SONGID = 5;
|
||||
int SONGARTIST = 6;
|
||||
int SONGDISPLAYARTIST = 6;
|
||||
int ALBUMTITLE = 7;
|
||||
int GENRE = 8;
|
||||
int YEAR = 9;
|
||||
|
@ -194,6 +198,7 @@ public class SongsListFragment extends AbstractCursorListFragment {
|
|||
viewHolder.details = (TextView)view.findViewById(R.id.details);
|
||||
viewHolder.art = (ImageView)view.findViewById(R.id.art);
|
||||
viewHolder.artist = (TextView)view.findViewById(R.id.artist);
|
||||
viewHolder.songInfo = new FileDownloadHelper.SongInfo();
|
||||
|
||||
view.setTag(viewHolder);
|
||||
return view;
|
||||
|
@ -206,22 +211,22 @@ public class SongsListFragment extends AbstractCursorListFragment {
|
|||
final ViewHolder viewHolder = (ViewHolder)view.getTag();
|
||||
|
||||
String title = cursor.getString(SongsListQuery.TITLE);
|
||||
viewHolder.songId = cursor.getInt(SongsListQuery.SONGID);
|
||||
|
||||
viewHolder.title.setText(title);
|
||||
|
||||
String artist = cursor.getString(SongsListQuery.SONGARTIST);
|
||||
String artist = cursor.getString(SongsListQuery.SONGDISPLAYARTIST);
|
||||
viewHolder.artist.setText(artist);
|
||||
|
||||
String albumTitle = cursor.getString(SongsListQuery.ALBUMTITLE);
|
||||
int year = cursor.getInt(SongsListQuery.YEAR);
|
||||
if (year > 0) {
|
||||
setDetails(viewHolder.details,
|
||||
cursor.getString(SongsListQuery.ALBUMTITLE),
|
||||
albumTitle,
|
||||
String.valueOf(year),
|
||||
cursor.getString(SongsListQuery.GENRE));
|
||||
} else {
|
||||
setDetails(viewHolder.details,
|
||||
cursor.getString(SongsListQuery.ALBUMTITLE),
|
||||
albumTitle,
|
||||
cursor.getString(SongsListQuery.GENRE));
|
||||
}
|
||||
|
||||
|
@ -230,6 +235,13 @@ public class SongsListFragment extends AbstractCursorListFragment {
|
|||
thumbnail, title,
|
||||
viewHolder.art, artWidth, artHeight);
|
||||
|
||||
viewHolder.songInfo.artist = artist;
|
||||
viewHolder.songInfo.album = albumTitle;
|
||||
viewHolder.songInfo.songId = cursor.getInt(SongsListQuery.SONGID);
|
||||
viewHolder.songInfo.title = cursor.getString(SongsListQuery.TITLE);
|
||||
viewHolder.songInfo.fileName = cursor.getString(SongsListQuery.FILE);
|
||||
viewHolder.songInfo.track = cursor.getInt(SongsListQuery.TRACK);
|
||||
|
||||
// For the popupmenu
|
||||
ImageView contextMenu = (ImageView)view.findViewById(R.id.list_context_menu);
|
||||
contextMenu.setTag(viewHolder);
|
||||
|
@ -251,27 +263,33 @@ public class SongsListFragment extends AbstractCursorListFragment {
|
|||
TextView details;
|
||||
TextView artist;
|
||||
|
||||
int songId;
|
||||
FileDownloadHelper.SongInfo songInfo;
|
||||
}
|
||||
|
||||
private void showPopupMenu(View v) {
|
||||
ViewHolder viewHolder = (ViewHolder) v.getTag();
|
||||
final ViewHolder viewHolder = (ViewHolder) v.getTag();
|
||||
|
||||
final PlaylistType.Item playListItem = new PlaylistType.Item();
|
||||
playListItem.songid = viewHolder.songId;
|
||||
|
||||
final PopupMenu popupMenu = new PopupMenu(getActivity(), v);
|
||||
popupMenu.getMenuInflater().inflate(R.menu.musiclist_item, popupMenu.getMenu());
|
||||
popupMenu.getMenuInflater().inflate(R.menu.song_item, popupMenu.getMenu());
|
||||
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_play:
|
||||
case R.id.action_play_song:
|
||||
MediaPlayerUtils.play(SongsListFragment.this, playListItem);
|
||||
return true;
|
||||
case R.id.action_queue:
|
||||
case R.id.action_add_to_playlist:
|
||||
MediaPlayerUtils.queue(SongsListFragment.this, playListItem, PlaylistType.GetPlaylistsReturnType.AUDIO);
|
||||
return true;
|
||||
case R.id.download:
|
||||
ArrayList<FileDownloadHelper.SongInfo> songInfoList = new ArrayList<>();
|
||||
songInfoList.add(viewHolder.songInfo);
|
||||
UIUtils.downloadSongs(getActivity(),
|
||||
songInfoList,
|
||||
HostManager.getInstance(getActivity()).getHostInfo(),
|
||||
callbackHandler);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ public class FileDownloadHelper {
|
|||
NO_TVSHOW_TITLE_DIR = "No title";
|
||||
|
||||
public static abstract class MediaInfo {
|
||||
public final String fileName;
|
||||
public String fileName;
|
||||
|
||||
public MediaInfo(final String fileName) {
|
||||
this.fileName = fileName;
|
||||
|
@ -106,11 +106,20 @@ public class FileDownloadHelper {
|
|||
* Info for downloading songs
|
||||
*/
|
||||
public static class SongInfo extends MediaInfo {
|
||||
public final String artist;
|
||||
public final String album;
|
||||
public final int songId;
|
||||
public final int track;
|
||||
public final String title;
|
||||
public String artist;
|
||||
public String album;
|
||||
public int songId;
|
||||
public int track;
|
||||
public String title;
|
||||
|
||||
public SongInfo() {
|
||||
super(null);
|
||||
artist = null;
|
||||
album = null;
|
||||
songId = -1;
|
||||
track = -1;
|
||||
title = null;
|
||||
}
|
||||
|
||||
public SongInfo(final String artist, final String album,
|
||||
final int songId, final int track, final String title,
|
||||
|
|
|
@ -18,11 +18,14 @@ package org.xbmc.kore.utils;
|
|||
import android.animation.Animator;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Handler;
|
||||
import android.os.Vibrator;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.annotation.NonNull;
|
||||
|
@ -46,6 +49,7 @@ import org.xbmc.kore.jsonrpc.type.GlobalType;
|
|||
import org.xbmc.kore.jsonrpc.type.VideoType;
|
||||
import org.xbmc.kore.ui.RemoteActivity;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -472,4 +476,89 @@ public class UIUtils {
|
|||
container.getHitRect(containerBounds);
|
||||
return view.getLocalVisibleRect(containerBounds);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Downloads a list of songs. Asks the user for confirmation if one or more songs
|
||||
* already exist on the device
|
||||
* @param context required to show the user a dialog
|
||||
* @param songInfoList the song infos for the songs that need to be downloaded
|
||||
* @param hostInfo the host info from which the songs should be downloaded
|
||||
* @param callbackHandler Thread handler that should be used to handle the download result
|
||||
*/
|
||||
public static void downloadSongs(final Context context,
|
||||
final ArrayList<FileDownloadHelper.SongInfo> songInfoList,
|
||||
final HostInfo hostInfo,
|
||||
final Handler callbackHandler) {
|
||||
if (songInfoList == null || songInfoList.size() == 0) {
|
||||
Toast.makeText(context, R.string.no_songs_to_download, Toast.LENGTH_LONG);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if any file exists and whether to overwrite it
|
||||
boolean someFilesExist = false;
|
||||
for (FileDownloadHelper.SongInfo songInfo : songInfoList) {
|
||||
File file = new File(songInfoList.get(0).getAbsoluteFilePath());
|
||||
if (file.exists()) {
|
||||
someFilesExist = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (someFilesExist) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setTitle(R.string.download)
|
||||
.setMessage(songInfoList.size() > 1 ? R.string.download_files_exists : R.string.download_file_exists)
|
||||
.setPositiveButton(R.string.overwrite,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
FileDownloadHelper.downloadFiles(context, hostInfo,
|
||||
songInfoList, FileDownloadHelper.OVERWRITE_FILES,
|
||||
callbackHandler);
|
||||
}
|
||||
})
|
||||
.setNeutralButton(R.string.download_with_new_name,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
FileDownloadHelper.downloadFiles(context, hostInfo,
|
||||
songInfoList, FileDownloadHelper.DOWNLOAD_WITH_NEW_NAME,
|
||||
callbackHandler);
|
||||
}
|
||||
})
|
||||
.setNegativeButton(android.R.string.cancel,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) { }
|
||||
})
|
||||
.show();
|
||||
} else {
|
||||
if ( songInfoList.size() > 12 ) { // No scientific reason this should be 12. I just happen to like 12.
|
||||
String message = context.getResources().getString(R.string.confirm_songs_download);
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setTitle(R.string.download)
|
||||
.setMessage(String.format(message, songInfoList.size()))
|
||||
.setPositiveButton(android.R.string.ok,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
FileDownloadHelper.downloadFiles(context, hostInfo,
|
||||
songInfoList, FileDownloadHelper.OVERWRITE_FILES,
|
||||
callbackHandler);
|
||||
}
|
||||
})
|
||||
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
}
|
||||
})
|
||||
.show();
|
||||
} else {
|
||||
FileDownloadHelper.downloadFiles(context, hostInfo,
|
||||
songInfoList, FileDownloadHelper.DOWNLOAD_WITH_NEW_NAME,
|
||||
callbackHandler);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -273,9 +273,11 @@
|
|||
<string name="confirm_episode_download">Are you sure you want to download this episode?\nThe episode will be downloaded in the background, but it can take a while to finish.</string>
|
||||
<string name="confirm_album_download">Are you sure you want to download this album?\nThe album will be downloaded in the background, but it can take a while to finish.</string>
|
||||
<string name="confirm_artist_download">Are you sure you want to download all albums?\nThe albums will be downloaded in the background, but it can take a while to finish.</string>
|
||||
<string name="confirm_songs_download">Are you sure you want to download %1$d songs?\nThe songs will be downloaded in the background, but it can take a while to finish.</string>
|
||||
|
||||
<string name="download_file_exists">File already exists.\nDo you want to overwrite it or download with a new name?</string>
|
||||
<string name="download_dir_exists">Download directory already exists.\nIf any files have the same name, do you want to overwrite them or download them with a new name?</string>
|
||||
<string name="download_files_exists">One or more files already exist.\nIf any files have the same name, do you want to overwrite them or download them with a new name?</string>
|
||||
<string name="overwrite">Overwrite</string>
|
||||
<string name="download_with_new_name">New name</string>
|
||||
<string name="download_file_description">Downloaded from your media center</string>
|
||||
|
|
Loading…
Reference in New Issue