Added basic support for App Shortcuts

Shuffle All, Top Tracks, and Last added. Still need to fix icons and add dynamic shortcuts for playlists
This commit is contained in:
Adrian Campos 2017-03-08 23:44:27 -08:00 committed by Karim Abou Zeid
commit 33ff49de0f
7 changed files with 232 additions and 0 deletions

View file

@ -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)
}
}
}
}

View file

@ -29,6 +29,8 @@
<category android:name="android.intent.category.APP_MUSIC" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data android:name="android.app.shortcuts"
android:resource="@xml/launcher_shortcuts" />
<intent-filter>
<action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" />
@ -173,6 +175,10 @@
<activity
android:name=".ui.activities.bugreport.BugReportActivity"
android:label="@string/report_an_issue" />
<activity
android:name=".appshortcuts.AppShortcutLauncherActivity"
android:exported="true"
/>
</application>
</manifest>

View file

@ -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<Song> 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
}
}

View file

@ -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<Song> 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<Song> 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) {

View file

@ -39,4 +39,6 @@
white-space: pre-wrap;
}
</string>
<string name="id_shortcuttype">com.kabouzeid.gramophone.appshortcuts.ShortcutType</string>
</resources>

View file

@ -275,4 +275,16 @@
<string name="copied_device_info_to_clipboard">Copied device info to clipboard.</string>
<string name="your_account_data_is_only_used_for_authentication">Your account data is only used for authentication.</string>
<string name="you_will_be_forwarded_to_the_issue_tracker_website">You will be forwarded to the issue tracker website.</string>
<!-- App Shortcuts -->
<string name="appshortcut_shuffleall_long">@string/action_shuffle_all</string>
<string name="appshortcut_shuffleall_short">Shuffle</string>
<string name="appshortcut_toptracks_long">@string/my_top_tracks</string>
<string name="appshortcut_toptracks_short">Top Tracks</string>
<string name="appshortcut_lastadded_long">@string/last_added</string>
<string name="appshortcut_lastadded_short">@string/last_added</string>
<string name="error_launching_shortcut">Error launching shortcut.</string>
</resources>

View file

@ -0,0 +1,55 @@
<shortcuts
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
tools:targetApi="25">
<shortcut
android:shortcutId="shuffle_all"
android:enabled="true"
android:icon="@drawable/ic_shuffle_white_24dp"
android:shortcutShortLabel="@string/appshortcut_shuffleall_short"
android:shortcutLongLabel="@string/appshortcut_shuffleall_long">
<intent
android:action="android.intent.action.VIEW"
android:targetClass="com.kabouzeid.gramophone.appshortcuts.AppShortcutLauncherActivity"
android:targetPackage="${applicationId}">
<extra
android:name="com.kabouzeid.gramophone.appshortcuts.ShortcutType"
android:value="SHUFFLE_ALL" />
</intent>
</shortcut>
<shortcut
android:shortcutId="top_tracks"
android:enabled="true"
android:icon="@drawable/ic_trending_up_white_24dp"
android:shortcutShortLabel="@string/appshortcut_toptracks_short"
android:shortcutLongLabel="@string/appshortcut_toptracks_long"
>
<intent
android:action="android.intent.action.VIEW"
android:targetClass="com.kabouzeid.gramophone.appshortcuts.AppShortcutLauncherActivity"
android:targetPackage="${applicationId}">
<extra
android:name="com.kabouzeid.gramophone.appshortcuts.ShortcutType"
android:value="TOP_TRACKS" />
</intent>
</shortcut>
<shortcut
android:shortcutId="last_added"
android:enabled="true"
android:icon="@drawable/ic_library_add_white_24dp"
android:shortcutShortLabel="@string/appshortcut_lastadded_short"
android:shortcutLongLabel="@string/appshortcut_lastadded_long"
>
<intent
android:action="android.intent.action.VIEW"
android:targetClass="com.kabouzeid.gramophone.appshortcuts.AppShortcutLauncherActivity"
android:targetPackage="${applicationId}">
<extra
android:name="com.kabouzeid.gramophone.appshortcuts.ShortcutType"
android:value="LAST_ADDED" />
</intent>
</shortcut>
</shortcuts>