mirror of
https://github.com/playmusicexporter/playmusicexporter
synced 2024-05-14 22:56:43 +00:00
Add file tools to framework
Add a playlist data source Improve the data sources
This commit is contained in:
parent
3b0eb97f51
commit
be1be7398c
|
@ -33,14 +33,17 @@ 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
|
||||
|
@ -106,10 +109,14 @@ public class TrackListActivity extends ActionBarActivity
|
|||
playMusicManager.setOfflineOnly(true);
|
||||
|
||||
AlbumDataSource albumDataSource = new AlbumDataSource(playMusicManager);
|
||||
albumDataSource.setSerchKey("A bird story");
|
||||
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,6 +136,14 @@ public class TrackListActivity extends ActionBarActivity
|
|||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
|
|
241
framework/src/main/java/de/arcus/framework/utils/FileTools.java
Normal file
241
framework/src/main/java/de/arcus/framework/utils/FileTools.java
Normal file
|
@ -0,0 +1,241 @@
|
|||
/*
|
||||
* 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.framework.utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import de.arcus.framework.logger.Logger;
|
||||
|
||||
/**
|
||||
* Help function for files
|
||||
*/
|
||||
public class FileTools {
|
||||
/**
|
||||
* Private constructor
|
||||
*/
|
||||
private FileTools() {}
|
||||
|
||||
/**
|
||||
* Creates a directory if it not exists
|
||||
* @param dir Directory path
|
||||
* @return Returns true if the directory was created or already exists
|
||||
*/
|
||||
public static boolean directoryCreate(String dir) {
|
||||
File fileDirectory = new File(dir);
|
||||
try {
|
||||
if (!fileDirectory.exists()) {
|
||||
Logger.getInstance().logVerbose("DirectoryCreate", "Create directory: " + dir);
|
||||
|
||||
// Creates the directory
|
||||
if (fileDirectory.mkdirs())
|
||||
return true;
|
||||
else
|
||||
Logger.getInstance().logWarning("DirectoryCreate", "MkDir failed");
|
||||
} else {
|
||||
// Directory exists
|
||||
Logger.getInstance().logDebug("DirectoryCreate", "Directory already exists");
|
||||
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// Failed
|
||||
Logger.getInstance().logError("DirectoryCreate", "Failed: " + e.getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the directory exists
|
||||
* @param dir Path of the file
|
||||
* @return Return whether the directory exists
|
||||
*/
|
||||
public static boolean directoryExists(String dir) {
|
||||
File tmp = new File(dir);
|
||||
|
||||
// Checks whether the directory exists and whether it is a directory
|
||||
return (tmp.isDirectory() && tmp.exists());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an empty file
|
||||
* @param file File path
|
||||
* @return Returns true if the file was successfully created
|
||||
*/
|
||||
public static boolean fileCreate(String file) {
|
||||
Logger.getInstance().logVerbose("FileCreate", "File: " + file);
|
||||
|
||||
try {
|
||||
// Create the file
|
||||
return (new File(file)).createNewFile();
|
||||
} catch (IOException e) {
|
||||
// Failed
|
||||
Logger.getInstance().logError("FileCreate", "Could not create file: " + e.getMessage());
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves a file
|
||||
* @param src Soruce path
|
||||
* @param dest Destination path
|
||||
* @return Return whether the moving was successful
|
||||
*/
|
||||
public static boolean fileMove(String src, String dest) {
|
||||
Logger.getInstance().logVerbose("FileMove", "From " + src + " to " + dest);
|
||||
|
||||
File fileSrc = new File(src);
|
||||
File fileDest = new File(dest);
|
||||
|
||||
// Move the file
|
||||
return fileSrc.renameTo(fileDest);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a file
|
||||
* @param file Path of the file
|
||||
* @return Returns whether the deleting was successful
|
||||
*/
|
||||
public static boolean fileDelete(String file) {
|
||||
// Delete the file
|
||||
return (new File(file)).delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the file exists
|
||||
* @param file Path of the file
|
||||
* @return Return whether the file exists
|
||||
*/
|
||||
public static boolean fileExists(String file) {
|
||||
File tmp = new File(file);
|
||||
|
||||
// Checks whether the file exists and whether it is a file
|
||||
return (tmp.isFile() && tmp.exists());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the file or directory is a link
|
||||
* @param path Path of the file / directory
|
||||
* @return Returns whether the file or directory is a link
|
||||
*/
|
||||
public static boolean pathIsSymbolicLink(String path) {
|
||||
File file = new File(path);
|
||||
|
||||
try {
|
||||
// Checks whether the file / directory is a symbolic link
|
||||
return (file.getAbsolutePath() == file.getCanonicalPath());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the root canonical file of a symbolic link
|
||||
* @param path The path
|
||||
* @return The root file
|
||||
*/
|
||||
public static File getRootCanonicalFile(String path) {
|
||||
return getRootCanonicalFile(new File(path));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the root canonical file of a symbolic link
|
||||
* @param file The file
|
||||
* @return The root file
|
||||
*/
|
||||
public static File getRootCanonicalFile(File file) {
|
||||
try {
|
||||
// Gets the canonical file
|
||||
File canonicalFile = file.getCanonicalFile();
|
||||
|
||||
// Differences between the canonical and the absolute file
|
||||
while (!file.getAbsolutePath().equals(canonicalFile.getAbsolutePath())) {
|
||||
file = canonicalFile;
|
||||
|
||||
// Go deeper
|
||||
canonicalFile = file.getCanonicalFile();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// Failed
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all storages; eg. all sdcards
|
||||
* @return List of all storages
|
||||
*/
|
||||
public static String[] getStorages() {
|
||||
List<String> storages = new ArrayList<>();
|
||||
|
||||
// Hard coded mount points
|
||||
final String[] mountPointBlacklist = new String[] { "/mnt/tmp", "/mnt/factory", "/mnt/obb", "/mnt/asec", "/mnt/secure", "/mnt/media_rw", "/mnt/shell" };
|
||||
final String[] mountPointDirectories = new String[] { "/mnt", "/storage" };
|
||||
final String[] mountPoints = new String[] { "/sdcard", "/external_sd" };
|
||||
|
||||
|
||||
// Adds all mount point directories
|
||||
for(String mountPointDirectory : mountPointDirectories) {
|
||||
// Checks all subdirectories
|
||||
File dir = getRootCanonicalFile(mountPointDirectory);
|
||||
if (dir.exists() && dir.isDirectory()) {
|
||||
File[] files = dir.listFiles();
|
||||
if (files != null) {
|
||||
for (File subDir : files) {
|
||||
subDir = getRootCanonicalFile(subDir);
|
||||
// Is directory
|
||||
if (subDir.isDirectory()) {
|
||||
// Add mount point to list
|
||||
if (!storages.contains(subDir.getAbsolutePath()))
|
||||
storages.add(subDir.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Adds all direct moint points
|
||||
for(String mointPoint : mountPoints) {
|
||||
File file = getRootCanonicalFile(mointPoint);
|
||||
if (file.isDirectory()) {
|
||||
if (!storages.contains(file.getAbsolutePath()))
|
||||
storages.add(file.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
// Remove all blacklisted paths
|
||||
for (String blacklistPath : mountPointBlacklist) {
|
||||
storages.remove(blacklistPath);
|
||||
}
|
||||
|
||||
// Returns the array
|
||||
return storages.toArray(new String[storages.size()]);
|
||||
}
|
||||
}
|
|
@ -29,8 +29,12 @@ import android.database.SQLException;
|
|||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import de.arcus.framework.superuser.SuperUser;
|
||||
import de.arcus.framework.superuser.SuperUserTools;
|
||||
import de.arcus.framework.utils.FileTools;
|
||||
import de.arcus.playmusiclib.exceptions.CouldNotOpenDatabase;
|
||||
import de.arcus.playmusiclib.exceptions.NoSuperUserException;
|
||||
import de.arcus.playmusiclib.exceptions.PlayMusicNotFound;
|
||||
|
@ -137,7 +141,10 @@ public class PlayMusicManager {
|
|||
|
||||
|
||||
/**
|
||||
* Loads all needed information
|
||||
* Loads all needed information and opens the database
|
||||
* @throws PlayMusicNotFound PlayMusic is not installed
|
||||
* @throws NoSuperUserException No super user permissions
|
||||
* @throws CouldNotOpenDatabase Could not open the database
|
||||
*/
|
||||
public void startUp() throws PlayMusicNotFound, NoSuperUserException, CouldNotOpenDatabase {
|
||||
// Gets the package manager
|
||||
|
@ -151,29 +158,59 @@ public class PlayMusicManager {
|
|||
throw new PlayMusicNotFound();
|
||||
}
|
||||
|
||||
|
||||
// Path to the private data
|
||||
mPathPrivateData = mPlayMusicApplicationInfo.dataDir;
|
||||
mPathPublicData = new String[] {}; // TODO: Get sdcards
|
||||
|
||||
List<String> publicDataList = new ArrayList<>();
|
||||
// Search on all sdcards
|
||||
for (String storage : FileTools.getStorages()) {
|
||||
String publicData = storage + "/Android/data/com.google.android.music";
|
||||
|
||||
// Directory exists
|
||||
if (FileTools.directoryExists(publicData))
|
||||
publicDataList.add(publicData);
|
||||
}
|
||||
// Convert to array
|
||||
mPathPublicData = publicDataList.toArray(new String[publicDataList.size()]);
|
||||
|
||||
// Loads the database
|
||||
loadDatabase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the database to a temp directory and opens it
|
||||
* @throws NoSuperUserException No super user permissions
|
||||
* @throws CouldNotOpenDatabase Could not open the database
|
||||
*/
|
||||
private void loadDatabase() throws NoSuperUserException, CouldNotOpenDatabase {
|
||||
// Ask for super user
|
||||
if (!SuperUser.askForPermissions())
|
||||
throw new NoSuperUserException();
|
||||
|
||||
// Close the database
|
||||
closeDatabase();
|
||||
|
||||
// Copy the database to the temp folder
|
||||
if (!SuperUserTools.fileCopy(getDatabasePath(), getTempDatabasePath()))
|
||||
throw new CouldNotOpenDatabase();
|
||||
|
||||
// Opens the database
|
||||
try {
|
||||
// Close the database
|
||||
closeDatabase();
|
||||
|
||||
mDatabase = SQLiteDatabase.openDatabase(getTempDatabasePath(), null, SQLiteDatabase.OPEN_READONLY);
|
||||
} catch (SQLException e) {
|
||||
throw new CouldNotOpenDatabase();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reloads the database from playmusic
|
||||
* @throws NoSuperUserException No super user permissions
|
||||
* @throws CouldNotOpenDatabase Could not open the database
|
||||
*/
|
||||
public void realoadDatabase() throws NoSuperUserException, CouldNotOpenDatabase {
|
||||
loadDatabase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the database if it's open
|
||||
|
@ -205,6 +242,13 @@ public class PlayMusicManager {
|
|||
// Music file exists
|
||||
if (SuperUserTools.fileExists(path)) return path;
|
||||
|
||||
// Search in the public data
|
||||
for (String publicData : mPathPublicData) {
|
||||
path = publicData + "/files/music/" + localCopyPath;
|
||||
|
||||
if (FileTools.fileExists(path)) return path;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -224,11 +268,18 @@ public class PlayMusicManager {
|
|||
// Artwork path is empty
|
||||
if (TextUtils.isEmpty(artworkPath)) return null;
|
||||
|
||||
// Private music path
|
||||
// Private artwork path
|
||||
String path = getPrivateFilesPath() + "/" + artworkPath;
|
||||
// Music file exists
|
||||
// Artwork file exists
|
||||
if (SuperUserTools.fileExists(path)) return path;
|
||||
|
||||
// Search in the public data
|
||||
for (String publicData : mPathPublicData) {
|
||||
path = publicData + "/files/" + artworkPath;
|
||||
|
||||
if (FileTools.fileExists(path)) return path;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
package de.arcus.playmusiclib.datasources;
|
||||
|
||||
import android.database.Cursor;
|
||||
import android.database.DatabaseUtils;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -34,16 +35,19 @@ import de.arcus.playmusiclib.items.Album;
|
|||
* Data source for albums
|
||||
*/
|
||||
public class AlbumDataSource extends DataSource<Album> {
|
||||
// Tables
|
||||
private final static String TABLE_MUSIC = "MUSIC";
|
||||
|
||||
private final static String COLUMN_ALBUMID = "AlbumId";
|
||||
private final static String COLUMN_ALBUM = "Album";
|
||||
private final static String COLUMN_ALBUMARTIST = "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";
|
||||
// All fields
|
||||
private final static String COLUMN_ALBUMID = "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_TITLE = "Title";
|
||||
private final static String COLUMN_ARTIST = "Artist";
|
||||
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};
|
||||
|
||||
|
@ -102,28 +106,25 @@ public class AlbumDataSource extends DataSource<Album> {
|
|||
* @return The new where command
|
||||
*/
|
||||
private String prepareWhere(String where) {
|
||||
// The new where
|
||||
String newWhere = "LocalCopyType != 300";
|
||||
// Ignore non-PlayMusic tracks
|
||||
where = combineWhere(where, "LocalCopyType != 300");
|
||||
|
||||
// Loads only offline tracks
|
||||
if (mOfflineOnly)
|
||||
newWhere += " AND LocalCopyPath IS NOT NULL";
|
||||
where = combineWhere(where, "LocalCopyPath IS NOT NULL");
|
||||
|
||||
// Search only items which contains the key
|
||||
if (!TextUtils.isEmpty(mSearchKey)) {
|
||||
String searchKey = mSearchKey.replace("'", "''");
|
||||
String searchKey = DatabaseUtils.sqlEscapeString("%" + mSearchKey + "%");
|
||||
|
||||
newWhere += " AND (" + COLUMN_ALBUM + " LIKE '%" + searchKey + "%'";
|
||||
newWhere += " OR " + COLUMN_TITLE + " LIKE '%" + searchKey + "%'";
|
||||
newWhere += " OR " + COLUMN_ALBUMARTIST + " LIKE '%" + searchKey + "%'";
|
||||
newWhere += " OR " + COLUMN_ARTIST + " LIKE '%" + searchKey + "%')";
|
||||
String searchWhere = COLUMN_ALBUM + " LIKE " + searchKey;
|
||||
searchWhere += " OR " + COLUMN_TITLE + " LIKE " + searchKey;
|
||||
searchWhere += " OR " + COLUMN_ALBUMARTIST + " LIKE " + searchKey;
|
||||
searchWhere += " OR " + COLUMN_ARTIST + " LIKE " + searchKey;
|
||||
|
||||
where = combineWhere(where, searchWhere);
|
||||
}
|
||||
|
||||
// Adds an 'and' if needed
|
||||
if (!TextUtils.isEmpty(where)) where = "(" + where + ") AND ";
|
||||
|
||||
where += newWhere;
|
||||
|
||||
return where;
|
||||
}
|
||||
|
||||
|
@ -151,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("AlbumID = " + id));
|
||||
return getItem(TABLE_MUSIC, COLUMNS_ALL, prepareWhere(COLUMN_ALBUMID + " = " + id));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -24,6 +24,7 @@ package de.arcus.playmusiclib.datasources;
|
|||
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
@ -150,4 +151,38 @@ public abstract class DataSource<T> {
|
|||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Combines two SQL where commands with an AND operator
|
||||
* @param whereA Where command A
|
||||
* @param whereB Where command B
|
||||
* @return Returns a combined where command
|
||||
*/
|
||||
protected static String combineWhere(String whereA, String whereB) {
|
||||
return combineWhere(whereA, whereB, "AND");
|
||||
}
|
||||
|
||||
/**
|
||||
* Combines two SQL where commands
|
||||
* @param whereA Where command A
|
||||
* @param whereB Where command B
|
||||
* @param operator The operator word to use (AND or OR)
|
||||
* @return Returns a combined where command
|
||||
*/
|
||||
protected static String combineWhere(String whereA, String whereB, String operator) {
|
||||
// Combine both
|
||||
if (!TextUtils.isEmpty(whereA) && !TextUtils.isEmpty(whereB))
|
||||
return "((" + whereA + ") " + operator + " (" + whereB + "))";
|
||||
|
||||
// Use only whereA
|
||||
if (!TextUtils.isEmpty(whereA) && TextUtils.isEmpty(whereB))
|
||||
return whereA;
|
||||
|
||||
// Use only whereB
|
||||
if (TextUtils.isEmpty(whereA) && !TextUtils.isEmpty(whereB))
|
||||
return whereB;
|
||||
|
||||
// No where is set
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
package de.arcus.playmusiclib.datasources;
|
||||
|
||||
import android.database.Cursor;
|
||||
import android.database.DatabaseUtils;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -41,24 +42,24 @@ public class MusicTrackDataSource extends DataSource<MusicTrack> {
|
|||
private final static String TABLE_MUSIC_PLAYLIST = "MUSIC LEFT JOIN LISTITEMS ON MUSIC.ID = LISTITEMS.MusicID";
|
||||
|
||||
// All fields
|
||||
private final static String COLUMN_ID = "Id";
|
||||
private final static String COLUMN_SIZE = "Size";
|
||||
private final static String COLUMN_LOCALCOPYPATH = "LocalCopyPath";
|
||||
private final static String COLUMN_LOCALCOPYTYPE = "LocalCopyType";
|
||||
private final static String COLUMN_LOCALCOPYSTORAGETYPE = "LocalCopyStorageType";
|
||||
private final static String COLUMN_TITLE = "Title";
|
||||
private final static String COLUMN_ARTIST = "Artist";
|
||||
private final static String COLUMN_ALBUMARTIST = "AlbumArtist";
|
||||
private final static String COLUMN_ALBUM = "Album";
|
||||
private final static String COLUMN_GENRE = "Genre";
|
||||
private final static String COLUMN_YEAR = "Year";
|
||||
private final static String COLUMN_TRACKNUMBER = "TrackNumber";
|
||||
private final static String COLUMN_DISCNUMBER = "DiscNumber";
|
||||
private final static String COLUMN_DURATION = "Duration";
|
||||
private final static String COLUMN_ALBUMID = "AlbumId";
|
||||
private final static String COLUMN_CLIENTID = "ClientId";
|
||||
private final static String COLUMN_SOURCEID = "SourceId";
|
||||
private final static String COLUMN_CPDATA = "CpData";
|
||||
private final static String COLUMN_ID = "MUSIC.Id";
|
||||
private final static String COLUMN_SIZE = "MUSIC.Size";
|
||||
private final static String COLUMN_LOCALCOPYPATH = "MUSIC.LocalCopyPath";
|
||||
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 = "MUSIC.Artist";
|
||||
private final static String COLUMN_ALBUMARTIST = "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_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_CPDATA = "MUSIC.CpData";
|
||||
private final static String COLUMN_ARTWORKFILE = "(SELECT LocalLocation FROM artwork_cache WHERE artwork_cache.RemoteLocation = AlbumArtLocation) AS ArtworkFile";
|
||||
|
||||
// All columns
|
||||
|
@ -122,28 +123,25 @@ public class MusicTrackDataSource extends DataSource<MusicTrack> {
|
|||
* @return The new where command
|
||||
*/
|
||||
private String prepareWhere(String where) {
|
||||
// The new where
|
||||
String newWhere = "LocalCopyType != 300";
|
||||
// Ignore non-PlayMusic tracks
|
||||
where = combineWhere(where, "LocalCopyType != 300");
|
||||
|
||||
// Loads only offline tracks
|
||||
if (mOfflineOnly)
|
||||
newWhere += " AND LocalCopyPath IS NOT NULL";
|
||||
where = combineWhere(where, "LocalCopyPath IS NOT NULL");
|
||||
|
||||
// Search only items which contains the key
|
||||
if (!TextUtils.isEmpty(mSearchKey)) {
|
||||
String searchKey = mSearchKey.replace("'", "''");
|
||||
String searchKey = DatabaseUtils.sqlEscapeString("%" + mSearchKey + "%");
|
||||
|
||||
newWhere += " AND (" + COLUMN_ALBUM + " LIKE '%" + searchKey + "%'";
|
||||
newWhere += " OR " + COLUMN_TITLE + " LIKE '%" + searchKey + "%'";
|
||||
newWhere += " OR " + COLUMN_ALBUMARTIST + " LIKE '%" + searchKey + "%'";
|
||||
newWhere += " OR " + COLUMN_ARTIST + " LIKE '%" + searchKey + "%')";
|
||||
String searchWhere = COLUMN_ALBUM + " LIKE " + searchKey;
|
||||
searchWhere += " OR " + COLUMN_TITLE + " LIKE " + searchKey;
|
||||
searchWhere += " OR " + COLUMN_ALBUMARTIST + " LIKE " + searchKey;
|
||||
searchWhere += " OR " + COLUMN_ARTIST + " LIKE " + searchKey;
|
||||
|
||||
where = combineWhere(where, searchWhere);
|
||||
}
|
||||
|
||||
// Adds an 'and' if needed
|
||||
if (!TextUtils.isEmpty(where)) where = "(" + where + ") AND ";
|
||||
|
||||
where += newWhere;
|
||||
|
||||
return where;
|
||||
}
|
||||
|
||||
|
@ -205,6 +203,6 @@ public class MusicTrackDataSource extends DataSource<MusicTrack> {
|
|||
* @return Returns the track list
|
||||
*/
|
||||
public List<MusicTrack> getByPlaylist(Playlist playlist) {
|
||||
return getItems(TABLE_MUSIC, COLUMNS_ALL, prepareWhere("ListId = " + playlist.getId()), "LISTITEMS.ID");
|
||||
return getItems(TABLE_MUSIC_PLAYLIST, COLUMNS_ALL, prepareWhere("ListId = " + playlist.getId()), "LISTITEMS.ID");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* 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.Playlist;
|
||||
|
||||
/**
|
||||
* Data source for playlists
|
||||
*/
|
||||
public class PlaylistDataSource extends DataSource<Playlist> {
|
||||
// Tables
|
||||
private final static String TABLE_LIST = "LISTS";
|
||||
|
||||
// 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";
|
||||
|
||||
// All columns
|
||||
private final static String[] COLUMNS_ALL = { COLUMN_ID, COLUMN_NAME,
|
||||
COLUMN_LISTTYPE, COLUMN_OWNERNAME, COLUMN_ARTWORKFILE};
|
||||
|
||||
|
||||
/**
|
||||
* If this is set the data source will only load offline tracks
|
||||
*/
|
||||
private boolean mOfflineOnly; // TODO: Offline only has no effects on the playlist 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 PlaylistDataSource(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_NAME + " LIKE " + searchKey + ")");
|
||||
}
|
||||
|
||||
return where;
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Gets the data object from a data row
|
||||
* @param cursor Data row
|
||||
* @return Data object
|
||||
*/
|
||||
protected Playlist getDataObject(Cursor cursor) {
|
||||
Playlist instance = new Playlist(mPlayMusicManager);
|
||||
|
||||
// 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)));
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a playlist by Id
|
||||
* @param id The playlist id
|
||||
* @return Returns the playlist or null
|
||||
*/
|
||||
public Playlist getById(long id) {
|
||||
return getItem(TABLE_LIST, COLUMNS_ALL, prepareWhere(COLUMN_ID + " = " + id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of all playlists
|
||||
* @return Returns all playlists
|
||||
*/
|
||||
public List<Playlist> getAll() {
|
||||
return getItems(TABLE_LIST, COLUMNS_ALL, prepareWhere(COLUMN_LISTTYPE + " != " + Playlist.TYPE_QUEUE), COLUMN_NAME);
|
||||
}
|
||||
}
|
|
@ -36,8 +36,10 @@ public class Playlist extends MusicList {
|
|||
private String mOwnerName;
|
||||
private String mArtworkFile;
|
||||
|
||||
private final static long TYPE_QUEUE = 10;
|
||||
private final static long TYPE_RADIO = 50;
|
||||
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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue