mirror of
https://github.com/playmusicexporter/playmusicexporter
synced 2024-05-14 02:46:42 +00:00
Added the playmusiclib
This commit is contained in:
parent
e85e97d141
commit
3b0eb97f51
|
@ -79,12 +79,14 @@
|
|||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Android API 21 Platform" jdkType="Android SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" exported="" name="appcompat-v7-21.0.3" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-annotations-21.0.3" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-v4-21.0.3" level="project" />
|
||||
<orderEntry type="module" module-name="playmusiclib" exported="" />
|
||||
<orderEntry type="module" module-name="framework" exported="" />
|
||||
</component>
|
||||
</module>
|
||||
|
|
|
@ -48,4 +48,5 @@ dependencies {
|
|||
compile 'com.android.support:appcompat-v7:21.0.3'
|
||||
compile 'com.android.support:support-v4:21.0.3'
|
||||
compile project(':framework')
|
||||
compile project(':playmusiclib')
|
||||
}
|
||||
|
|
|
@ -26,10 +26,21 @@ import android.content.Intent;
|
|||
import android.os.Bundle;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.util.Log;
|
||||
|
||||
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.playmusiclib.PlayMusicManager;
|
||||
import de.arcus.playmusiclib.datasources.AlbumDataSource;
|
||||
import de.arcus.playmusiclib.datasources.MusicTrackDataSource;
|
||||
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;
|
||||
|
||||
/**
|
||||
* An activity representing a list of Tracks. This activity
|
||||
|
@ -87,7 +98,44 @@ public class TrackListActivity extends ActionBarActivity
|
|||
}
|
||||
|
||||
|
||||
SuperUser.askForPermissions();
|
||||
PlayMusicManager playMusicManager = new PlayMusicManager(this);
|
||||
|
||||
try {
|
||||
// Simple play ground
|
||||
playMusicManager.startUp();
|
||||
playMusicManager.setOfflineOnly(true);
|
||||
|
||||
AlbumDataSource albumDataSource = new AlbumDataSource(playMusicManager);
|
||||
albumDataSource.setSerchKey("A bird story");
|
||||
|
||||
// Load all albums
|
||||
List<Album> albums = albumDataSource.getAll();
|
||||
|
||||
if (albums.size() > 0) {
|
||||
// Gets the first album
|
||||
Album album = albums.get(0);
|
||||
|
||||
// Load tracks from album
|
||||
List<MusicTrack> tracks = album.getMusicTrackList();
|
||||
|
||||
if (tracks.size() > 0) {
|
||||
// Gets the first track
|
||||
MusicTrack track = tracks.get(0);
|
||||
|
||||
String fileMusic = track.getSourceFile();
|
||||
String artwork = track.getArtworkPath();
|
||||
|
||||
Log.d("Debug", "Breakpoint");
|
||||
}
|
||||
}
|
||||
|
||||
} catch (PlayMusicNotFound playMusicNotFound) {
|
||||
playMusicNotFound.printStackTrace();
|
||||
} catch (NoSuperUserException e) {
|
||||
e.printStackTrace();
|
||||
} catch (CouldNotOpenDatabase couldNotOpenDatabase) {
|
||||
couldNotOpenDatabase.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
// TODO: If exposing deep links into your app, handle intents here.
|
||||
|
|
|
@ -113,7 +113,7 @@ public class SuperUser {
|
|||
// Starts the process
|
||||
if (sessionStart()) {
|
||||
// Test for superuser
|
||||
SuperUserCommand superUserCommand = new SuperUserCommand("whoami");
|
||||
SuperUserCommand superUserCommand = new SuperUserCommand("echo 'root'");
|
||||
|
||||
Logger.getInstance().logInfo("SuperUser", "askForPermissions");
|
||||
if (superUserCommand.execute()) {
|
||||
|
|
|
@ -26,19 +26,35 @@ package de.arcus.framework.superuser;
|
|||
* Tools for the superuser
|
||||
*/
|
||||
public class SuperUserTools {
|
||||
/**
|
||||
* Private constructor
|
||||
*/
|
||||
private SuperUserTools() {}
|
||||
|
||||
/**
|
||||
* Copy a file with root permissions
|
||||
* @param src Source file
|
||||
* @param dest Destination file
|
||||
* @return Returns whether the command was successful
|
||||
*/
|
||||
public static boolean copyFile(String src, String dest) {
|
||||
public static boolean fileCopy(String src, String dest) {
|
||||
SuperUserCommand superUserCommand = new SuperUserCommand(new String[] {
|
||||
"rm -f '" + dest + "'", // Remove destination file
|
||||
"cat '" + src + "' >> '" + dest + "'", // Using cat to copy file instead of cp, because you can use it without busybox
|
||||
"chmod 0777 '" + dest + "'" // Change the access mode to all users (chown sdcard_r will fail on some devices)
|
||||
"chmod 0777 '" + dest + "'", // Change the access mode to all users (chown sdcard_r will fail on some devices)
|
||||
"echo 'done'" // Fix to prevent the 'no output' bug in SuperUserCommand
|
||||
});
|
||||
// Execute the command
|
||||
// Executes the command
|
||||
superUserCommand.execute();
|
||||
|
||||
// Superuser permissions and command are successful
|
||||
return superUserCommand.commandWasSuccessful();
|
||||
}
|
||||
|
||||
public static boolean fileExists(String filename) {
|
||||
SuperUserCommand superUserCommand = new SuperUserCommand("ls '" + filename + "'");
|
||||
|
||||
// Executes the command
|
||||
superUserCommand.execute();
|
||||
|
||||
// Superuser permissions and command are successful
|
||||
|
|
1
playmusiclib/.gitignore
vendored
Normal file
1
playmusiclib/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/build
|
46
playmusiclib/build.gradle
Normal file
46
playmusiclib/build.gradle
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
compileSdkVersion 21
|
||||
buildToolsVersion "21.1.2"
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 8
|
||||
targetSdkVersion 21
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
compile project(':framework')
|
||||
}
|
91
playmusiclib/playmusiclib.iml
Normal file
91
playmusiclib/playmusiclib.iml
Normal file
|
@ -0,0 +1,91 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="android-gradle" name="Android-Gradle">
|
||||
<configuration>
|
||||
<option name="GRADLE_PROJECT_PATH" value=":playmusiclib" />
|
||||
</configuration>
|
||||
</facet>
|
||||
<facet type="android" name="Android">
|
||||
<configuration>
|
||||
<option name="SELECTED_BUILD_VARIANT" value="debug" />
|
||||
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
|
||||
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
|
||||
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugTest" />
|
||||
<option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
|
||||
<option name="TEST_SOURCE_GEN_TASK_NAME" value="generateDebugTestSources" />
|
||||
<option name="ALLOW_USER_CONFIGURATION" value="false" />
|
||||
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
|
||||
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
|
||||
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
|
||||
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
|
||||
<option name="LIBRARY_PROJECT" value="true" />
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="false">
|
||||
<output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/test/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/test/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/test/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/test/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/test/debug" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/test/debug" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Android API 21 Platform" jdkType="Android SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" exported="" name="support-annotations-21.0.3" level="project" />
|
||||
<orderEntry type="module" module-name="framework" exported="" />
|
||||
</component>
|
||||
</module>
|
||||
|
17
playmusiclib/proguard-rules.pro
vendored
Normal file
17
playmusiclib/proguard-rules.pro
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in /home/david/android-sdks/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import android.app.Application;
|
||||
import android.test.ApplicationTestCase;
|
||||
|
||||
/**
|
||||
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
|
||||
*/
|
||||
public class ApplicationTest extends ApplicationTestCase<Application> {
|
||||
public ApplicationTest() {
|
||||
super(Application.class);
|
||||
}
|
||||
}
|
30
playmusiclib/src/main/AndroidManifest.xml
Normal file
30
playmusiclib/src/main/AndroidManifest.xml
Normal file
|
@ -0,0 +1,30 @@
|
|||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="de.arcus.playmusiclib">
|
||||
|
||||
<application android:allowBackup="true">
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
|
@ -0,0 +1,204 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
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;
|
||||
private OutputStream mOutput;
|
||||
private byte[] mMagicNumber;
|
||||
|
||||
static final int BUFFER_SIZE = 1024;
|
||||
static final byte[] MAGIC_NUMBER = { 18, -45, 21, 39 };
|
||||
|
||||
/**
|
||||
* Creates a new exporter for AllAccess files
|
||||
*
|
||||
* @param input The encrypted music file (Copy the file into a readable directory before you use them.)
|
||||
* @param cpData The 16 byte long key (CpData-Blob in MUSIC table)
|
||||
* @throws NoSuchAlgorithmException Encryption method is not supported on this device
|
||||
* @throws NoSuchPaddingException Padding mode is not supported on this device
|
||||
* @throws IOException File could not be read (This class does not support SU commands; first copy your file into a readable directory)
|
||||
*/
|
||||
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");
|
||||
|
||||
// Opens the source file
|
||||
mInput = new FileInputStream(mFileName);
|
||||
|
||||
// Reads the first 4 bytes = MagicNumber
|
||||
mMagicNumber = new byte[4];
|
||||
if (mInput.read(mMagicNumber) != 4)
|
||||
mMagicNumber = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the magic number of the file is correct
|
||||
*
|
||||
* @return Returns whether the Magic Number is valid
|
||||
*/
|
||||
public boolean hasValidMagicNumber()
|
||||
{
|
||||
if (mMagicNumber == null)
|
||||
return false;
|
||||
|
||||
if (mMagicNumber.length != 4)
|
||||
return false;
|
||||
|
||||
for(int i=0; i<4; i++)
|
||||
if (mMagicNumber[i] != MAGIC_NUMBER[i])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves an unencrypted copy of the music file as an Mp3
|
||||
* @param filename The path to the target file
|
||||
* @return Returns whether the file was successfully saved
|
||||
*/
|
||||
public boolean save(String filename)
|
||||
{
|
||||
try {
|
||||
// Opens the target file
|
||||
mOutput = new FileOutputStream(filename);
|
||||
|
||||
byte[] output = new byte[BUFFER_SIZE];
|
||||
|
||||
// Reads all blocks of the file
|
||||
while(mInput.available() > 0) {
|
||||
int size = read(output);
|
||||
if (size > 0) {
|
||||
mOutput.write(output, 0, size);
|
||||
} else
|
||||
break;
|
||||
}
|
||||
|
||||
// Close the files
|
||||
mInput.close();
|
||||
mOutput.close();
|
||||
|
||||
// Everything went according to plan
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// Try to close the files if an error occurs
|
||||
try {
|
||||
if (mInput != null)
|
||||
mInput.close();
|
||||
if (mOutput != null)
|
||||
mOutput.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// An error has Occurred
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a block and decrypts it
|
||||
* @param output output buffer
|
||||
* @return Returns the length of the output buffer
|
||||
* @throws Exception
|
||||
*/
|
||||
private int read(byte[] output) throws Exception
|
||||
{
|
||||
byte[] mBuffer = new byte[BUFFER_SIZE];
|
||||
byte[] mIvBuffer = new byte[16];
|
||||
|
||||
int pos = 0;
|
||||
|
||||
// Fills the buffer
|
||||
while (pos < BUFFER_SIZE)
|
||||
{
|
||||
int size = mInput.read(mBuffer, pos, BUFFER_SIZE - pos);
|
||||
// There is nothing more to read
|
||||
if (size == -1)
|
||||
{
|
||||
// Error, there was nothing more to read
|
||||
if (pos == 0)
|
||||
return -1;
|
||||
|
||||
// Buffer is filled
|
||||
if (pos > 16)
|
||||
break;
|
||||
|
||||
// Error, block is smaller than 16 bytes
|
||||
return -1;
|
||||
}
|
||||
pos += size;
|
||||
}
|
||||
|
||||
// The first 16 bytes of the block are the initialization vector
|
||||
System.arraycopy(mBuffer, 0, mIvBuffer, 0, 16);
|
||||
IvParameterSpec ivParameter = new IvParameterSpec(mIvBuffer);
|
||||
|
||||
// The remaining bytes are the encrypted data
|
||||
int decodeSize = pos - 16;
|
||||
|
||||
try
|
||||
{
|
||||
// Initializes the encryption method
|
||||
mCipher.init(Cipher.DECRYPT_MODE, mKeySpec, ivParameter);
|
||||
|
||||
// Decrypts the block
|
||||
if (mCipher.doFinal(mBuffer, 16, decodeSize, output, 0) != decodeSize)
|
||||
throw new IllegalStateException("Wrong block size");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Unexpected error
|
||||
throw new Exception("Unexpected error while decrypting", ex);
|
||||
}
|
||||
|
||||
// Returns the block size
|
||||
return decodeSize;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,262 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.database.SQLException;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import de.arcus.framework.superuser.SuperUser;
|
||||
import de.arcus.framework.superuser.SuperUserTools;
|
||||
import de.arcus.playmusiclib.exceptions.CouldNotOpenDatabase;
|
||||
import de.arcus.playmusiclib.exceptions.NoSuperUserException;
|
||||
import de.arcus.playmusiclib.exceptions.PlayMusicNotFound;
|
||||
import de.arcus.playmusiclib.items.MusicTrack;
|
||||
|
||||
/**
|
||||
* Connects to the PlayMusic data
|
||||
*/
|
||||
public class PlayMusicManager {
|
||||
/**
|
||||
* PlayMusic package id
|
||||
*/
|
||||
public static final String PLAYMUSIC_PACKAGE_ID = "com.google.android.music";
|
||||
|
||||
/**
|
||||
* Context of the app, needed to access to the package manager
|
||||
*/
|
||||
private Context mContext;
|
||||
|
||||
/**
|
||||
* @return Gets the app context
|
||||
*/
|
||||
public Context getContext() {
|
||||
return mContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Play Music database
|
||||
*/
|
||||
private SQLiteDatabase mDatabase;
|
||||
|
||||
/**
|
||||
* @return Gets the database
|
||||
*/
|
||||
public SQLiteDatabase getDatabase() {
|
||||
return mDatabase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Path to the private app data
|
||||
* Eg.: /data/data/com.google.android.music/
|
||||
*/
|
||||
private String mPathPrivateData;
|
||||
|
||||
/**
|
||||
* Paths to all possible public app data
|
||||
* Eg.: /sdcard/Android/data/com.google.android.music/
|
||||
*/
|
||||
private String[] mPathPublicData;
|
||||
|
||||
/**
|
||||
* Application info from PlayMusic
|
||||
*/
|
||||
private ApplicationInfo mPlayMusicApplicationInfo;
|
||||
|
||||
/**
|
||||
* @return Gets the path to the database
|
||||
*/
|
||||
private String getDatabasePath() {
|
||||
return mPathPrivateData + "/databases/music.db";
|
||||
}
|
||||
|
||||
/**
|
||||
* The database will be copied to a temp folder to access from the app
|
||||
* @return Gets the temp path to the database
|
||||
*/
|
||||
private String getTempDatabasePath() {
|
||||
return getTempPath() + "/music.db";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the temp path to the exported music
|
||||
*/
|
||||
private String getTempPath() {
|
||||
return mContext.getCacheDir().getAbsolutePath();
|
||||
}
|
||||
|
||||
/**
|
||||
* If this is set the data source will only load offline tracks
|
||||
*/
|
||||
private boolean mOfflineOnly;
|
||||
|
||||
/**
|
||||
* @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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new PlayMusic manager
|
||||
* @param context App context
|
||||
*/
|
||||
public PlayMusicManager(Context context) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Loads all needed information
|
||||
*/
|
||||
public void startUp() throws PlayMusicNotFound, NoSuperUserException, CouldNotOpenDatabase {
|
||||
// Gets the package manager
|
||||
PackageManager packageManager = mContext.getPackageManager();
|
||||
|
||||
try {
|
||||
// Loads the application info
|
||||
mPlayMusicApplicationInfo = packageManager.getApplicationInfo(PLAYMUSIC_PACKAGE_ID, 0);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
// No PlayMusic
|
||||
throw new PlayMusicNotFound();
|
||||
}
|
||||
|
||||
// Path to the private data
|
||||
mPathPrivateData = mPlayMusicApplicationInfo.dataDir;
|
||||
mPathPublicData = new String[] {}; // TODO: Get sdcards
|
||||
|
||||
// Ask for super user
|
||||
if (!SuperUser.askForPermissions())
|
||||
throw new NoSuperUserException();
|
||||
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Closes the database if it's open
|
||||
*/
|
||||
private void closeDatabase() {
|
||||
if (mDatabase == null) return;
|
||||
|
||||
mDatabase.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the path to the private music
|
||||
*/
|
||||
public String getPrivateMusicPath() {
|
||||
return mPathPrivateData + "/files/music";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the path to the music track
|
||||
* @param localCopyPath The local copy path
|
||||
* @return The path to the music file
|
||||
*/
|
||||
public String getMusicFile(String localCopyPath) {
|
||||
// LocalCopyPath is empty
|
||||
if (TextUtils.isEmpty(localCopyPath)) return null;
|
||||
|
||||
// Private music path
|
||||
String path = getPrivateMusicPath() + "/" + localCopyPath;
|
||||
// Music file exists
|
||||
if (SuperUserTools.fileExists(path)) return path;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the path to the private files
|
||||
*/
|
||||
public String getPrivateFilesPath() {
|
||||
return mPathPrivateData + "/files";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the full path to the artwork
|
||||
* @param artworkPath The artwork path
|
||||
* @return The full path to the artwork
|
||||
*/
|
||||
public String getArtworkPath(String artworkPath) {
|
||||
// Artwork path is empty
|
||||
if (TextUtils.isEmpty(artworkPath)) return null;
|
||||
|
||||
// Private music path
|
||||
String path = getPrivateFilesPath() + "/" + artworkPath;
|
||||
// Music file exists
|
||||
if (SuperUserTools.fileExists(path)) return path;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports a track to the sd card
|
||||
* @param musicTrack The music track you want to export
|
||||
* @param dest The destination path
|
||||
* @return Returns whether the export was successful
|
||||
*/
|
||||
public boolean exportMusicTrack(MusicTrack musicTrack, String dest) {
|
||||
// Check for null
|
||||
if (musicTrack == null) return false;
|
||||
|
||||
String srcFile = musicTrack.getSourceFile();
|
||||
|
||||
// Could not find the source file
|
||||
if (srcFile == null) return false;
|
||||
|
||||
String fileTmp = getTempPath() + "/tmp.mp3";
|
||||
|
||||
// Copy to temp path failed
|
||||
if (!SuperUserTools.fileCopy(srcFile, fileTmp))
|
||||
return false;
|
||||
|
||||
// TODO
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
* 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.text.TextUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import de.arcus.playmusiclib.PlayMusicManager;
|
||||
import de.arcus.playmusiclib.items.Album;
|
||||
|
||||
/**
|
||||
* Data source for albums
|
||||
*/
|
||||
public class AlbumDataSource extends DataSource<Album> {
|
||||
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";
|
||||
|
||||
private final static String COLUMN_TITLE = "Title";
|
||||
private final static String COLUMN_ARTIST = "Artist";
|
||||
|
||||
private final static String[] COLUMNS_ALL = { COLUMN_ALBUMID, COLUMN_ALBUM,
|
||||
COLUMN_ALBUMARTIST, COLUMN_ALBUM_ARTWORKFILE};
|
||||
|
||||
/**
|
||||
* If this is set the data source will only load offline tracks
|
||||
*/
|
||||
private boolean mOfflineOnly;
|
||||
|
||||
/**
|
||||
* 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 AlbumDataSource(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) {
|
||||
// The new where
|
||||
String newWhere = "LocalCopyType != 300";
|
||||
|
||||
// Loads only offline tracks
|
||||
if (mOfflineOnly)
|
||||
newWhere += " AND LocalCopyPath IS NOT NULL";
|
||||
|
||||
// Search only items which contains the key
|
||||
if (!TextUtils.isEmpty(mSearchKey)) {
|
||||
String searchKey = mSearchKey.replace("'", "''");
|
||||
|
||||
newWhere += " AND (" + COLUMN_ALBUM + " LIKE '%" + searchKey + "%'";
|
||||
newWhere += " OR " + COLUMN_TITLE + " LIKE '%" + searchKey + "%'";
|
||||
newWhere += " OR " + COLUMN_ALBUMARTIST + " LIKE '%" + searchKey + "%'";
|
||||
newWhere += " OR " + COLUMN_ARTIST + " LIKE '%" + searchKey + "%')";
|
||||
}
|
||||
|
||||
// Adds an 'and' if needed
|
||||
if (!TextUtils.isEmpty(where)) where = "(" + where + ") AND ";
|
||||
|
||||
where += newWhere;
|
||||
|
||||
return where;
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Gets the data object from a data row
|
||||
* @param cursor Data row
|
||||
* @return Data object
|
||||
*/
|
||||
protected Album getDataObject(Cursor cursor) {
|
||||
Album instance = new Album(mPlayMusicManager);
|
||||
|
||||
// Read all properties from the data row
|
||||
instance.setAlbumId(cursor.getLong(getColumnsIndex(COLUMNS_ALL, COLUMN_ALBUMID)));
|
||||
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)));
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads an album by Id
|
||||
* @param id The album id
|
||||
* @return Returns the album or null
|
||||
*/
|
||||
public Album getById(long id) {
|
||||
return getItem(TABLE_MUSIC, COLUMNS_ALL, prepareWhere("AlbumID = " + id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of all albums
|
||||
* @return Returns all albums
|
||||
*/
|
||||
public List<Album> getAll() {
|
||||
return getItems(TABLE_MUSIC, COLUMNS_ALL, prepareWhere(""), COLUMN_ALBUM);
|
||||
}
|
||||
}
|
|
@ -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.sqlite.SQLiteDatabase;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import de.arcus.playmusiclib.PlayMusicManager;
|
||||
|
||||
/**
|
||||
* Universal data source
|
||||
*/
|
||||
public abstract class DataSource<T> {
|
||||
/**
|
||||
* The manager
|
||||
*/
|
||||
protected PlayMusicManager mPlayMusicManager;
|
||||
|
||||
/**
|
||||
* Creates a new data source
|
||||
* @param playMusicManager The manager
|
||||
*/
|
||||
public DataSource(PlayMusicManager playMusicManager) {
|
||||
mPlayMusicManager = playMusicManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index of the column
|
||||
* @param columns Table header
|
||||
* @param column Column
|
||||
* @return Index
|
||||
*/
|
||||
protected static int getColumnsIndex(String[] columns, String column) {
|
||||
for (int n=0; n<columns.length; n++) {
|
||||
// Found column
|
||||
if (columns[n].equals(column))
|
||||
return n;
|
||||
}
|
||||
|
||||
// Not found
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected abstract T getDataObject(Cursor cursor);
|
||||
|
||||
/**
|
||||
* Loads all items from the database
|
||||
* @param table The table
|
||||
* @param columns All columns
|
||||
* @param where The where-command
|
||||
* @return Returns a list with all items
|
||||
*/
|
||||
protected List<T> getItems(String table, String[] columns, String where) {
|
||||
return getItems(table, columns, where, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all items from the database
|
||||
* @param table The table
|
||||
* @param columns All columns
|
||||
* @param where The where-command
|
||||
* @param orderBy Order
|
||||
* @return Returns a list with all items
|
||||
*/
|
||||
protected List<T> getItems(String table, String[] columns, String where, String orderBy) {
|
||||
// No connection; abort
|
||||
if (!mPlayMusicManager.getDatabase().isOpen()) return null;
|
||||
|
||||
// Creates the list
|
||||
List<T> items = new LinkedList<>();
|
||||
|
||||
try {
|
||||
// Gets the first data row
|
||||
Cursor cursor = mPlayMusicManager.getDatabase().query(table, columns, where, null, null, null, orderBy);
|
||||
|
||||
// SQL error
|
||||
if (cursor == null) return null;
|
||||
|
||||
cursor.moveToFirst();
|
||||
|
||||
int pos = 0;
|
||||
// Reads the table
|
||||
while (!cursor.isAfterLast()) {
|
||||
pos ++;
|
||||
|
||||
// Adds the object
|
||||
items.add(getDataObject(cursor));
|
||||
|
||||
// Go to next data row
|
||||
cursor.moveToNext();
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads one item from the database
|
||||
* @param table The table
|
||||
* @param columns All columns
|
||||
* @param where The where-command
|
||||
* @return Returns the item
|
||||
*/
|
||||
protected T getItem(String table, String[] columns, String where) {
|
||||
return getItem(table, columns, where, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads one item from the database
|
||||
* @param table The table
|
||||
* @param columns All columns
|
||||
* @param where The where-command
|
||||
* @param orderBy Order
|
||||
* @return Returns the item
|
||||
*/
|
||||
protected T getItem(String table, String[] columns, String where, String orderBy) {
|
||||
// Loads the list
|
||||
List<T> items = getItems(table, columns, where, orderBy);
|
||||
|
||||
// Gets the first item
|
||||
if (items.size() > 0)
|
||||
return items.get(0);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,210 @@
|
|||
/*
|
||||
* 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.text.TextUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import de.arcus.playmusiclib.PlayMusicManager;
|
||||
import de.arcus.playmusiclib.items.Album;
|
||||
import de.arcus.playmusiclib.items.MusicTrack;
|
||||
import de.arcus.playmusiclib.items.Playlist;
|
||||
|
||||
/**
|
||||
* Data source for music tracks
|
||||
*/
|
||||
public class MusicTrackDataSource extends DataSource<MusicTrack> {
|
||||
// Tables
|
||||
private final static String TABLE_MUSIC = "MUSIC";
|
||||
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_ARTWORKFILE = "(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 };
|
||||
|
||||
/**
|
||||
* If this is set the data source will only load offline tracks
|
||||
*/
|
||||
private boolean mOfflineOnly;
|
||||
|
||||
/**
|
||||
* 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 MusicTrackDataSource(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) {
|
||||
// The new where
|
||||
String newWhere = "LocalCopyType != 300";
|
||||
|
||||
// Loads only offline tracks
|
||||
if (mOfflineOnly)
|
||||
newWhere += " AND LocalCopyPath IS NOT NULL";
|
||||
|
||||
// Search only items which contains the key
|
||||
if (!TextUtils.isEmpty(mSearchKey)) {
|
||||
String searchKey = mSearchKey.replace("'", "''");
|
||||
|
||||
newWhere += " AND (" + COLUMN_ALBUM + " LIKE '%" + searchKey + "%'";
|
||||
newWhere += " OR " + COLUMN_TITLE + " LIKE '%" + searchKey + "%'";
|
||||
newWhere += " OR " + COLUMN_ALBUMARTIST + " LIKE '%" + searchKey + "%'";
|
||||
newWhere += " OR " + COLUMN_ARTIST + " LIKE '%" + searchKey + "%')";
|
||||
}
|
||||
|
||||
// Adds an 'and' if needed
|
||||
if (!TextUtils.isEmpty(where)) where = "(" + where + ") AND ";
|
||||
|
||||
where += newWhere;
|
||||
|
||||
return where;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Gets the data object from a data row
|
||||
* @param cursor Data row
|
||||
* @return Data object
|
||||
*/
|
||||
protected MusicTrack getDataObject(Cursor cursor) {
|
||||
MusicTrack instance = new MusicTrack(mPlayMusicManager);
|
||||
|
||||
// Read all properties from the data row
|
||||
instance.setId(cursor.getLong(getColumnsIndex(COLUMNS_ALL, COLUMN_ID)));
|
||||
instance.setSize(cursor.getLong(getColumnsIndex(COLUMNS_ALL, COLUMN_SIZE)));
|
||||
instance.setLocalCopyPath(cursor.getString(getColumnsIndex(COLUMNS_ALL, COLUMN_LOCALCOPYPATH)));
|
||||
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.setArtist(cursor.getString(getColumnsIndex(COLUMNS_ALL, COLUMN_ARTIST)));
|
||||
instance.setAlbumArtist(cursor.getString(getColumnsIndex(COLUMNS_ALL, COLUMN_ALBUMARTIST)));
|
||||
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.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.setCpData(cursor.getBlob(getColumnsIndex(COLUMNS_ALL, COLUMN_CPDATA)));
|
||||
instance.setArtworkFile(cursor.getString(getColumnsIndex(COLUMNS_ALL, COLUMN_ARTWORKFILE)));
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a track by Id
|
||||
* @param id The track id
|
||||
* @return Returns the music track or null
|
||||
*/
|
||||
public MusicTrack getById(long id) {
|
||||
return getItem(TABLE_MUSIC, COLUMNS_ALL, prepareWhere("Id = " + id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of tracks by an album
|
||||
* @param album The album
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of tracks by an playlist
|
||||
* @param playlist The playlist
|
||||
* @return Returns the track list
|
||||
*/
|
||||
public List<MusicTrack> getByPlaylist(Playlist playlist) {
|
||||
return getItems(TABLE_MUSIC, COLUMNS_ALL, prepareWhere("ListId = " + playlist.getId()), "LISTITEMS.ID");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* 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.exceptions;
|
||||
|
||||
/**
|
||||
* Exception will thrown if the database could not be copied or opened
|
||||
*/
|
||||
public class CouldNotOpenDatabase extends Exception {
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* 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.exceptions;
|
||||
|
||||
/**
|
||||
* Exception will thrown if the app dosen't have super user permissions
|
||||
*/
|
||||
public class NoSuperUserException extends Exception {
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* 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.exceptions;
|
||||
|
||||
/**
|
||||
* Exception will thrown if PlayMusic is not installed
|
||||
*/
|
||||
public class PlayMusicNotFound extends Exception {
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* 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 Album
|
||||
*/
|
||||
public class Album extends MusicList {
|
||||
// Variables
|
||||
private long mAlbumId;
|
||||
private String mAlbum, mAlbumArtist, mArtworkFile;
|
||||
|
||||
private String mArtworkPath;
|
||||
|
||||
/**
|
||||
* Creates a data item
|
||||
* @param playMusicManager The manager
|
||||
*/
|
||||
public Album(PlayMusicManager playMusicManager) {
|
||||
super(playMusicManager);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the album id
|
||||
*/
|
||||
public long getAlbumId() {
|
||||
return mAlbumId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param albumId Sets the album id
|
||||
*/
|
||||
public void setAlbumId(long albumId) {
|
||||
this.mAlbumId = albumId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the name of the album
|
||||
*/
|
||||
public String getAlbum() {
|
||||
return mAlbum;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param album Sets the name of the album
|
||||
*/
|
||||
public void setAlbum(String album) {
|
||||
this.mAlbum = album;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return gets the album artist
|
||||
*/
|
||||
public String getAlbumArtist() {
|
||||
return mAlbumArtist;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param albumArtist Sets the album artist
|
||||
*/
|
||||
public void setAlbumArtist(String albumArtist) {
|
||||
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
|
||||
*/
|
||||
public String getTitle() {
|
||||
return getAlbum();
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Gets the album artist
|
||||
*/
|
||||
public String getDescription() {
|
||||
return getAlbumArtist();
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Loads all tracks from this album
|
||||
*/
|
||||
protected void fetchTrackList() {
|
||||
// Music track data source
|
||||
MusicTrackDataSource musicTrackDataSource = new MusicTrackDataSource(mPlayMusicManager);
|
||||
|
||||
// Load the track list
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* 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 android.content.Context;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import de.arcus.playmusiclib.PlayMusicManager;
|
||||
|
||||
/**
|
||||
* List of {@link de.arcus.playmusiclib.items.MusicTrack MusicTracks}.
|
||||
* Eg. albums, playlists, etc...
|
||||
*/
|
||||
public abstract class MusicList {
|
||||
/**
|
||||
* The manager
|
||||
*/
|
||||
protected PlayMusicManager mPlayMusicManager;
|
||||
|
||||
/**
|
||||
* Creates a data item
|
||||
* @param playMusicManager The manager
|
||||
*/
|
||||
public MusicList(PlayMusicManager playMusicManager) {
|
||||
mPlayMusicManager = playMusicManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* List of all loaded tracks in this list.
|
||||
* This list will only be loaded if {@link #getMusicTrackList()} was called
|
||||
*/
|
||||
protected List<MusicTrack> mMusicTrackList;
|
||||
|
||||
public List<MusicTrack> getMusicTrackList() {
|
||||
// List is requested for the fist time
|
||||
if (mMusicTrackList == null)
|
||||
fetchTrackList();
|
||||
|
||||
// Return list
|
||||
return mMusicTrackList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @return Title
|
||||
*/
|
||||
public abstract String getTitle();
|
||||
|
||||
/**
|
||||
* Gets the description of the list.
|
||||
* Eg. the artist of the album
|
||||
* @return Description
|
||||
*/
|
||||
public abstract String getDescription();
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getTitle();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,350 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* A single music track from Play Music
|
||||
*/
|
||||
public class MusicTrack {
|
||||
// Variables
|
||||
private long mId, mSize, mTrackNumber, mDiscNumber, mAlbumId, mLocalCopyType, mLocalCopyStorageType, mDuration;
|
||||
private String mTitle, mArtist, mAlbum, mAlbumArtist, mLocalCopyPath, mGenre, mYear, mClientId, mSourceId, mArtworkFile;
|
||||
private byte[] mCpData;
|
||||
|
||||
private String mSourceFile;
|
||||
private String mArtworkPath;
|
||||
|
||||
/**
|
||||
* The manager
|
||||
*/
|
||||
private PlayMusicManager mPlayMusicManager;
|
||||
|
||||
/**
|
||||
* Creates a data item
|
||||
* @param playMusicManager The manager
|
||||
*/
|
||||
public MusicTrack(PlayMusicManager playMusicManager) {
|
||||
mPlayMusicManager = playMusicManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the track is
|
||||
*/
|
||||
public long getId() {
|
||||
return mId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id Sets the track id
|
||||
*/
|
||||
public void setId(long id) {
|
||||
this.mId = mId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the file size
|
||||
*/
|
||||
public long getSize() {
|
||||
return mSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param size Sets the file size
|
||||
*/
|
||||
public void setSize(long size) {
|
||||
this.mSize = size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Get the track number in the album
|
||||
*/
|
||||
public long getTrackNumber() {
|
||||
return mTrackNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param trackNumber Sets the track number in the album
|
||||
*/
|
||||
public void setTrackNumber(long trackNumber) {
|
||||
this.mTrackNumber = trackNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the disc number in the album
|
||||
*/
|
||||
public long getDiscNumber() {
|
||||
return mDiscNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param discNumber Sets the disc number in the album
|
||||
*/
|
||||
public void setDiscNumber(long discNumber) {
|
||||
this.mDiscNumber = discNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the duration of the track
|
||||
*/
|
||||
public long getDuration() {
|
||||
return mDuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param duration Sets the duration of the track
|
||||
*/
|
||||
public void setDuration(long duration) {
|
||||
this.mDuration = duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the local copy type
|
||||
*/
|
||||
public long getLocalCopyType() {
|
||||
return mLocalCopyType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param localCopyType Sets the local copy type
|
||||
*/
|
||||
public void setLocalCopyType(long localCopyType) {
|
||||
this.mLocalCopyType = localCopyType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the local copy storage type
|
||||
*/
|
||||
public long getLocalCopyStorageType() {
|
||||
return mLocalCopyStorageType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param localCopyStorageType Sets the local copy storage type
|
||||
*/
|
||||
public void setLocalCopyStorageType(long localCopyStorageType) {
|
||||
this.mLocalCopyStorageType = localCopyStorageType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the release year of the song
|
||||
*/
|
||||
public String getYear() {
|
||||
return mYear;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param year Sets the release year of the song
|
||||
*/
|
||||
public void setYear(String year) {
|
||||
this.mYear = year;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the album id
|
||||
*/
|
||||
public long getAlbumId() {
|
||||
return mAlbumId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param albumId Sets the album id
|
||||
*/
|
||||
public void setAlbumId(long albumId) {
|
||||
this.mAlbumId = albumId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the track title
|
||||
*/
|
||||
public String getTitle() {
|
||||
return mTitle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param title Sets the track title
|
||||
*/
|
||||
public void setTitle(String title) {
|
||||
this.mTitle = title;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the artist
|
||||
*/
|
||||
public String getArtist() {
|
||||
return mArtist;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param artist Sets the artist
|
||||
*/
|
||||
public void setArtist(String artist) {
|
||||
this.mArtist = artist;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the album artist
|
||||
*/
|
||||
public String getAlbumArtist() {
|
||||
return mAlbumArtist;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param albumArtist Sets the album artist
|
||||
*/
|
||||
public void setAlbumArtist(String albumArtist) {
|
||||
this.mAlbumArtist = albumArtist;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the album title
|
||||
*/
|
||||
public String getAlbum() {
|
||||
return mAlbum;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param album Sets the album title
|
||||
*/
|
||||
public void setAlbum(String album) {
|
||||
this.mAlbum = album;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the local copy path
|
||||
*/
|
||||
public String getLocalCopyPath() {
|
||||
return mLocalCopyPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param localCopyPath Sets the local copy path
|
||||
*/
|
||||
public void setLocalCopyPath(String localCopyPath) {
|
||||
this.mLocalCopyPath = localCopyPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the genre
|
||||
*/
|
||||
public String getGenre() {
|
||||
return mGenre;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param genre Sets the genre
|
||||
*/
|
||||
public void setGenre(String genre) {
|
||||
this.mGenre = genre;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the client id
|
||||
*/
|
||||
public String getClientId() {
|
||||
return mClientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clientId Sets the client id
|
||||
*/
|
||||
public void setClientId(String clientId) {
|
||||
this.mClientId = clientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the source id
|
||||
*/
|
||||
public String getSourceId() {
|
||||
return mSourceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param sourceId Sets the source id
|
||||
*/
|
||||
public void setSourceId(String sourceId) {
|
||||
this.mSourceId = sourceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the AllAccess decryption key
|
||||
*/
|
||||
public byte[] getCpData() {
|
||||
return mCpData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param cpData Sets the AllAccess decryption key
|
||||
*/
|
||||
public void setCpData(byte[] cpData) {
|
||||
this.mCpData = cpData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the artwork file name
|
||||
*/
|
||||
public String getArtworkFile() {
|
||||
return mArtworkFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param artworkFile Sets the artwork file name
|
||||
*/
|
||||
public void setArtworkFile(String artworkFile) {
|
||||
this.mArtworkFile = artworkFile;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Returns the source file path
|
||||
*/
|
||||
public String getSourceFile() {
|
||||
// Search for the source file
|
||||
if (mSourceFile == null)
|
||||
mSourceFile = mPlayMusicManager.getMusicFile(mLocalCopyPath);
|
||||
return mSourceFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the full album artwork path
|
||||
*/
|
||||
public String getArtworkPath() {
|
||||
// Search for the artwork path
|
||||
if (mArtworkPath == null)
|
||||
mArtworkPath = mPlayMusicManager.getArtworkPath(mArtworkFile);
|
||||
return mArtworkPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns if this file is encoded from AllAccess
|
||||
*/
|
||||
public boolean isEncoded() {
|
||||
return (mCpData != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return mTitle;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,174 @@
|
|||
/*
|
||||
* 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.R;
|
||||
import de.arcus.playmusiclib.datasources.MusicTrackDataSource;
|
||||
|
||||
/**
|
||||
* Created by david on 24.01.15.
|
||||
*/
|
||||
public class Playlist extends MusicList {
|
||||
// Variables
|
||||
private long mId, mListType;
|
||||
private String mName;
|
||||
private String mOwnerName;
|
||||
private String mArtworkFile;
|
||||
|
||||
private final static long TYPE_QUEUE = 10;
|
||||
private final static long TYPE_RADIO = 50;
|
||||
|
||||
private String mArtworkPath;
|
||||
|
||||
/**
|
||||
* Creates a data item
|
||||
* @param playMusicManager The manager
|
||||
*/
|
||||
public Playlist(PlayMusicManager playMusicManager) {
|
||||
super(playMusicManager);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the playlist id
|
||||
*/
|
||||
public long getId() {
|
||||
return mId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id Sets the playlist id
|
||||
*/
|
||||
public void setId(long id) {
|
||||
this.mId = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the playlist type
|
||||
*/
|
||||
long getListType() {
|
||||
return mListType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param listType Sets the playlist type
|
||||
*/
|
||||
public void setListType(long listType) {
|
||||
this.mListType = listType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the playlist name
|
||||
*/
|
||||
public String getName() {
|
||||
return mName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name Sets the name of the playlist
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.mName = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the name of the playlist owner
|
||||
*/
|
||||
public String getOwnerName() {
|
||||
return mOwnerName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ownerName Sets the name of the playlist owner
|
||||
*/
|
||||
public void setOwnerName(String ownerName) {
|
||||
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
|
||||
*/
|
||||
public String getTitle() {
|
||||
// Play queue
|
||||
if (getListType() == TYPE_QUEUE) {
|
||||
return mPlayMusicManager.getContext().getString(R.string.music_playlist_queue);
|
||||
}
|
||||
|
||||
return getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Gets the playlist name
|
||||
*/
|
||||
public String getDescription() {
|
||||
// Play queue
|
||||
if (getListType() == TYPE_QUEUE) {
|
||||
return mPlayMusicManager.getContext().getString(R.string.music_playlist_queue_description);
|
||||
}
|
||||
|
||||
// Radio
|
||||
if (getListType() == TYPE_RADIO) {
|
||||
return mPlayMusicManager.getContext().getString(R.string.music_playlist_radio);
|
||||
}
|
||||
|
||||
return getOwnerName();
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Loads all tracks from this playlist
|
||||
*/
|
||||
protected void fetchTrackList() {
|
||||
// Music track data source
|
||||
MusicTrackDataSource musicTrackDataSource = new MusicTrackDataSource(mPlayMusicManager);
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
28
playmusiclib/src/main/res/values-de/strings.xml
Normal file
28
playmusiclib/src/main/res/values-de/strings.xml
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<string name="music_playlist_radio">Radiosender</string>
|
||||
<string name="music_playlist_queue_description">Zuletzt angehört</string>
|
||||
<string name="music_playlist_queue">Wiedergabeliste</string>
|
||||
</resources>
|
28
playmusiclib/src/main/res/values/strings.xml
Normal file
28
playmusiclib/src/main/res/values/strings.xml
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<string name="music_playlist_queue">Play queue</string>
|
||||
<string name="music_playlist_queue_description">Recently played</string>
|
||||
<string name="music_playlist_radio">Radio</string>
|
||||
</resources>
|
|
@ -22,4 +22,4 @@
|
|||
|
||||
|
||||
|
||||
include ':app', ':framework'
|
||||
include ':app', ':framework', ':playmusiclib'
|
||||
|
|
Loading…
Reference in a new issue