diff --git a/app/build.gradle b/app/build.gradle
index 9c13bf94..899925b1 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -117,3 +117,37 @@ dependencies {
compile 'com.jakewharton:butterknife:8.5.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1'
}
+
+// Add support for placeholders in resource files.
+// Required so that packagename can be referenced in xml. https://code.google.com/p/android/issues/detail?id=69224#c12
+def replacePlaceholdersInFile(basePath, fileName, placeholders) {
+ def file = new File(basePath, fileName);
+
+ if (!file.exists()) {
+ logger.quiet("Unable to replace placeholders in " + file.toString() + ". File cannot be found.")
+ return;
+ }
+
+ logger.debug("Replacing placeholders in " + file.toString())
+ logger.debug("Placeholders: " + placeholders.toString())
+
+ def content = file.getText('UTF-8')
+
+ placeholders.each { entry ->
+ content = content.replaceAll("\\\$\\{${entry.key}\\}", entry.value)
+ }
+
+ file.write(content, 'UTF-8')
+}
+
+afterEvaluate {
+ android.applicationVariants.all { variant ->
+ variant.outputs.each { output ->
+ output.processResources.doFirst {
+ // prepare placeholder map from manifestPlaceholders including applicationId placeholder
+ def placeholders = variant.mergedFlavor.manifestPlaceholders + [applicationId: variant.applicationId]
+ replacePlaceholdersInFile(resDir, 'xml/launcher_shortcuts.xml', placeholders)
+ }
+ }
+ }
+}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 8579a7ab..78046818 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -29,6 +29,8 @@
+
@@ -173,6 +175,10 @@
+
\ No newline at end of file
diff --git a/app/src/main/java/com/kabouzeid/gramophone/appshortcuts/AppShortcutLauncherActivity.java b/app/src/main/java/com/kabouzeid/gramophone/appshortcuts/AppShortcutLauncherActivity.java
new file mode 100644
index 00000000..372eca9e
--- /dev/null
+++ b/app/src/main/java/com/kabouzeid/gramophone/appshortcuts/AppShortcutLauncherActivity.java
@@ -0,0 +1,99 @@
+package com.kabouzeid.gramophone.appshortcuts;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.widget.Toast;
+
+import com.kabouzeid.gramophone.R;
+import com.kabouzeid.gramophone.loader.LastAddedLoader;
+import com.kabouzeid.gramophone.loader.SongLoader;
+import com.kabouzeid.gramophone.loader.TopAndRecentlyPlayedTracksLoader;
+import com.kabouzeid.gramophone.model.Song;
+import com.kabouzeid.gramophone.ui.activities.MainActivity;
+
+import java.util.ArrayList;
+
+/**
+ * @author Adrian Campos
+ */
+
+public class AppShortcutLauncherActivity extends Activity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ ShortcutType shortcutType = ShortcutType.NONE;
+
+ //Set shortcutType from the intent extras
+ Bundle extras = getIntent().getExtras();
+ if (extras!=null){
+ try {
+ shortcutType = ShortcutType.valueOf(extras.getString(getString(R.string.id_shortcuttype)));
+ } catch (IllegalArgumentException e){ //In the event we're somehow passed an invalid enum string, don't crash.
+ e.printStackTrace();
+ shortcutType = ShortcutType.NONE;
+ }
+ }
+
+ //Perform the action found in the extras
+ switch (shortcutType) {
+ case SHUFFLE_ALL:
+ launchMainActivityWithSongs(PlayMode.SHUFFLE,
+ SongLoader.getAllSongs(getApplicationContext()));
+ break;
+ case TOP_TRACKS:
+ launchMainActivityWithSongs(PlayMode.NORMAL,
+ TopAndRecentlyPlayedTracksLoader.getRecentlyPlayedTracks(getApplicationContext()));
+ break;
+ case LAST_ADDED:
+ launchMainActivityWithSongs(PlayMode.NORMAL,
+ LastAddedLoader.getLastAddedSongs(getApplicationContext()));
+ break;
+ case NONE:
+ shortcutError();
+ break;
+ default:
+ shortcutError();
+ break;
+ }
+
+ finish();
+
+ }
+
+
+ enum PlayMode {NORMAL, SHUFFLE}
+ private void launchMainActivityWithSongs(PlayMode playMode, ArrayList songs){
+ //Create a new intent to launch MainActivity
+ Intent intent = new Intent(this, MainActivity.class);
+ switch (playMode){
+ case NORMAL:
+ intent.setAction(MainActivity.INTENT_ACTION_MEDIA_PLAY);
+ break;
+ case SHUFFLE:
+ intent.setAction(MainActivity.INTENT_ACTION_MEDIA_PLAY_SHUFFLED);
+ break;
+ }
+
+
+ //Create a bundle to store the songs to shuffle through songs
+ Bundle bundle = new Bundle();
+ bundle.putParcelableArrayList(MainActivity.INTENT_EXTRA_SONGS, songs);
+
+ //Put the bundle in the intent
+ intent.putExtras(bundle);
+
+ //Finally, start MainActivity with those extras
+ startActivity(intent);
+ }
+
+ private void shortcutError(){
+ Toast.makeText(getApplicationContext(), R.string.error_launching_shortcut, Toast.LENGTH_LONG).show();
+ }
+
+ public enum ShortcutType {
+ SHUFFLE_ALL, TOP_TRACKS, LAST_ADDED, NONE
+ }
+}
diff --git a/app/src/main/java/com/kabouzeid/gramophone/ui/activities/MainActivity.java b/app/src/main/java/com/kabouzeid/gramophone/ui/activities/MainActivity.java
index 9e219fa9..fe46ea15 100644
--- a/app/src/main/java/com/kabouzeid/gramophone/ui/activities/MainActivity.java
+++ b/app/src/main/java/com/kabouzeid/gramophone/ui/activities/MainActivity.java
@@ -60,6 +60,12 @@ public class MainActivity extends AbsSlidingMusicPanelActivity {
private static final int LIBRARY = 0;
private static final int FOLDERS = 1;
+ public static final String PHONOGRAPH_PACKAGE_NAME = "com.kabouzeid.gramophone";
+ public static final String INTENT_ACTION_MEDIA_PLAY_SHUFFLED = PHONOGRAPH_PACKAGE_NAME + ".intent_action.play_shuffled";
+ public static final String INTENT_ACTION_MEDIA_PLAY = PHONOGRAPH_PACKAGE_NAME + ".intent_action.play";
+ public static final String INTENT_EXTRA_SONGS = PHONOGRAPH_PACKAGE_NAME + ".intent_extra.songs";
+
+
@BindView(R.id.navigation_view)
NavigationView navigationView;
@BindView(R.id.drawer_layout)
@@ -296,6 +302,24 @@ public class MainActivity extends AbsSlidingMusicPanelActivity {
} else {
MusicPlayerRemote.openQueue(songs, 0, true);
}
+
+ } else if (intent.getAction() != null && intent.getAction().equals(MainActivity.INTENT_ACTION_MEDIA_PLAY_SHUFFLED)){
+ //Shuffle songs in extras
+ final ArrayList songs = intent.getExtras().getParcelableArrayList(INTENT_EXTRA_SONGS);
+
+ //Start the songs, setting the shuffle mode to shuffle
+ MusicPlayerRemote.openAndShuffleQueue(songs, true);
+
+ } else if (intent.getAction() != null && intent.getAction().equals(MainActivity.INTENT_ACTION_MEDIA_PLAY)){
+ //Shuffle songs in extras
+ final ArrayList songs = intent.getExtras().getParcelableArrayList(INTENT_EXTRA_SONGS);
+
+ //Start the songs, preserving the user's shuffle mode
+ if (MusicPlayerRemote.getShuffleMode() == MusicService.SHUFFLE_MODE_SHUFFLE) {
+ MusicPlayerRemote.openAndShuffleQueue(songs, true);
+ } else {
+ MusicPlayerRemote.openQueue(songs, 0, true);
+ }
}
if (uri != null && uri.toString().length() > 0) {
diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml
index 417cd4f1..3783fdb5 100644
--- a/app/src/main/res/values/donottranslate.xml
+++ b/app/src/main/res/values/donottranslate.xml
@@ -39,4 +39,6 @@
white-space: pre-wrap;
}
+
+ com.kabouzeid.gramophone.appshortcuts.ShortcutType
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 2160388e..b550ce35 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -275,4 +275,16 @@
Copied device info to clipboard.
Your account data is only used for authentication.
You will be forwarded to the issue tracker website.
+
+
+ @string/action_shuffle_all
+ Shuffle
+
+ @string/my_top_tracks
+ Top Tracks
+
+ @string/last_added
+ @string/last_added
+
+ Error launching shortcut.
diff --git a/app/src/main/res/xml/launcher_shortcuts.xml b/app/src/main/res/xml/launcher_shortcuts.xml
new file mode 100644
index 00000000..598fd3df
--- /dev/null
+++ b/app/src/main/res/xml/launcher_shortcuts.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file