Add artist data source

Add export method in th PlayMusicManager
Add Mp3agic as ID3 lib
Fixed a lot of warnings
This commit is contained in:
David Schulte 2015-01-25 16:53:00 +01:00
parent be1be7398c
commit 0aeba42d12
24 changed files with 921 additions and 172 deletions

View file

@ -0,0 +1,9 @@
<component name="libraryTable">
<library name="mp3agic-0.8.4-SNAPSHOT">
<CLASSES>
<root url="jar://$PROJECT_DIR$/playmusiclib/libs/mp3agic-0.8.4-SNAPSHOT.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View file

@ -24,6 +24,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="de.arcus.playmusicexporter2" >
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"

View file

@ -24,6 +24,7 @@ package de.arcus.playmusicexporter2;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
@ -32,18 +33,10 @@ import java.util.List;
import de.arcus.framework.logger.Logger;
import de.arcus.framework.crashhandler.CrashHandler;
import de.arcus.framework.superuser.SuperUser;
import de.arcus.framework.utils.FileTools;
import de.arcus.playmusiclib.PlayMusicManager;
import de.arcus.playmusiclib.datasources.AlbumDataSource;
import de.arcus.playmusiclib.datasources.MusicTrackDataSource;
import de.arcus.playmusiclib.datasources.PlaylistDataSource;
import de.arcus.playmusiclib.exceptions.CouldNotOpenDatabase;
import de.arcus.playmusiclib.exceptions.NoSuperUserException;
import de.arcus.playmusiclib.exceptions.PlayMusicNotFound;
import de.arcus.playmusiclib.items.Album;
import de.arcus.playmusiclib.items.MusicTrack;
import de.arcus.playmusiclib.items.Playlist;
/**
* An activity representing a list of Tracks. This activity
@ -109,14 +102,11 @@ public class TrackListActivity extends ActionBarActivity
playMusicManager.setOfflineOnly(true);
AlbumDataSource albumDataSource = new AlbumDataSource(playMusicManager);
PlaylistDataSource playlistDataSource = new PlaylistDataSource(playMusicManager);
albumDataSource.setSerchKey("Ed Sheeran");
playlistDataSource.setSerchKey("Playlist 1");
// Load all albums
List<Album> albums = albumDataSource.getAll();
List<Playlist> playlists = playlistDataSource.getAll();
if (albums.size() > 0) {
// Gets the first album
@ -129,27 +119,16 @@ public class TrackListActivity extends ActionBarActivity
// Gets the first track
MusicTrack track = tracks.get(0);
String fileMusic = track.getSourceFile();
String artwork = track.getArtworkPath();
// Test: exports the track to the sd card
String filename = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC) + "/test.mp3";
boolean success = playMusicManager.exportMusicTrack(track, filename);
Log.d("Debug", "Breakpoint");
Log.d("Debug", "Success: " + success);
}
}
if (playlists.size() > 0) {
Playlist playlist = playlists.get(0);
List<MusicTrack> musicTracks = playlist.getMusicTrackList();
Log.d("Debug", "Breakpoint");
}
} catch (PlayMusicNotFound playMusicNotFound) {
playMusicNotFound.printStackTrace();
} catch (NoSuperUserException e) {
e.printStackTrace();
} catch (CouldNotOpenDatabase couldNotOpenDatabase) {
couldNotOpenDatabase.printStackTrace();
} catch (Exception e) {
Logger.getInstance().logError("Test", e.toString());
}

View file

@ -94,7 +94,7 @@ public class TrackListFragment extends ListFragment {
super.onCreate(savedInstanceState);
// TODO: replace with a real list adapter.
setListAdapter(new ArrayAdapter<DummyContent.DummyItem>(
setListAdapter(new ArrayAdapter<>(
getActivity(),
android.R.layout.simple_list_item_activated_1,
android.R.id.text1,

View file

@ -38,12 +38,12 @@ public class DummyContent {
/**
* An array of sample (dummy) items.
*/
public static List<DummyItem> ITEMS = new ArrayList<DummyItem>();
public static List<DummyItem> ITEMS = new ArrayList<>();
/**
* A map of sample (dummy) items, by ID.
*/
public static Map<String, DummyItem> ITEM_MAP = new HashMap<String, DummyItem>();
public static Map<String, DummyItem> ITEM_MAP = new HashMap<>();
static {
// Add 3 sample items.

View file

@ -71,27 +71,27 @@ public class CrashHandler implements Thread.UncaughtExceptionHandler {
// Information
logBuilder.append("---------- Information -----------\n");
logBuilder.append("PackageName: " + mActivity.getPackageName() + "\n");
logBuilder.append("Crashed activity: " + mActivity.getLocalClassName() + "\n");
logBuilder.append("PackageName: ").append(mActivity.getPackageName()).append("\n");
logBuilder.append("Crashed activity: ").append(mActivity.getLocalClassName()).append("\n");
logBuilder.append("----------- Exception ------------\n");
logBuilder.append(ex.getMessage() + "\n");
logBuilder.append(ex.getMessage()).append("\n");
// Log stack trace
for (StackTraceElement stackTraceElement : ex.getStackTrace())
{
logBuilder.append("\t" + stackTraceElement.toString() + "\n");
logBuilder.append("\t").append(stackTraceElement.toString()).append("\n");
}
// Log Caused by
if (ex.getCause() != null) {
logBuilder.append("----------- Caused by ------------\n");
logBuilder.append(ex.getCause().getMessage() + "\n");
logBuilder.append(ex.getCause().getMessage()).append("\n");
// Log stack trace
for (StackTraceElement stackTraceElement : ex.getCause().getStackTrace())
{
logBuilder.append("\t" + stackTraceElement.toString() + "\n");
logBuilder.append("\t").append(stackTraceElement.toString()).append("\n");
}
}

View file

@ -34,7 +34,7 @@ public class Logger {
/**
* Type of the log entry
*/
public enum LogEntryType { Verbose, Debug, Info, Warning, Error };
public enum LogEntryType { Verbose, Debug, Info, Warning, Error }
/**
* Instance of the logger

View file

@ -22,9 +22,12 @@
package de.arcus.framework.superuser;
import org.apache.http.util.ByteArrayBuffer;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
@ -44,8 +47,64 @@ public class SuperUserCommand {
private String[] mOutputStandard = new String[] {};
private String[] mOutputError = new String[] {};
// If we want to get a binary return
private byte[] mOutputStandardBinary = new byte[] {};
/**
* Command failed?
*/
private boolean mSuperUserFailed;
/**
* If this value is set, the command will not store any standard output to the logger
*/
private boolean mHideStandardOutput = false;
/**
* If this value is set, the command will not store any error output to the logger
*/
private boolean mHideErrorOutput = false;
/**
* @return Gets whether the command hides the standard output log
*/
public boolean getHideStandardOutput() {
return mHideStandardOutput;
}
/**
* @param hideStandardOutput Set this to hide the standard output to the logger
*/
public void setHideStandardOutput(boolean hideStandardOutput) {
mHideStandardOutput = hideStandardOutput;
}
/**
* @return Gets whether the command hides the error output log
*/
public boolean getHideErrorOutput() {
return mHideErrorOutput;
}
/**
* @param hideErrorOutput Set this to hide the error output to the logger
*/
public void setHideErrorOutput(boolean hideErrorOutput) {
mHideErrorOutput = hideErrorOutput;
}
/**
* If this value is set the command will read the standard output as binary
*/
private boolean mBinaryStandardOutput = false;
public boolean getBinaryStandardOutput() {
return mBinaryStandardOutput;
}
public void setBinaryStandardOutput(boolean binaryStandardOutput) {
mBinaryStandardOutput = binaryStandardOutput;
}
/**
* The timeout for this command in milliseconds
*/
@ -76,19 +135,26 @@ public class SuperUserCommand {
}
/**
* @return Get the standard output
* @return Gets the standard output
*/
public String[] getStandardOutput() {
return mOutputStandard;
}
/**
* @return Get the error output
* @return Gets the error output
*/
public String[] getErrorOutput() {
return mOutputError;
}
/**
* @return Gets the standard output as binary
*/
public byte[] getStandardOutputBinary() {
return mOutputStandardBinary;
}
/**
* @return Gets whether the command was executed without errors, even without error outputs from the command.
*/
@ -174,20 +240,43 @@ public class SuperUserCommand {
if (timeNow - timeStarted >= mTimeout) break;
}
// Reads the standard output
tmpList.clear();
while (bufferedInputReader.ready()) {
tmpLine = bufferedInputReader.readLine();
// We want to read the data as binary
if (mBinaryStandardOutput) {
int len;
byte[] buffer = new byte[1024];
// End of data
if (tmpLine == null) break;
// Byte buffer
ByteArrayBuffer byteArrayBuffer = new ByteArrayBuffer(1024);
Logger.getInstance().logInfo("SuperUser", "> " + tmpLine);
tmpList.add(tmpLine);
// Need the direct input stream
InputStream inputStream = SuperUser.getProcess().getInputStream();
while (bufferedInputReader.ready()) {
// Read to buffer
len = inputStream.read(buffer);
// Write to buffer
byteArrayBuffer.append(buffer, 0, len);
}
mOutputStandardBinary = byteArrayBuffer.toByteArray();
} else {
// Reads the standard output as text
tmpList.clear();
while (bufferedInputReader.ready()) {
tmpLine = bufferedInputReader.readLine();
// End of data
if (tmpLine == null) break;
if (!mHideStandardOutput)
Logger.getInstance().logInfo("SuperUser", "> " + tmpLine);
tmpList.add(tmpLine);
}
// Convert list to array
mOutputStandard = tmpList.toArray(new String[tmpList.size()]);
}
// Convert list to array
mOutputStandard = tmpList.toArray(new String[tmpList.size()]);
// Reads the error output
tmpList.clear();
@ -196,7 +285,9 @@ public class SuperUserCommand {
// End of data
if (tmpLine == null) break;
Logger.getInstance().logError("SuperUser", "> " + tmpLine);
if (!mHideErrorOutput)
Logger.getInstance().logError("SuperUser", "> " + tmpLine);
tmpList.add(tmpLine);
}

View file

@ -51,8 +51,13 @@ public class SuperUserTools {
return superUserCommand.commandWasSuccessful();
}
public static boolean fileExists(String filename) {
SuperUserCommand superUserCommand = new SuperUserCommand("ls '" + filename + "'");
/**
* Checks if the file exists
* @param path The path to check
* @return Returns whether the path exists
*/
public static boolean fileExists(String path) {
SuperUserCommand superUserCommand = new SuperUserCommand("ls '" + path + "'");
// Executes the command
superUserCommand.execute();
@ -60,4 +65,27 @@ public class SuperUserTools {
// Superuser permissions and command are successful
return superUserCommand.commandWasSuccessful();
}
/**
* Gets all bytes from one file
* @param path The path to the file
* @return Returns the byte array or null if the file doesn't exists
*/
public static byte[] fileReadToByteArray(String path) {
SuperUserCommand superUserCommand = new SuperUserCommand("cat '" + path + "'");
// Don't spam the log with binary code
superUserCommand.setHideStandardOutput(true);
superUserCommand.setBinaryStandardOutput(true);
// Executes the command
superUserCommand.execute();
// Failed
if (!superUserCommand.commandWasSuccessful())
return null;
return superUserCommand.getStandardOutputBinary();
}
}

View file

@ -23,7 +23,11 @@
package de.arcus.framework.utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
@ -114,6 +118,59 @@ public class FileTools {
return fileSrc.renameTo(fileDest);
}
/**
* Copies a file
* @param src Soruce path
* @param dest Destination path
* @return Return whether the file was copied successful
*/
public static boolean fileCopy(String src, String dest) {
Logger.getInstance().logVerbose("FileCopy", "From " + src + " to " + dest);
// The buffer size
final int BUFFER_SIZE = 1024;
// Will be set on true if the file was copied correctly
boolean success = false;
InputStream inputStream = null;
OutputStream outputStream = null;
try {
// Open the file streams
inputStream = new FileInputStream(src);
outputStream = new FileOutputStream(dest);
// The copy buffer
byte[] buffer = new byte[BUFFER_SIZE];
int length;
// Copy block by block
while ((length = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
// Copy was successful
success = true;
} catch (IOException ex) {
// Failed
Logger.getInstance().logError("FileCopy", "Failed: " + ex.toString());
}
try {
// Close all streams
if (inputStream != null)
inputStream.close();
if (outputStream != null)
outputStream.close();
} catch (IOException ex) {
// Failed
Logger.getInstance().logError("FileCopy", "Failed: " + ex.toString());
}
return success;
}
/**
* Deletes a file
* @param file Path of the file
@ -146,7 +203,7 @@ public class FileTools {
try {
// Checks whether the file / directory is a symbolic link
return (file.getAbsolutePath() == file.getCanonicalPath());
return (file.getAbsolutePath().equals(file.getCanonicalPath()));
} catch (IOException e) {
e.printStackTrace();
}

Binary file not shown.

View file

@ -84,6 +84,7 @@
</content>
<orderEntry type="jdk" jdkName="Android API 21 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" exported="" name="mp3agic-0.8.4-SNAPSHOT" level="project" />
<orderEntry type="library" exported="" name="support-annotations-21.0.3" level="project" />
<orderEntry type="module" module-name="framework" exported="" />
</component>

View file

@ -38,8 +38,6 @@ import javax.crypto.spec.SecretKeySpec;
* Exports encrypted music files from Google Music All Access
*/
public class AllAccessExporter {
private String mFileName;
private byte[] mCpData;
private Cipher mCipher;
private SecretKeySpec mKeySpec;
private InputStream mInput;
@ -60,15 +58,12 @@ public class AllAccessExporter {
*/
public AllAccessExporter(String input, byte[] cpData) throws NoSuchAlgorithmException, NoSuchPaddingException, IOException
{
mFileName = input;
mCpData = cpData;
// Select encryption mode
mCipher = Cipher.getInstance("AES/CTR/NoPadding");
mKeySpec = new SecretKeySpec(mCpData, "AES");
mKeySpec = new SecretKeySpec(cpData, "AES");
// Opens the source file
mInput = new FileInputStream(mFileName);
mInput = new FileInputStream(input);
// Reads the first 4 bytes = MagicNumber
mMagicNumber = new byte[4];

View file

@ -29,9 +29,18 @@ import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.text.TextUtils;
import com.mpatric.mp3agic.ID3v1Genres;
import com.mpatric.mp3agic.ID3v1Tag;
import com.mpatric.mp3agic.ID3v2;
import com.mpatric.mp3agic.ID3v22Tag;
import com.mpatric.mp3agic.ID3v23Tag;
import com.mpatric.mp3agic.ID3v24Tag;
import com.mpatric.mp3agic.Mp3File;
import java.util.ArrayList;
import java.util.List;
import de.arcus.framework.logger.Logger;
import de.arcus.framework.superuser.SuperUser;
import de.arcus.framework.superuser.SuperUserTools;
import de.arcus.framework.utils.FileTools;
@ -40,6 +49,7 @@ import de.arcus.playmusiclib.exceptions.NoSuperUserException;
import de.arcus.playmusiclib.exceptions.PlayMusicNotFound;
import de.arcus.playmusiclib.items.MusicTrack;
/**
* Connects to the PlayMusic data
*/
@ -131,6 +141,88 @@ public class PlayMusicManager {
mOfflineOnly = offlineOnly;
}
/**
* If this is set the exporter will add ID3 tag to the mp3 files
*/
private boolean mID3Enable = true;
/**
* @return Gets whether the exporter adds ID3 tags to the mp3 files
*/
public boolean getID3Enable() {
return mID3Enable;
}
/**
* @param id3Enable Sets whether the exporter adds ID3 tags to the mp3 files
*/
public void setID3Enable(boolean id3Enable) {
mID3Enable = id3Enable;
}
/**
* If this is set the exporter will add the artwork to the ID2v2 tag
*/
private boolean mID3ExportArtwork = true;
/**
* @return Gets whether the exporter adds the artwork image
*/
public boolean getID3ExportArtwork() {
return mID3ExportArtwork;
}
/**
* @param id3ExportArtwork Sets whether the exporter adds the artwork image
*/
public void setID3ExportArtwork(boolean id3ExportArtwork) {
mID3ExportArtwork = id3ExportArtwork;
}
/**
* If this is set the exporter will also adds ID3v1 tags
*/
private boolean mID3ExportFallback = true;
/**
* @return Gets whether the exporter adds ID3v1 tags as fallback
*/
public boolean getID3ExportFallback() {
return mID3ExportFallback;
}
/**
* @param id3ExportFallback Sets whether the exporter adds ID3v1 tags as fallback
*/
public void setmID3ExportFallback(boolean id3ExportFallback) {
mID3ExportFallback = id3ExportFallback;
}
/**
* The ID3v2 sub version
*/
public enum ID3v2Version { ID3v22, ID3v23, ID3v24 }
/**
* The sub version of ID3v2
* Use 2.3 for default to fix issues with the Windows Windows Media Player
*/
private ID3v2Version mID3v2Version = ID3v2Version.ID3v23;
/**
* @return Gets the sub version of ID3v2
*/
public ID3v2Version getID3v2Version() {
return mID3v2Version;
}
/**
* @param id3v2Version Sets the sub version of ID3v2
*/
public void setID3v2Version(ID3v2Version id3v2Version) {
mID3v2Version = id3v2Version;
}
/**
* Creates a new PlayMusic manager
* @param context App context
@ -204,7 +296,7 @@ public class PlayMusicManager {
}
/**
* Reloads the database from playmusic
* Reloads the database from PlayMusic
* @throws NoSuperUserException No super user permissions
* @throws CouldNotOpenDatabase Could not open the database
*/
@ -304,10 +396,189 @@ public class PlayMusicManager {
if (!SuperUserTools.fileCopy(srcFile, fileTmp))
return false;
// TODO
// Encrypt the file
if (musicTrack.isEncoded()) {
String fileTmpCrypt = getTempPath() + "/crypt.mp3";
// Encrypts the file
if (trackEncrypt(musicTrack, fileTmp, fileTmpCrypt)) {
// Remove the old tmp file
FileTools.fileDelete(fileTmp);
// New tmp file
fileTmp = fileTmpCrypt;
} else {
Logger.getInstance().logWarning("ExportMusicTrack", "Encrypting failed! Continue with decrypted file.");
}
}
// We want to export the ID3 tags
if (mID3Enable) {
// Adds the meta data
if (!trackWriteID3(musicTrack, fileTmp, dest)) {
Logger.getInstance().logWarning("ExportMusicTrack", "ID3 writer failed! Continue without ID3 tags.");
// Failed, moving without meta data
if (!FileTools.fileMove(fileTmp, dest)) {
Logger.getInstance().logError("ExportMusicTrack", "Moving the raw file failed!");
// Could not copy the file
return false;
}
}
} else {
// Moving the file
if (!FileTools.fileMove(fileTmp, dest)) {
Logger.getInstance().logError("ExportMusicTrack", "Moving the raw file failed!");
// Could not copy the file
return false;
}
}
// Done
return true;
}
/**
* Copies the music file to a new path and adds the mp3 meta data
* @param musicTrack Track information
* @param src The source mp3 file
* @param dest The destination path
* return Return if the operation was successful
*/
private boolean trackWriteID3(MusicTrack musicTrack, String src, String dest) {
try {
// Opens the mp3
Mp3File mp3File = new Mp3File(src);
// Removes all existing tags
mp3File.removeId3v1Tag();
mp3File.removeId3v2Tag();
mp3File.removeCustomTag();
// We want to add a fallback ID3v1 tag
if (mID3ExportFallback) {
// Create a new tag with ID3v1
ID3v1Tag tagID3v1 = new ID3v1Tag();
// Set all tag values
tagID3v1.setTrack(musicTrack.getTitle());
tagID3v1.setArtist(musicTrack.getArtist());
tagID3v1.setAlbum(musicTrack.getAlbum());
tagID3v1.setYear(musicTrack.getYear());
// Search the genre
for(int n=0; n<ID3v1Genres.GENRES.length; n++) {
// Genre found
if (ID3v1Genres.GENRES[n].equals(musicTrack.getGenre())) {
tagID3v1.setGenre(n);
break;
}
}
mp3File.setId3v1Tag(tagID3v1);
}
// It can't be null
ID3v2 tagID3v2 = null;
// Creates the requested version
switch(mID3v2Version) {
case ID3v22:
tagID3v2 = new ID3v22Tag();
break;
case ID3v23:
tagID3v2 = new ID3v23Tag();
break;
case ID3v24:
tagID3v2 = new ID3v24Tag();
break;
}
// Set all tag values
tagID3v2.setTitle(musicTrack.getTitle());
tagID3v2.setArtist(musicTrack.getArtist());
tagID3v2.setAlbum(musicTrack.getTitle());
tagID3v2.setAlbumArtist(musicTrack.getAlbumArtist());
tagID3v2.setTrack("" + musicTrack.getTrackNumber());
tagID3v2.setPartOfSet("" + musicTrack.getDiscNumber());
tagID3v2.setYear(musicTrack.getYear());
try {
// Maybe the genre is not supported
tagID3v2.setGenreDescription(musicTrack.getGenre());
} catch (IllegalArgumentException e) {
Logger.getInstance().logWarning("TrackWriteID3", e.getMessage());
}
// Add the artwork to the meta data
if (mID3ExportArtwork) {
// Reads the artwork with root permissions (maybe it is in /data)
byte[] artwork = SuperUserTools.fileReadToByteArray(musicTrack.getArtworkPath());
if (artwork != null) {
// The file extension is always .jpg even if the image is a PNG file,
// so we need to check the magic number
// JPEG is default
String mimeType = "image/jpeg";
// Check for other image formats
if (artwork.length > 4) {
// PNG-Header
if (artwork[0] == -119 && artwork[1] == 80 && artwork[2] == 78 && artwork[3] == 71) {
mimeType = "image/png";
}
}
// Adds the artwork to the meta data
tagID3v2.setAlbumImage(artwork, mimeType);
}
}
mp3File.setId3v2Tag(tagID3v2);
// Save the file
mp3File.save(dest);
// Done
return true;
} catch (Exception e) {
Logger.getInstance().logError("TrackWriteId3", e.toString());
}
// Failed
return false;
}
/**
* Encrypts a track and save it to a new path
* @param musicTrack The music track
* @param src The source mp3 file
* @param dest The destination path
* @return Return if the operation was successful
*/
private boolean trackEncrypt(MusicTrack musicTrack, String src, String dest) {
try {
AllAccessExporter allAccessExporter = new AllAccessExporter(src, musicTrack.getCpData());
// Checks the magic number
if (!allAccessExporter.hasValidMagicNumber()) {
Logger.getInstance().logError("TrackEncrypt", "Invalid magic number! This is not an AllAccess file");
return false;
}
// Saves the file
return allAccessExporter.save(dest);
} catch (Exception e) {
Logger.getInstance().logError("TrackEncrypt", e.toString());
}
// Failed
return false;
}
}

View file

@ -39,17 +39,17 @@ public class AlbumDataSource extends DataSource<Album> {
private final static String TABLE_MUSIC = "MUSIC";
// All fields
private final static String COLUMN_ALBUMID = "MUSIC.AlbumId";
private final static String COLUMN_ALBUM_ID = "MUSIC.AlbumId";
private final static String COLUMN_ALBUM = "MUSIC.Album";
private final static String COLUMN_ALBUMARTIST = "MUSIC.AlbumArtist";
private final static String COLUMN_ALBUM_ARTWORKFILE = "(SELECT ARTWORK_CACHE.LocalLocation FROM MUSIC AS MUSIC2 LEFT JOIN ARTWORK_CACHE ON MUSIC2.AlbumArtLocation = ARTWORK_CACHE.RemoteLocation WHERE MUSIC2.AlbumID = MUSIC.AlbumID AND ARTWORK_CACHE.RemoteLocation IS NOT NULL LIMIT 1) AS ArtistArtworkPath";
private final static String COLUMN_ALBUM_ARTIST = "MUSIC.AlbumArtist";
private final static String COLUMN_ALBUM_ARTWORK_FILE = "(SELECT ARTWORK_CACHE.LocalLocation FROM MUSIC AS MUSIC2 LEFT JOIN ARTWORK_CACHE ON MUSIC2.AlbumArtLocation = ARTWORK_CACHE.RemoteLocation WHERE MUSIC2.AlbumID = MUSIC.AlbumID AND ARTWORK_CACHE.RemoteLocation IS NOT NULL LIMIT 1) AS ArtistArtworkPath";
private final static String COLUMN_TITLE = "MUSIC.Title";
private final static String COLUMN_ARTIST = "MUSIC.Artist";
// All columns
private final static String[] COLUMNS_ALL = { COLUMN_ALBUMID, COLUMN_ALBUM,
COLUMN_ALBUMARTIST, COLUMN_ALBUM_ARTWORKFILE};
private final static String[] COLUMNS_ALL = {COLUMN_ALBUM_ID, COLUMN_ALBUM,
COLUMN_ALBUM_ARTIST, COLUMN_ALBUM_ARTWORK_FILE};
/**
* If this is set the data source will only load offline tracks
@ -119,7 +119,7 @@ public class AlbumDataSource extends DataSource<Album> {
String searchWhere = COLUMN_ALBUM + " LIKE " + searchKey;
searchWhere += " OR " + COLUMN_TITLE + " LIKE " + searchKey;
searchWhere += " OR " + COLUMN_ALBUMARTIST + " LIKE " + searchKey;
searchWhere += " OR " + COLUMN_ALBUM_ARTIST + " LIKE " + searchKey;
searchWhere += " OR " + COLUMN_ARTIST + " LIKE " + searchKey;
where = combineWhere(where, searchWhere);
@ -138,10 +138,10 @@ public class AlbumDataSource extends DataSource<Album> {
Album instance = new Album(mPlayMusicManager);
// Read all properties from the data row
instance.setAlbumId(cursor.getLong(getColumnsIndex(COLUMNS_ALL, COLUMN_ALBUMID)));
instance.setAlbumId(cursor.getLong(getColumnsIndex(COLUMNS_ALL, COLUMN_ALBUM_ID)));
instance.setAlbum(cursor.getString(getColumnsIndex(COLUMNS_ALL, COLUMN_ALBUM)));
instance.setAlbumArtist(cursor.getString(getColumnsIndex(COLUMNS_ALL, COLUMN_ALBUMARTIST)));
instance.setArtworkFile(cursor.getString(getColumnsIndex(COLUMNS_ALL, COLUMN_ALBUM_ARTWORKFILE)));
instance.setAlbumArtist(cursor.getString(getColumnsIndex(COLUMNS_ALL, COLUMN_ALBUM_ARTIST)));
instance.setArtworkFile(cursor.getString(getColumnsIndex(COLUMNS_ALL, COLUMN_ALBUM_ARTWORK_FILE)));
return instance;
}
@ -152,7 +152,7 @@ public class AlbumDataSource extends DataSource<Album> {
* @return Returns the album or null
*/
public Album getById(long id) {
return getItem(TABLE_MUSIC, COLUMNS_ALL, prepareWhere(COLUMN_ALBUMID + " = " + id));
return getItem(TABLE_MUSIC, COLUMNS_ALL, prepareWhere(COLUMN_ALBUM_ID + " = " + id));
}
/**

View file

@ -0,0 +1,148 @@
/*
* Copyright (c) 2015 David Schulte
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package de.arcus.playmusiclib.datasources;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.text.TextUtils;
import java.util.List;
import de.arcus.playmusiclib.PlayMusicManager;
import de.arcus.playmusiclib.items.Artist;
/**
* Data source for artists
*/
public class ArtistDataSource extends DataSource<Artist> {
// Tables
private final static String TABLE_MUSIC = "MUSIC";
// All fields
private final static String COLUMN_ARTIST_ID = "ArtistId";
private final static String COLUMN_ARTIST = "Artist";
private final static String COLUMN_ARTWORK_FILE = "(SELECT ARTWORK_CACHE.LocalLocation FROM MUSIC AS MUSIC2 LEFT JOIN ARTWORK_CACHE ON ARTWORK_CACHE.RemoteLocation = MUSIC.AlbumArtLocation WHERE MUSIC2.ArtistId = MUSIC.ArtistId AND ARTWORK_CACHE.LocalLocation IS NOT NULL LIMIT 1) AS ArtworkFile";
// All columns
private final static String[] COLUMNS_ALL = { COLUMN_ARTIST_ID, COLUMN_ARTIST, COLUMN_ARTWORK_FILE };
/**
* If this is set the data source will only load offline tracks
*/
private boolean mOfflineOnly; // TODO: Offline only has no effects on the artists data sources
/**
* If the search key is set, this data source will only load items which contains this text
*/
private String mSearchKey;
/**
* @return Returns whether the data source should only load offline tracks
*/
public boolean getOfflineOnly() {
return mOfflineOnly;
}
/**
* @param offlineOnly Sets whether the data source should only load offline tracks
*/
public void setOfflineOnly(boolean offlineOnly) {
mOfflineOnly = offlineOnly;
}
/**
* @return Gets the search key
*/
public String getSearchKey() {
return mSearchKey;
}
/**
* @param searchKey Sets the search key
*/
public void setSerchKey(String searchKey) {
mSearchKey = searchKey;
}
/**
* Creates a new data source
* @param playMusicManager The manager
*/
public ArtistDataSource(PlayMusicManager playMusicManager) {
super(playMusicManager);
// Load global settings
setOfflineOnly(playMusicManager.getOfflineOnly());
}
/**
* Prepare the where command and adds the global settings
* @param where The where command
* @return The new where command
*/
private String prepareWhere(String where) {
// Search only items which contains the key
if (!TextUtils.isEmpty(mSearchKey)) {
String searchKey = DatabaseUtils.sqlEscapeString("%" + mSearchKey + "%");
where = combineWhere(where, "(" + COLUMN_ARTIST + " LIKE " + searchKey + ")");
}
return where;
}
@Override
/**
* Gets the data object from a data row
* @param cursor Data row
* @return Data object
*/
protected Artist getDataObject(Cursor cursor) {
Artist instance = new Artist(mPlayMusicManager);
// Read all properties from the data row
instance.setArtistId(cursor.getLong(getColumnsIndex(COLUMNS_ALL, COLUMN_ARTIST_ID)));
instance.setArtist(cursor.getString(getColumnsIndex(COLUMNS_ALL, COLUMN_ARTIST)));
instance.setArtworkFile(cursor.getString(getColumnsIndex(COLUMNS_ALL, COLUMN_ARTWORK_FILE)));
return instance;
}
/**
* Loads a artist by Id
* @param id The artist id
* @return Returns the artist or null
*/
public Artist getById(long id) {
return getItem(TABLE_MUSIC, COLUMNS_ALL, prepareWhere(COLUMN_ARTIST_ID + " = " + id));
}
/**
* Gets a list of all artists
* @return Returns all artists
*/
public List<Artist> getAll() {
return getItems(TABLE_MUSIC, COLUMNS_ALL, prepareWhere(""), COLUMN_ARTIST);
}
}

View file

@ -23,7 +23,6 @@
package de.arcus.playmusiclib.datasources;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.text.TextUtils;
import java.util.LinkedList;

View file

@ -30,6 +30,7 @@ import java.util.List;
import de.arcus.playmusiclib.PlayMusicManager;
import de.arcus.playmusiclib.items.Album;
import de.arcus.playmusiclib.items.Artist;
import de.arcus.playmusiclib.items.MusicTrack;
import de.arcus.playmusiclib.items.Playlist;
@ -48,25 +49,26 @@ public class MusicTrackDataSource extends DataSource<MusicTrack> {
private final static String COLUMN_LOCALCOPYTYPE = "MUSIC.LocalCopyType";
private final static String COLUMN_LOCALCOPYSTORAGETYPE = "MUSIC.LocalCopyStorageType";
private final static String COLUMN_TITLE = "MUSIC.Title";
private final static String COLUMN_ARTIST_ID = "MUSIC.ArtistID";
private final static String COLUMN_ARTIST = "MUSIC.Artist";
private final static String COLUMN_ALBUMARTIST = "MUSIC.AlbumArtist";
private final static String COLUMN_ALBUM_ARTIST = "MUSIC.AlbumArtist";
private final static String COLUMN_ALBUM = "MUSIC.Album";
private final static String COLUMN_GENRE = "MUSIC.Genre";
private final static String COLUMN_YEAR = "MUSIC.Year";
private final static String COLUMN_TRACKNUMBER = "MUSIC.TrackNumber";
private final static String COLUMN_DISCNUMBER = "MUSIC.DiscNumber";
private final static String COLUMN_TRACK_NUMBER = "MUSIC.TrackNumber";
private final static String COLUMN_DISC_NUMBER = "MUSIC.DiscNumber";
private final static String COLUMN_DURATION = "MUSIC.Duration";
private final static String COLUMN_ALBUMID = "MUSIC.AlbumId";
private final static String COLUMN_CLIENTID = "MUSIC.ClientId";
private final static String COLUMN_SOURCEID = "MUSIC.SourceId";
private final static String COLUMN_ALBUM_ID = "MUSIC.AlbumId";
private final static String COLUMN_CLIENT_ID = "MUSIC.ClientId";
private final static String COLUMN_SOURCE_ID = "MUSIC.SourceId";
private final static String COLUMN_CPDATA = "MUSIC.CpData";
private final static String COLUMN_ARTWORKFILE = "(SELECT LocalLocation FROM artwork_cache WHERE artwork_cache.RemoteLocation = AlbumArtLocation) AS ArtworkFile";
private final static String COLUMN_ARTWORK_FILE = "(SELECT LocalLocation FROM artwork_cache WHERE artwork_cache.RemoteLocation = AlbumArtLocation) AS ArtworkFile";
// All columns
private final static String[] COLUMNS_ALL = { COLUMN_ID, COLUMN_SIZE,
COLUMN_LOCALCOPYPATH, COLUMN_LOCALCOPYTYPE, COLUMN_LOCALCOPYSTORAGETYPE, COLUMN_TITLE, COLUMN_ARTIST, COLUMN_ALBUMARTIST,
COLUMN_ALBUM, COLUMN_GENRE, COLUMN_YEAR, COLUMN_TRACKNUMBER, COLUMN_DISCNUMBER, COLUMN_DURATION,
COLUMN_ALBUMID, COLUMN_CLIENTID, COLUMN_SOURCEID, COLUMN_ARTWORKFILE, COLUMN_CPDATA };
COLUMN_LOCALCOPYPATH, COLUMN_LOCALCOPYTYPE, COLUMN_LOCALCOPYSTORAGETYPE, COLUMN_TITLE, COLUMN_ARTIST_ID, COLUMN_ARTIST, COLUMN_ALBUM_ARTIST,
COLUMN_ALBUM, COLUMN_GENRE, COLUMN_YEAR, COLUMN_TRACK_NUMBER, COLUMN_DISC_NUMBER, COLUMN_DURATION,
COLUMN_ALBUM_ID, COLUMN_CLIENT_ID, COLUMN_SOURCE_ID, COLUMN_ARTWORK_FILE, COLUMN_CPDATA };
/**
* If this is set the data source will only load offline tracks
@ -106,6 +108,16 @@ public class MusicTrackDataSource extends DataSource<MusicTrack> {
mSearchKey = searchKey;
}
/**
* The name of the container (eg. a playlist or an artist)
*/
private String mContainerName;
/**
* The position of the track in the container
*/
private long mContainerPosition;
/**
* Creates a new data source
* @param playMusicManager The manager
@ -136,7 +148,7 @@ public class MusicTrackDataSource extends DataSource<MusicTrack> {
String searchWhere = COLUMN_ALBUM + " LIKE " + searchKey;
searchWhere += " OR " + COLUMN_TITLE + " LIKE " + searchKey;
searchWhere += " OR " + COLUMN_ALBUMARTIST + " LIKE " + searchKey;
searchWhere += " OR " + COLUMN_ALBUM_ARTIST + " LIKE " + searchKey;
searchWhere += " OR " + COLUMN_ARTIST + " LIKE " + searchKey;
where = combineWhere(where, searchWhere);
@ -162,19 +174,25 @@ public class MusicTrackDataSource extends DataSource<MusicTrack> {
instance.setLocalCopyType(cursor.getLong(getColumnsIndex(COLUMNS_ALL, COLUMN_LOCALCOPYTYPE)));
instance.setLocalCopyStorageType(cursor.getLong(getColumnsIndex(COLUMNS_ALL, COLUMN_LOCALCOPYSTORAGETYPE)));
instance.setTitle(cursor.getString(getColumnsIndex(COLUMNS_ALL, COLUMN_TITLE)));
instance.setArtistId(cursor.getLong(getColumnsIndex(COLUMNS_ALL, COLUMN_ARTIST_ID)));
instance.setArtist(cursor.getString(getColumnsIndex(COLUMNS_ALL, COLUMN_ARTIST)));
instance.setAlbumArtist(cursor.getString(getColumnsIndex(COLUMNS_ALL, COLUMN_ALBUMARTIST)));
instance.setAlbumArtist(cursor.getString(getColumnsIndex(COLUMNS_ALL, COLUMN_ALBUM_ARTIST)));
instance.setAlbum(cursor.getString(getColumnsIndex(COLUMNS_ALL, COLUMN_ALBUM)));
instance.setGenre(cursor.getString(getColumnsIndex(COLUMNS_ALL, COLUMN_GENRE)));
instance.setYear(cursor.getString(getColumnsIndex(COLUMNS_ALL, COLUMN_YEAR)));
instance.setTrackNumber(cursor.getLong(getColumnsIndex(COLUMNS_ALL, COLUMN_TRACKNUMBER)));
instance.setDiscNumber(cursor.getLong(getColumnsIndex(COLUMNS_ALL, COLUMN_DISCNUMBER)));
instance.setTrackNumber(cursor.getLong(getColumnsIndex(COLUMNS_ALL, COLUMN_TRACK_NUMBER)));
instance.setDiscNumber(cursor.getLong(getColumnsIndex(COLUMNS_ALL, COLUMN_DISC_NUMBER)));
instance.setDuration(cursor.getLong(getColumnsIndex(COLUMNS_ALL, COLUMN_DURATION)));
instance.setAlbumId(cursor.getLong(getColumnsIndex(COLUMNS_ALL, COLUMN_ALBUMID)));
instance.setClientId(cursor.getString(getColumnsIndex(COLUMNS_ALL, COLUMN_CLIENTID)));
instance.setSourceId(cursor.getString(getColumnsIndex(COLUMNS_ALL, COLUMN_SOURCEID)));
instance.setAlbumId(cursor.getLong(getColumnsIndex(COLUMNS_ALL, COLUMN_ALBUM_ID)));
instance.setClientId(cursor.getString(getColumnsIndex(COLUMNS_ALL, COLUMN_CLIENT_ID)));
instance.setSourceId(cursor.getString(getColumnsIndex(COLUMNS_ALL, COLUMN_SOURCE_ID)));
instance.setCpData(cursor.getBlob(getColumnsIndex(COLUMNS_ALL, COLUMN_CPDATA)));
instance.setArtworkFile(cursor.getString(getColumnsIndex(COLUMNS_ALL, COLUMN_ARTWORKFILE)));
instance.setArtworkFile(cursor.getString(getColumnsIndex(COLUMNS_ALL, COLUMN_ARTWORK_FILE)));
// Sets the container information
mContainerPosition++;
instance.setContainerName(mContainerName);
instance.setContainerPosition(mContainerPosition);
return instance;
}
@ -185,6 +203,9 @@ public class MusicTrackDataSource extends DataSource<MusicTrack> {
* @return Returns the music track or null
*/
public MusicTrack getById(long id) {
mContainerName = null;
mContainerPosition = 0;
return getItem(TABLE_MUSIC, COLUMNS_ALL, prepareWhere("Id = " + id));
}
@ -194,15 +215,33 @@ public class MusicTrackDataSource extends DataSource<MusicTrack> {
* @return Returns the track list
*/
public List<MusicTrack> getByAlbum(Album album) {
return getItems(TABLE_MUSIC, COLUMNS_ALL, prepareWhere("AlbumId = " + album.getAlbumId()), COLUMN_DISCNUMBER + ", " + COLUMN_TRACKNUMBER);
mContainerName = null;
mContainerPosition = 0;
return getItems(TABLE_MUSIC, COLUMNS_ALL, prepareWhere("AlbumId = " + album.getAlbumId()), COLUMN_DISC_NUMBER + ", " + COLUMN_TRACK_NUMBER);
}
/**
* Gets a list of tracks by an playlist
* Gets a list of tracks by a playlist
* @param playlist The playlist
* @return Returns the track list
*/
public List<MusicTrack> getByPlaylist(Playlist playlist) {
mContainerName = playlist.getTitle();
mContainerPosition = 0;
return getItems(TABLE_MUSIC_PLAYLIST, COLUMNS_ALL, prepareWhere("ListId = " + playlist.getId()), "LISTITEMS.ID");
}
/**
* Gets a list of tracks by an artist
* @param artist The artist
* @return Returns the track list
*/
public List<MusicTrack> getByArtist(Artist artist) {
mContainerName = artist.getTitle();
mContainerPosition = 0;
return getItems(TABLE_MUSIC, COLUMNS_ALL, prepareWhere(COLUMN_ARTIST_ID + " = " + artist.getArtistId()), COLUMN_ARTIST);
}
}

View file

@ -41,13 +41,13 @@ public class PlaylistDataSource extends DataSource<Playlist> {
// All fields
private final static String COLUMN_ID = "LISTS.Id";
private final static String COLUMN_NAME = "LISTS.Name";
private final static String COLUMN_LISTTYPE = "LISTS.ListType";
private final static String COLUMN_OWNERNAME = "LISTS.OwnerName";
private final static String COLUMN_ARTWORKFILE = "(SELECT ARTWORK_CACHE.LocalLocation FROM LISTITEMS LEFT JOIN MUSIC ON MUSIC.Id = LISTITEMS.MusicId LEFT JOIN ARTWORK_CACHE ON ARTWORK_CACHE.RemoteLocation = MUSIC.AlbumArtLocation WHERE LISTITEMS.ListId = LISTS.Id AND ARTWORK_CACHE.LocalLocation IS NOT NULL LIMIT 1) AS ArtworkFile";
private final static String COLUMN_LIST_TYPE = "LISTS.ListType";
private final static String COLUMN_OWNER_NAME = "LISTS.OwnerName";
private final static String COLUMN_ARTWORK_FILE = "(SELECT ARTWORK_CACHE.LocalLocation FROM LISTITEMS LEFT JOIN MUSIC ON MUSIC.Id = LISTITEMS.MusicId LEFT JOIN ARTWORK_CACHE ON ARTWORK_CACHE.RemoteLocation = MUSIC.AlbumArtLocation WHERE LISTITEMS.ListId = LISTS.Id AND ARTWORK_CACHE.LocalLocation IS NOT NULL LIMIT 1) AS ArtworkFile";
// All columns
private final static String[] COLUMNS_ALL = { COLUMN_ID, COLUMN_NAME,
COLUMN_LISTTYPE, COLUMN_OWNERNAME, COLUMN_ARTWORKFILE};
COLUMN_LIST_TYPE, COLUMN_OWNER_NAME, COLUMN_ARTWORK_FILE};
/**
@ -127,9 +127,9 @@ public class PlaylistDataSource extends DataSource<Playlist> {
// Read all properties from the data row
instance.setId(cursor.getLong(getColumnsIndex(COLUMNS_ALL, COLUMN_ID)));
instance.setName(cursor.getString(getColumnsIndex(COLUMNS_ALL, COLUMN_NAME)));
instance.setListType(cursor.getLong(getColumnsIndex(COLUMNS_ALL, COLUMN_LISTTYPE)));
instance.setOwnerName(cursor.getString(getColumnsIndex(COLUMNS_ALL, COLUMN_OWNERNAME)));
instance.setArtworkFile(cursor.getString(getColumnsIndex(COLUMNS_ALL, COLUMN_ARTWORKFILE)));
instance.setListType(cursor.getLong(getColumnsIndex(COLUMNS_ALL, COLUMN_LIST_TYPE)));
instance.setOwnerName(cursor.getString(getColumnsIndex(COLUMNS_ALL, COLUMN_OWNER_NAME)));
instance.setArtworkFile(cursor.getString(getColumnsIndex(COLUMNS_ALL, COLUMN_ARTWORK_FILE)));
return instance;
}
@ -148,6 +148,6 @@ public class PlaylistDataSource extends DataSource<Playlist> {
* @return Returns all playlists
*/
public List<Playlist> getAll() {
return getItems(TABLE_LIST, COLUMNS_ALL, prepareWhere(COLUMN_LISTTYPE + " != " + Playlist.TYPE_QUEUE), COLUMN_NAME);
return getItems(TABLE_LIST, COLUMNS_ALL, prepareWhere(COLUMN_LIST_TYPE + " != " + Playlist.TYPE_QUEUE), COLUMN_NAME);
}
}

View file

@ -28,12 +28,10 @@ import de.arcus.playmusiclib.datasources.MusicTrackDataSource;
/**
* An Album
*/
public class Album extends MusicList {
public class Album extends MusicTrackList {
// Variables
private long mAlbumId;
private String mAlbum, mAlbumArtist, mArtworkFile;
private String mArtworkPath;
private String mAlbum, mAlbumArtist;
/**
* Creates a data item
@ -85,20 +83,6 @@ public class Album extends MusicList {
this.mAlbumArtist = albumArtist;
}
/**
* Gets the artwork file name
*/
public String getArtworkFile() {
return mArtworkFile;
}
/**
* @param artworkFile Sets the artwork file name
*/
public void setArtworkFile(String artworkFile) {
mArtworkFile = artworkFile;
}
@Override
/**
* Gets the album name
@ -127,14 +111,5 @@ public class Album extends MusicList {
mMusicTrackList = musicTrackDataSource.getByAlbum(this);
}
@Override
/**
* return Gets the full path to the artwork
*/
public String getArtworkPath() {
// Search for the artwork path
if (mArtworkPath == null)
mArtworkPath = mPlayMusicManager.getArtworkPath(mArtworkFile);
return mArtworkPath;
}
}

View file

@ -0,0 +1,99 @@
/*
* Copyright (c) 2015 David Schulte
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package de.arcus.playmusiclib.items;
import de.arcus.playmusiclib.PlayMusicManager;
import de.arcus.playmusiclib.datasources.MusicTrackDataSource;
/**
* An artist
*/
public class Artist extends MusicTrackList {
// Variables
private long mArtistId;
private String mArtist;
/**
* Creates a data item
* @param playMusicManager The manager
*/
public Artist(PlayMusicManager playMusicManager) {
super(playMusicManager);
}
/**
* @return Gets the id of the artist
*/
public long getArtistId() {
return mArtistId;
}
/**
* @param artistId Sets the id of the artist
*/
public void setArtistId(long artistId) {
mArtistId = artistId;
}
/**
* @return Gets the name of the artist
*/
public String getArtist() {
return mArtist;
}
/**
* @param artist Sets the name of the artist
*/
public void setArtist(String artist) {
mArtist = artist;
}
@Override
/**
* Gets the artist name
*/
public String getTitle() {
return getArtist();
}
@Override
/**
* Gets the artist name
*/
public String getDescription() {
return ""; // TODO
}
@Override
/**
* Loads all tracks from this artist
*/
protected void fetchTrackList() {
// Music track data source
MusicTrackDataSource musicTrackDataSource = new MusicTrackDataSource(mPlayMusicManager);
// Load the track list
mMusicTrackList = musicTrackDataSource.getByArtist(this);
}
}

View file

@ -29,7 +29,7 @@ import de.arcus.playmusiclib.PlayMusicManager;
*/
public class MusicTrack {
// Variables
private long mId, mSize, mTrackNumber, mDiscNumber, mAlbumId, mLocalCopyType, mLocalCopyStorageType, mDuration;
private long mId, mSize, mTrackNumber, mDiscNumber, mAlbumId, mArtistId, mLocalCopyType, mLocalCopyStorageType, mDuration;
private String mTitle, mArtist, mAlbum, mAlbumArtist, mLocalCopyPath, mGenre, mYear, mClientId, mSourceId, mArtworkFile;
private byte[] mCpData;
@ -60,7 +60,7 @@ public class MusicTrack {
* @param id Sets the track id
*/
public void setId(long id) {
this.mId = mId;
this.mId = id;
}
/**
@ -189,6 +189,20 @@ public class MusicTrack {
this.mTitle = title;
}
/**
* @return Gets the artist is
*/
public long getArtistId() {
return mArtistId;
}
/**
* @param artistId Sets the artist id
*/
public void setArtistId(long artistId) {
this.mArtistId = artistId;
}
/**
* @return Gets the artist
*/
@ -315,6 +329,43 @@ public class MusicTrack {
this.mArtworkFile = artworkFile;
}
/**
* The name of the container (eg. a playlist or an artist)
*/
private String mContainerName;
/**
* @return Gets the name of the container
*/
public String getContainerName() {
return mContainerName;
}
/**
* @param containerName Sets the name of the container
*/
public void setContainerName(String containerName) {
mContainerName = containerName;
}
/**
* The position of the track in the container
*/
private long mContainerPosition;
/**
* @return Gets the position in the container
*/
public long getContainerPosition() {
return mContainerPosition;
}
/**
* @param containerPosition Sets the position in the container
*/
public void setContainerPosition(long containerPosition) {
mContainerPosition = containerPosition;
}
/**
* @return Returns the source file path

View file

@ -22,8 +22,6 @@
package de.arcus.playmusiclib.items;
import android.content.Context;
import java.util.List;
import de.arcus.playmusiclib.PlayMusicManager;
@ -32,7 +30,7 @@ import de.arcus.playmusiclib.PlayMusicManager;
* List of {@link de.arcus.playmusiclib.items.MusicTrack MusicTracks}.
* Eg. albums, playlists, etc...
*/
public abstract class MusicList {
public abstract class MusicTrackList {
/**
* The manager
*/
@ -42,7 +40,7 @@ public abstract class MusicList {
* Creates a data item
* @param playMusicManager The manager
*/
public MusicList(PlayMusicManager playMusicManager) {
public MusicTrackList(PlayMusicManager playMusicManager) {
mPlayMusicManager = playMusicManager;
}
@ -52,6 +50,17 @@ public abstract class MusicList {
*/
protected List<MusicTrack> mMusicTrackList;
/**
* The filename of the artwork
*/
protected String mArtworkFile;
/**
* The complet path of the artwork
*/
protected String mArtworkPath;
public List<MusicTrack> getMusicTrackList() {
// List is requested for the fist time
if (mMusicTrackList == null)
@ -61,17 +70,28 @@ public abstract class MusicList {
return mMusicTrackList;
}
/**
* Gets the artwork filename
*/
public String getArtworkFile() {
return mArtworkFile;
}
/**
* @param artworkFile Sets the artwork filename
*/
public void setArtworkFile(String artworkFile) {
mArtworkFile = artworkFile;
}
/**
* Loads all tracks from this list.
* Must be overwritten in all extended classes
*/
protected abstract void fetchTrackList();
/**
* Gets the artwork path
* @return Path to the artwork
*/
public abstract String getArtworkPath();
/**
* Gets the title of the list
@ -86,6 +106,17 @@ public abstract class MusicList {
*/
public abstract String getDescription();
/**
* Gets the artwork path
* @return Path to the artwork
*/
public String getArtworkPath() {
// Search for the artwork path
if (mArtworkPath == null)
mArtworkPath = mPlayMusicManager.getArtworkPath(mArtworkFile);
return mArtworkPath;
}
@Override
public String toString() {
return getTitle();

View file

@ -27,22 +27,19 @@ import de.arcus.playmusiclib.R;
import de.arcus.playmusiclib.datasources.MusicTrackDataSource;
/**
* Created by david on 24.01.15.
* A playlist
*/
public class Playlist extends MusicList {
public class Playlist extends MusicTrackList {
// Variables
private long mId, mListType;
private String mName;
private String mOwnerName;
private String mArtworkFile;
public final static long TYPE_USER = 0;
public final static long TYPE_QUEUE = 10;
public final static long TYPE_RADIO = 50;
public final static long TYPE_PUBLIC = 71;
private String mArtworkPath;
/**
* Creates a data item
* @param playMusicManager The manager
@ -107,22 +104,10 @@ public class Playlist extends MusicList {
this.mOwnerName = ownerName;
}
/**
* @return Gets the artwork file name
*/
public String getArtworFile() {
return mArtworkFile;
}
/**
* @param artworkfile Sets the artwork file name
*/
public void setArtworkFile(String artworkfile) {
this.mArtworkFile = artworkfile;
}
@Override
/**
* Gets the album name
* Gets the playlist name
*/
public String getTitle() {
// Play queue
@ -135,7 +120,7 @@ public class Playlist extends MusicList {
@Override
/**
* Gets the playlist name
* Gets the list owner name
*/
public String getDescription() {
// Play queue
@ -162,15 +147,4 @@ public class Playlist extends MusicList {
// Load the track list
mMusicTrackList = musicTrackDataSource.getByPlaylist(this);
}
@Override
/**
* return Gets the full path to the artwork
*/
public String getArtworkPath() {
// Search for the artwork path
if (mArtworkPath == null)
mArtworkPath = mPlayMusicManager.getArtworkPath(mArtworkFile);
return mArtworkPath;
}
}