Merge pull request #2258 from MeirSD/develop

Enable support for Android Auto with support for OnPlayFromSearch
This commit is contained in:
Martin Fietz 2017-04-11 07:43:19 +02:00 committed by GitHub
commit 7da9e8876b
7 changed files with 163 additions and 3 deletions

View File

@ -37,6 +37,8 @@
android:backupAgent=".core.backup.OpmlBackupAgent"
android:restoreAnyVersion="true"
android:logo="@drawable/ic_launcher">
<meta-data android:name="com.google.android.gms.car.notification.SmallIcon"
android:resource="@drawable/ic_notification" />
<meta-data
android:name="com.google.android.backup.api_key"
android:value="AEdPqrEAAAAI3a05VToCTlqBymJrbFGaKQMvF-bBAuLsOdavBA"/>
@ -51,6 +53,13 @@
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name=
"android.media.action.MEDIA_PLAY_FROM_SEARCH" />
<category android:name=
"android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".activity.MainActivity"
@ -365,6 +374,10 @@
<meta-data
android:name="de.danoeh.antennapod.core.glide.ApGlideModule"
android:value="GlideModule" />
<meta-data
android:name="com.google.android.gms.car.application"
android:resource="@xml/automotive_app_desc"/>
</application>
</manifest>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<automotiveApp xmlns:android="http://schemas.android.com/apk/res/android">
<uses name="media"/>
</automotiveApp>

View File

@ -15,6 +15,7 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
@ -49,9 +50,11 @@ import de.danoeh.antennapod.core.ClientConfig;
import de.danoeh.antennapod.core.R;
import de.danoeh.antennapod.core.event.MessageEvent;
import de.danoeh.antennapod.core.feed.Chapter;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.feed.MediaType;
import de.danoeh.antennapod.core.feed.SearchResult;
import de.danoeh.antennapod.core.glide.ApGlideSettings;
import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
import de.danoeh.antennapod.core.preferences.SleepTimerPreferences;
@ -60,6 +63,7 @@ import de.danoeh.antennapod.core.receiver.MediaButtonReceiver;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBTasks;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.storage.FeedSearcher;
import de.danoeh.antennapod.core.util.IntList;
import de.danoeh.antennapod.core.util.QueueAccess;
import de.danoeh.antennapod.core.util.playback.ExternalMedia;
@ -363,6 +367,19 @@ public class PlaybackService extends MediaBrowserServiceCompat {
MediaBrowserCompat.MediaItem.FLAG_BROWSABLE);
}
private MediaBrowserCompat.MediaItem createBrowsableMediaItemForFeed(Feed feed) {
MediaDescriptionCompat description = new MediaDescriptionCompat.Builder()
.setMediaId("FeedId:" + Long.toString(feed.getId()))
.setTitle(feed.getTitle())
.setDescription(feed.getDescription())
.setIconUri(Uri.parse(feed.getImageLocation()))
.setSubtitle(feed.getCustomTitle())
.setMediaUri(Uri.parse(feed.getLink()))
.build();
return new MediaBrowserCompat.MediaItem(description,
MediaBrowserCompat.MediaItem.FLAG_BROWSABLE);
}
@Override
public void onLoadChildren(@NonNull String parentId,
@NonNull Result<List<MediaBrowserCompat.MediaItem>> result) {
@ -371,6 +388,10 @@ public class PlaybackService extends MediaBrowserServiceCompat {
if (parentId.equals(getResources().getString(R.string.app_name))) {
// Root List
mediaItems.add(createBrowsableMediaItemForRoot());
List<Feed> feeds = DBReader.getFeedList();
for (Feed feed: feeds) {
mediaItems.add(createBrowsableMediaItemForFeed(feed));
}
} else if (parentId.equals(getResources().getString(R.string.queue_label))){
// Child List
try {
@ -380,6 +401,14 @@ public class PlaybackService extends MediaBrowserServiceCompat {
} catch (InterruptedException e) {
e.printStackTrace();
}
} else if (parentId.startsWith("FeedId:")) {
Long feedId = Long.parseLong(parentId.split(":")[1]);
List<FeedItem> feedItems = DBReader.getFeedItemList(DBReader.getFeed(feedId));
for (FeedItem feedItem: feedItems) {
if(feedItem.getMedia() != null && feedItem.getMedia().getMediaItem() != null) {
mediaItems.add(feedItem.getMedia().getMediaItem());
}
}
}
result.sendResult(mediaItems);
}
@ -1635,8 +1664,22 @@ public class PlaybackService extends MediaBrowserServiceCompat {
@Override
public void onPlayFromSearch (String query, Bundle extras) {
//Until we parse the query just play from queue
Log.d(TAG, "onPlayFromSearch query=" + query + " extras=" + extras.toString());
List<SearchResult> results = FeedSearcher.performSearch(getBaseContext(),query,0);
for( SearchResult result : results) {
try {
FeedMedia p = ((FeedItem)(result.getComponent())).getMedia();
mediaPlayer.playMediaObject(p, !p.localFileAvailable(), true, true);
return;
} catch (Exception e) {
Log.d(TAG, e.getMessage());
e.printStackTrace();
continue;
}
}
onPlay();
return;
}
@Override

View File

@ -677,6 +677,54 @@ public final class DBTasks {
});
}
/**
* Searches the authors of FeedItems of a specific Feed for a given
* string.
*
* @param context Used for accessing the DB.
* @param feedID The id of the feed whose items should be searched.
* @param query The search string.
* @return A FutureTask object that executes the search request and returns the search result as a List of FeedItems.
*/
public static FutureTask<List<FeedItem>> searchFeedItemAuthor(final Context context,
final long feedID, final String query) {
return new FutureTask<>(new QueryTask<List<FeedItem>>(context) {
@Override
public void execute(PodDBAdapter adapter) {
Cursor searchResult = adapter.searchItemAuthors(feedID,
query);
List<FeedItem> items = DBReader.extractItemlistFromCursor(searchResult);
DBReader.loadAdditionalFeedItemListData(items);
setResult(items);
searchResult.close();
}
});
}
/**
* Searches the feed identifiers of FeedItems of a specific Feed for a given
* string.
*
* @param context Used for accessing the DB.
* @param feedID The id of the feed whose items should be searched.
* @param query The search string.
* @return A FutureTask object that executes the search request and returns the search result as a List of FeedItems.
*/
public static FutureTask<List<FeedItem>> searchFeedItemFeedIdentifier(final Context context,
final long feedID, final String query) {
return new FutureTask<>(new QueryTask<List<FeedItem>>(context) {
@Override
public void execute(PodDBAdapter adapter) {
Cursor searchResult = adapter.searchItemFeedIdentifiers(feedID,
query);
List<FeedItem> items = DBReader.extractItemlistFromCursor(searchResult);
DBReader.loadAdditionalFeedItemListData(items);
setResult(items);
searchResult.close();
}
});
}
/**
* Searches the descriptions of FeedItems of a specific Feed for a given
* string.

View File

@ -35,11 +35,13 @@ public class FeedSearcher {
*/
public static List<SearchResult> performSearch(final Context context,
final String query, final long selectedFeed) {
final int values[] = {2, 1, 0, 0};
final int values[] = {2, 1, 0, 0, 0, 0};
final String[] subtitles = {context.getString(R.string.found_in_title_label),
context.getString(R.string.found_in_chapters_label),
context.getString(R.string.found_in_shownotes_label),
context.getString(R.string.found_in_shownotes_label)};
context.getString(R.string.found_in_shownotes_label),
context.getString(R.string.found_in_authors_label),
context.getString(R.string.found_in_feeds_label)};
List<SearchResult> result = new ArrayList<>();
@ -48,6 +50,8 @@ public class FeedSearcher {
tasks.add(DBTasks.searchFeedItemChapters(context, selectedFeed, query));
tasks.add(DBTasks.searchFeedItemDescription(context, selectedFeed, query));
tasks.add(DBTasks.searchFeedItemContentEncoded(context, selectedFeed, query));
tasks.add(DBTasks.searchFeedItemAuthor(context, selectedFeed, query));
tasks.add(DBTasks.searchFeedItemFeedIdentifier(context, selectedFeed, query));
for (FutureTask<List<FeedItem>> task : tasks) {
task.run();

View File

@ -1589,6 +1589,52 @@ public class PodDBAdapter {
}
}
public Cursor searchItemAuthors(long feedID, String query) {
if (feedID != 0) {
// search items in specific feed
return db.rawQuery("SELECT " + TextUtils.join(", ", FEEDITEM_SEL_FI_SMALL) + " FROM " + TABLE_NAME_FEED_ITEMS
+ " JOIN " + TABLE_NAME_FEEDS + " ON " + TABLE_NAME_FEED_ITEMS+"."+KEY_FEED+"="+TABLE_NAME_FEEDS+"."+KEY_ID
+ " WHERE " + KEY_FEED
+ "=? AND " + KEY_AUTHOR + " LIKE '%"
+ prepareSearchQuery(query) + "%' ORDER BY "
+ TABLE_NAME_FEED_ITEMS + "." + KEY_PUBDATE + " DESC",
new String[]{String.valueOf(feedID)}
);
} else {
// search through all items
return db.rawQuery("SELECT " + TextUtils.join(", ", FEEDITEM_SEL_FI_SMALL) + " FROM " + TABLE_NAME_FEED_ITEMS
+ " JOIN " + TABLE_NAME_FEEDS + " ON " + TABLE_NAME_FEED_ITEMS+"."+KEY_FEED+"="+TABLE_NAME_FEEDS+"."+KEY_ID
+ " WHERE " + KEY_AUTHOR + " LIKE '%"
+ prepareSearchQuery(query) + "%' ORDER BY "
+ TABLE_NAME_FEED_ITEMS + "." + KEY_PUBDATE + " DESC",
null
);
}
}
public Cursor searchItemFeedIdentifiers(long feedID, String query) {
if (feedID != 0) {
// search items in specific feed
return db.rawQuery("SELECT " + TextUtils.join(", ", FEEDITEM_SEL_FI_SMALL) + " FROM " + TABLE_NAME_FEED_ITEMS
+ " JOIN " + TABLE_NAME_FEEDS + " ON " + TABLE_NAME_FEED_ITEMS+"."+KEY_FEED+"="+TABLE_NAME_FEEDS+"."+KEY_ID
+ " WHERE " + KEY_FEED
+ "=? AND " + KEY_FEED_IDENTIFIER + " LIKE '%"
+ prepareSearchQuery(query) + "%' ORDER BY "
+ TABLE_NAME_FEED_ITEMS + "." + KEY_PUBDATE + " DESC",
new String[]{String.valueOf(feedID)}
);
} else {
// search through all items
return db.rawQuery("SELECT " + TextUtils.join(", ", FEEDITEM_SEL_FI_SMALL) + " FROM " + TABLE_NAME_FEED_ITEMS
+ " JOIN " + TABLE_NAME_FEEDS + " ON " + TABLE_NAME_FEED_ITEMS+"."+KEY_FEED+"="+TABLE_NAME_FEEDS+"."+KEY_ID
+ " WHERE " + KEY_FEED_IDENTIFIER + " LIKE '%"
+ prepareSearchQuery(query) + "%' ORDER BY "
+ TABLE_NAME_FEED_ITEMS + "." + KEY_PUBDATE + " DESC",
null
);
}
}
public Cursor searchItemChapters(long feedID, String searchQuery) {
final String query;
if (feedID != 0) {

View File

@ -436,6 +436,8 @@
<string name="search_hint">Search for episodes</string>
<string name="found_in_shownotes_label">Found in show notes</string>
<string name="found_in_chapters_label">Found in chapters</string>
<string name="found_in_authors_label">Found in authors</string>
<string name="found_in_feeds_label">Found in feeds</string>
<string name="search_status_no_results">No results were found</string>
<string name="search_label">Search</string>
<string name="found_in_title_label">Found in title</string>