From c69779ca1c1ba11da80765f6c5545e5a30f6fd4f Mon Sep 17 00:00:00 2001 From: Scott Jackson Date: Tue, 11 Oct 2016 19:46:01 -0700 Subject: Fixes #746: Add support for Play Title by Artist voice commands --- .../dsub/activity/SubsonicFragmentActivity.java | 6 +- .../dsub/activity/VoiceQueryReceiverActivity.java | 16 ++++ .../daneren2005/dsub/fragments/SearchFragment.java | 85 ++++++++++++++++++---- 3 files changed, 90 insertions(+), 17 deletions(-) (limited to 'app/src/main/java/github') diff --git a/app/src/main/java/github/daneren2005/dsub/activity/SubsonicFragmentActivity.java b/app/src/main/java/github/daneren2005/dsub/activity/SubsonicFragmentActivity.java index c7190046..e37c6d49 100644 --- a/app/src/main/java/github/daneren2005/dsub/activity/SubsonicFragmentActivity.java +++ b/app/src/main/java/github/daneren2005/dsub/activity/SubsonicFragmentActivity.java @@ -30,6 +30,7 @@ import android.content.res.TypedArray; import android.os.Bundle; import android.os.Handler; import android.preference.PreferenceManager; +import android.provider.MediaStore; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.support.v7.app.AlertDialog; @@ -402,9 +403,12 @@ public class SubsonicFragmentActivity extends SubsonicActivity implements Downlo if(currentFragment instanceof SearchFragment) { String query = intent.getStringExtra(Constants.INTENT_EXTRA_NAME_QUERY); boolean autoplay = intent.getBooleanExtra(Constants.INTENT_EXTRA_NAME_AUTOPLAY, false); + String artist = intent.getStringExtra(MediaStore.EXTRA_MEDIA_ARTIST); + String album = intent.getStringExtra(MediaStore.EXTRA_MEDIA_ALBUM); + String title = intent.getStringExtra(MediaStore.EXTRA_MEDIA_TITLE); if (query != null) { - ((SearchFragment)currentFragment).search(query, autoplay); + ((SearchFragment)currentFragment).search(query, autoplay, artist, album, title); } getIntent().removeExtra(Constants.INTENT_EXTRA_NAME_QUERY); } else { diff --git a/app/src/main/java/github/daneren2005/dsub/activity/VoiceQueryReceiverActivity.java b/app/src/main/java/github/daneren2005/dsub/activity/VoiceQueryReceiverActivity.java index c0effe27..641b118f 100644 --- a/app/src/main/java/github/daneren2005/dsub/activity/VoiceQueryReceiverActivity.java +++ b/app/src/main/java/github/daneren2005/dsub/activity/VoiceQueryReceiverActivity.java @@ -55,6 +55,22 @@ public class VoiceQueryReceiverActivity extends Activity { if(!GMS_SEARCH_ACTION.equals(getIntent().getAction())) { intent.putExtra(Constants.INTENT_EXTRA_NAME_AUTOPLAY, true); } + + String artist = getIntent().getStringExtra(MediaStore.EXTRA_MEDIA_ARTIST); + if(artist != null) { + intent.putExtra(MediaStore.EXTRA_MEDIA_ARTIST, artist); + } + + String album = getIntent().getStringExtra(MediaStore.EXTRA_MEDIA_ALBUM); + if(album != null) { + intent.putExtra(MediaStore.EXTRA_MEDIA_ALBUM, album); + } + + String title = getIntent().getStringExtra(MediaStore.EXTRA_MEDIA_TITLE); + if(title != null) { + intent.putExtra(MediaStore.EXTRA_MEDIA_TITLE, title); + } + intent.putExtra(MediaStore.EXTRA_MEDIA_FOCUS, getIntent().getStringExtra(MediaStore.EXTRA_MEDIA_FOCUS)); intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP); Util.startActivityWithoutTransition(VoiceQueryReceiverActivity.this, intent); diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/SearchFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/SearchFragment.java index eed714af..dfff45cd 100644 --- a/app/src/main/java/github/daneren2005/dsub/fragments/SearchFragment.java +++ b/app/src/main/java/github/daneren2005/dsub/fragments/SearchFragment.java @@ -3,7 +3,10 @@ package github.daneren2005.dsub.fragments; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.TreeMap; import android.content.Intent; import android.os.Bundle; @@ -26,6 +29,7 @@ import github.daneren2005.dsub.adapter.SearchAdapter; import github.daneren2005.dsub.adapter.SectionAdapter; import github.daneren2005.dsub.domain.Artist; import github.daneren2005.dsub.domain.MusicDirectory; +import github.daneren2005.dsub.domain.MusicDirectory.Entry; import github.daneren2005.dsub.domain.SearchCritera; import github.daneren2005.dsub.domain.SearchResult; import github.daneren2005.dsub.service.MusicService; @@ -132,7 +136,7 @@ public class SearchFragment extends SubsonicFragment implements SectionAdapter.O @Override public void onCreateContextMenu(Menu menu, MenuInflater menuInflater, UpdateView updateView, Serializable item) { onCreateContextMenuSupport(menu, menuInflater, updateView, item); - if(item instanceof MusicDirectory.Entry && !((MusicDirectory.Entry) item).isVideo() && !Util.isOffline(context)) { + if(item instanceof Entry && !((Entry) item).isVideo() && !Util.isOffline(context)) { menu.removeItem(R.id.song_menu_remove_playlist); } recreateContextMenu(menu); @@ -152,8 +156,8 @@ public class SearchFragment extends SubsonicFragment implements SectionAdapter.O public void onItemClicked(UpdateView updateView, Serializable item) { if (item instanceof Artist) { onArtistSelected((Artist) item, false); - } else if (item instanceof MusicDirectory.Entry) { - MusicDirectory.Entry entry = (MusicDirectory.Entry) item; + } else if (item instanceof Entry) { + Entry entry = (Entry) item; if (entry.isDirectory()) { onAlbumSelected(entry, false); } else if (entry.isVideo()) { @@ -165,12 +169,12 @@ public class SearchFragment extends SubsonicFragment implements SectionAdapter.O } @Override - protected List getSelectedEntries() { + protected List getSelectedEntries() { List selected = adapter.getSelected(); - List selectedMedia = new ArrayList<>(); + List selectedMedia = new ArrayList<>(); for(Serializable ser: selected) { - if(ser instanceof MusicDirectory.Entry) { - selectedMedia.add((MusicDirectory.Entry) ser); + if(ser instanceof Entry) { + selectedMedia.add((Entry) ser); } } @@ -182,7 +186,7 @@ public class SearchFragment extends SubsonicFragment implements SectionAdapter.O return true; } - public void search(final String query, final boolean autoplay) { + public void search(final String query, final boolean autoplay, final String artist, final String album, final String title) { if(skipSearch) { skipSearch = false; return; @@ -202,7 +206,7 @@ public class SearchFragment extends SubsonicFragment implements SectionAdapter.O searchResult = result; recyclerView.setAdapter(adapter = new SearchAdapter(context, searchResult, getImageLoader(), largeAlbums, SearchFragment.this)); if (autoplay) { - autoplay(query); + autoplay(query, artist, album, title); } } @@ -232,7 +236,7 @@ public class SearchFragment extends SubsonicFragment implements SectionAdapter.O replaceFragment(fragment); } - private void onAlbumSelected(MusicDirectory.Entry album, boolean autoplay) { + private void onAlbumSelected(Entry album, boolean autoplay) { SubsonicFragment fragment = new SelectDirectoryFragment(); Bundle args = new Bundle(); args.putString(Constants.INTENT_EXTRA_NAME_ID, album.getId()); @@ -245,7 +249,7 @@ public class SearchFragment extends SubsonicFragment implements SectionAdapter.O replaceFragment(fragment); } - private void onSongSelected(MusicDirectory.Entry song, boolean save, boolean append, boolean autoplay, boolean playNext) { + private void onSongSelected(Entry song, boolean save, boolean append, boolean autoplay, boolean playNext) { DownloadService downloadService = getDownloadService(); if (downloadService != null) { if (!append) { @@ -260,7 +264,7 @@ public class SearchFragment extends SubsonicFragment implements SectionAdapter.O } } - private void onVideoSelected(MusicDirectory.Entry entry) { + private void onVideoSelected(Entry entry) { int maxBitrate = Util.getMaxVideoBitrate(context); Intent intent = new Intent(Intent.ACTION_VIEW); @@ -268,6 +272,55 @@ public class SearchFragment extends SubsonicFragment implements SectionAdapter.O startActivity(intent); } + private void autoplay(String query, String artistQuery, String albumQuery, String titleQuery) { + Log.i(TAG, "Query: '" + query + "' ( Artist: '" + artistQuery + "', Album: '" + albumQuery + "', Title: '" + titleQuery + "')"); + + if(titleQuery != null && !searchResult.getSongs().isEmpty()) { + titleQuery = titleQuery.toLowerCase(); + + TreeMap tree = new TreeMap<>(); + for(Entry song: searchResult.getSongs()) { + tree.put(Util.getStringDistance(song.getTitle().toLowerCase(), titleQuery), song); + } + + Map.Entry entry = tree.firstEntry(); + if(entry.getKey() <= MIN_CLOSENESS) { + onSongSelected(entry.getValue(), false, false, true, false); + } else { + autoplay(query); + } + } else if(albumQuery != null && !searchResult.getAlbums().isEmpty()) { + albumQuery = albumQuery.toLowerCase(); + + TreeMap tree = new TreeMap<>(); + for(Entry album: searchResult.getAlbums()) { + tree.put(Util.getStringDistance(album.getTitle().toLowerCase(), albumQuery), album); + } + + Map.Entry entry = tree.firstEntry(); + if(entry.getKey() <= MIN_CLOSENESS) { + onAlbumSelected(entry.getValue(), true); + } else { + autoplay(query); + } + } else if(artistQuery != null && !searchResult.getArtists().isEmpty()) { + artistQuery = artistQuery.toLowerCase(); + + TreeMap tree = new TreeMap<>(); + for(Artist artist: searchResult.getArtists()) { + tree.put(Util.getStringDistance(artist.getName().toLowerCase(), artistQuery), artist); + } + Map.Entry entry = tree.firstEntry(); + if(entry.getKey() <= MIN_CLOSENESS) { + onArtistSelected(entry.getValue(), true); + } else { + autoplay(query); + } + } else { + autoplay(query); + } + } + private void autoplay(String query) { query = query.toLowerCase(); @@ -276,12 +329,12 @@ public class SearchFragment extends SubsonicFragment implements SectionAdapter.O artist = searchResult.getArtists().get(0); artist.setCloseness(Util.getStringDistance(artist.getName().toLowerCase(), query)); } - MusicDirectory.Entry album = null; + Entry album = null; if(!searchResult.getAlbums().isEmpty()) { album = searchResult.getAlbums().get(0); album.setCloseness(Util.getStringDistance(album.getTitle().toLowerCase(), query)); } - MusicDirectory.Entry song = null; + Entry song = null; if(!searchResult.getSongs().isEmpty()) { song = searchResult.getSongs().get(0); song.setCloseness(Util.getStringDistance(song.getTitle().toLowerCase(), query)); @@ -289,10 +342,10 @@ public class SearchFragment extends SubsonicFragment implements SectionAdapter.O if(artist != null && (artist.getCloseness() <= MIN_CLOSENESS || (album == null || artist.getCloseness() <= album.getCloseness()) && - (song == null || artist.getCloseness() <= song.getCloseness()))) { + (song == null || artist.getCloseness() <= song.getCloseness()))) { onArtistSelected(artist, true); } else if(album != null && (album.getCloseness() <= MIN_CLOSENESS || - song == null || album.getCloseness() <= song.getCloseness())) { + song == null || album.getCloseness() <= song.getCloseness())) { onAlbumSelected(album, true); } else if(song != null) { onSongSelected(song, false, false, true, false); -- cgit v1.2.3