Merge branch 'description_update' into develop
Conflicts: src/de/danoeh/antennapod/feed/FeedItem.java
This commit is contained in:
commit
7f92cdce70
|
@ -69,8 +69,10 @@ public class SearchActivity extends SherlockListActivity {
|
|||
if (AppConfig.DEBUG)
|
||||
Log.d(TAG, "Starting search");
|
||||
String query = intent.getStringExtra(SearchManager.QUERY);
|
||||
getSupportActionBar().setSubtitle(
|
||||
getString(R.string.search_term_label) + "\"" + query + "\"");
|
||||
getSupportActionBar()
|
||||
.setSubtitle(
|
||||
getString(R.string.search_term_label) + "\""
|
||||
+ query + "\"");
|
||||
handleSearchRequest(query);
|
||||
}
|
||||
}
|
||||
|
@ -133,48 +135,46 @@ public class SearchActivity extends SherlockListActivity {
|
|||
}
|
||||
|
||||
@SuppressLint({ "NewApi", "NewApi" })
|
||||
private void handleSearchRequest(String query) {
|
||||
AsyncTask<String, Void, ArrayList<SearchResult>> executor = new AsyncTask<String, Void, ArrayList<SearchResult>>() {
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
if (searchAdapter != null) {
|
||||
searchAdapter.clear();
|
||||
searchAdapter.notifyDataSetChanged();
|
||||
}
|
||||
txtvStatus.setText(R.string.search_status_searching);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ArrayList<SearchResult> doInBackground(String... params) {
|
||||
if (AppConfig.DEBUG)
|
||||
Log.d(TAG, "Starting background work");
|
||||
return FeedSearcher.performSearch(params[0], selectedFeed);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(ArrayList<SearchResult> result) {
|
||||
if (AppConfig.DEBUG)
|
||||
Log.d(TAG, "Background work finished");
|
||||
if (AppConfig.DEBUG)
|
||||
Log.d(TAG, "Found " + result.size() + " results");
|
||||
content = result;
|
||||
|
||||
searchAdapter = new SearchlistAdapter(SearchActivity.this, 0,
|
||||
content);
|
||||
getListView().setAdapter(searchAdapter);
|
||||
searchAdapter.notifyDataSetChanged();
|
||||
if (content.isEmpty()) {
|
||||
txtvStatus.setText(R.string.search_status_no_results);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.GINGERBREAD_MR1) {
|
||||
executor.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, query);
|
||||
} else {
|
||||
executor.execute(query);
|
||||
private void handleSearchRequest(final String query) {
|
||||
if (searchAdapter != null) {
|
||||
searchAdapter.clear();
|
||||
searchAdapter.notifyDataSetChanged();
|
||||
}
|
||||
txtvStatus.setText(R.string.search_status_searching);
|
||||
|
||||
Thread thread = new Thread() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Log.d(TAG, "Starting background work");
|
||||
final ArrayList<SearchResult> result = FeedSearcher
|
||||
.performSearch(SearchActivity.this, query, selectedFeed);
|
||||
if (SearchActivity.this != null) {
|
||||
SearchActivity.this.runOnUiThread(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (AppConfig.DEBUG)
|
||||
Log.d(TAG, "Background work finished");
|
||||
if (AppConfig.DEBUG)
|
||||
Log.d(TAG, "Found " + result.size()
|
||||
+ " results");
|
||||
content = result;
|
||||
|
||||
searchAdapter = new SearchlistAdapter(
|
||||
SearchActivity.this, 0, content);
|
||||
getListView().setAdapter(searchAdapter);
|
||||
searchAdapter.notifyDataSetChanged();
|
||||
if (content.isEmpty()) {
|
||||
txtvStatus
|
||||
.setText(R.string.search_status_no_results);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
thread.start();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -144,6 +144,15 @@ public class Feed extends FeedFile {
|
|||
return download_url;
|
||||
}
|
||||
}
|
||||
|
||||
/** Calls cacheDescriptions on all items. */
|
||||
protected void cacheDescriptionsOfItems() {
|
||||
if (items != null) {
|
||||
for (FeedItem item : items) {
|
||||
item.cacheDescriptions();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTypeAsInt() {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package de.danoeh.antennapod.feed;
|
||||
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -13,11 +14,23 @@ import de.danoeh.antennapod.PodcastApp;
|
|||
*/
|
||||
public class FeedItem extends FeedComponent {
|
||||
|
||||
/** The id/guid that can be found in the rss/atom feed. Might not be set.*/
|
||||
/** The id/guid that can be found in the rss/atom feed. Might not be set. */
|
||||
private String itemIdentifier;
|
||||
private String title;
|
||||
/**
|
||||
* The description of a feeditem. This field should only be set by the
|
||||
* parser.
|
||||
*/
|
||||
private String description;
|
||||
/**
|
||||
* The content of the content-encoded tag of a feeditem. This field should
|
||||
* only be set by the parser.
|
||||
*/
|
||||
private String contentEncoded;
|
||||
|
||||
private SoftReference<String> cachedDescription;
|
||||
private SoftReference<String> cachedContentEncoded;
|
||||
|
||||
private String link;
|
||||
private Date pubDate;
|
||||
private FeedMedia media;
|
||||
|
@ -30,16 +43,19 @@ public class FeedItem extends FeedComponent {
|
|||
this.read = true;
|
||||
}
|
||||
|
||||
public FeedItem(String title, String description, String link,
|
||||
Date pubDate, FeedMedia media, Feed feed) {
|
||||
super();
|
||||
this.title = title;
|
||||
this.description = description;
|
||||
this.link = link;
|
||||
this.pubDate = pubDate;
|
||||
this.media = media;
|
||||
this.feed = feed;
|
||||
this.read = true;
|
||||
/**
|
||||
* Moves the 'description' and 'contentEncoded' field of feeditem to their
|
||||
* SoftReference fields.
|
||||
*/
|
||||
protected void cacheDescriptions() {
|
||||
if (description != null) {
|
||||
cachedDescription = new SoftReference<String>(description);
|
||||
}
|
||||
if (contentEncoded != null) {
|
||||
cachedContentEncoded = new SoftReference<String>(contentEncoded);
|
||||
}
|
||||
description = null;
|
||||
contentEncoded = null;
|
||||
}
|
||||
|
||||
/** Get the chapter that fits the position. */
|
||||
|
@ -62,11 +78,12 @@ public class FeedItem extends FeedComponent {
|
|||
public Chapter getCurrentChapter() {
|
||||
return getCurrentChapter(media.getPosition());
|
||||
}
|
||||
|
||||
/** Returns the value that uniquely identifies this FeedItem.
|
||||
* If the itemIdentifier attribute is not null, it will be returned.
|
||||
* Else it will try to return the title. If the title is not given, it will
|
||||
* use the link of the entry.
|
||||
|
||||
/**
|
||||
* Returns the value that uniquely identifies this FeedItem. If the
|
||||
* itemIdentifier attribute is not null, it will be returned. Else it will
|
||||
* try to return the title. If the title is not given, it will use the link
|
||||
* of the entry.
|
||||
* */
|
||||
public String getIdentifyingValue() {
|
||||
if (itemIdentifier != null) {
|
||||
|
@ -87,6 +104,9 @@ public class FeedItem extends FeedComponent {
|
|||
}
|
||||
|
||||
public String getDescription() {
|
||||
if (description == null && cachedDescription != null) {
|
||||
return cachedDescription.get();
|
||||
}
|
||||
return description;
|
||||
}
|
||||
|
||||
|
@ -131,6 +151,10 @@ public class FeedItem extends FeedComponent {
|
|||
}
|
||||
|
||||
public String getContentEncoded() {
|
||||
if (contentEncoded == null && cachedContentEncoded != null) {
|
||||
return cachedContentEncoded.get();
|
||||
|
||||
}
|
||||
return contentEncoded;
|
||||
}
|
||||
|
||||
|
@ -161,7 +185,7 @@ public class FeedItem extends FeedComponent {
|
|||
public void setItemIdentifier(String itemIdentifier) {
|
||||
this.itemIdentifier = itemIdentifier;
|
||||
}
|
||||
|
||||
|
||||
public boolean isPlaying() {
|
||||
if (media != null) {
|
||||
if (PodcastApp.getCurrentlyPlayingMediaId() == media.getId()) {
|
||||
|
@ -170,6 +194,13 @@ public class FeedItem extends FeedComponent {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public void setCachedDescription(String d) {
|
||||
cachedDescription = new SoftReference<String>(d);
|
||||
}
|
||||
|
||||
public void setCachedContentEncoded(String c) {
|
||||
cachedContentEncoded = new SoftReference<String>(c);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -774,6 +774,7 @@ public class FeedManager {
|
|||
PodDBAdapter adapter = new PodDBAdapter(context);
|
||||
adapter.open();
|
||||
adapter.setCompleteFeed(feed);
|
||||
feed.cacheDescriptionsOfItems();
|
||||
adapter.close();
|
||||
}
|
||||
});
|
||||
|
@ -867,6 +868,7 @@ public class FeedManager {
|
|||
public void setFeed(Feed feed, PodDBAdapter adapter) {
|
||||
if (adapter != null) {
|
||||
adapter.setFeed(feed);
|
||||
feed.cacheDescriptionsOfItems();
|
||||
} else {
|
||||
Log.w(TAG, "Adapter in setFeed was null");
|
||||
}
|
||||
|
@ -914,6 +916,7 @@ public class FeedManager {
|
|||
PodDBAdapter adapter = new PodDBAdapter(context);
|
||||
adapter.open();
|
||||
adapter.setFeed(feed);
|
||||
feed.cacheDescriptionsOfItems();
|
||||
adapter.close();
|
||||
}
|
||||
});
|
||||
|
@ -1009,6 +1012,19 @@ public class FeedManager {
|
|||
return null;
|
||||
}
|
||||
|
||||
/** Get a FeedItem by its id and the id of its feed. */
|
||||
public FeedItem getFeedItem(long itemId, long feedId) {
|
||||
Feed feed = getFeed(feedId);
|
||||
if (feed != null && feed.getItems() != null) {
|
||||
for (FeedItem item : feed.getItems()) {
|
||||
if (item.getId() == itemId) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Get a FeedMedia object by the id of the Media object and the feed object */
|
||||
public FeedMedia getFeedMedia(long id, Feed feed) {
|
||||
if (feed != null) {
|
||||
|
@ -1129,37 +1145,34 @@ public class FeedManager {
|
|||
do {
|
||||
FeedItem item = new FeedItem();
|
||||
|
||||
item.id = itemlistCursor.getLong(PodDBAdapter.KEY_ID_INDEX);
|
||||
item.id = itemlistCursor.getLong(PodDBAdapter.IDX_FI_SMALL_ID);
|
||||
item.setFeed(feed);
|
||||
item.setTitle(itemlistCursor
|
||||
.getString(PodDBAdapter.KEY_TITLE_INDEX));
|
||||
.getString(PodDBAdapter.IDX_FI_SMALL_TITLE));
|
||||
item.setLink(itemlistCursor
|
||||
.getString(PodDBAdapter.KEY_LINK_INDEX));
|
||||
item.setDescription(itemlistCursor
|
||||
.getString(PodDBAdapter.KEY_DESCRIPTION_INDEX));
|
||||
item.setContentEncoded(itemlistCursor
|
||||
.getString(PodDBAdapter.KEY_CONTENT_ENCODED_INDEX));
|
||||
.getString(PodDBAdapter.IDX_FI_SMALL_LINK));
|
||||
item.setPubDate(new Date(itemlistCursor
|
||||
.getLong(PodDBAdapter.KEY_PUBDATE_INDEX)));
|
||||
.getLong(PodDBAdapter.IDX_FI_SMALL_PUBDATE)));
|
||||
item.setPaymentLink(itemlistCursor
|
||||
.getString(PodDBAdapter.KEY_PAYMENT_LINK_INDEX));
|
||||
.getString(PodDBAdapter.IDX_FI_SMALL_PAYMENT_LINK));
|
||||
long mediaId = itemlistCursor
|
||||
.getLong(PodDBAdapter.KEY_MEDIA_INDEX);
|
||||
.getLong(PodDBAdapter.IDX_FI_SMALL_MEDIA);
|
||||
if (mediaId != 0) {
|
||||
mediaIds.add(String.valueOf(mediaId));
|
||||
item.setMedia(new FeedMedia(mediaId, item));
|
||||
}
|
||||
item.read = (itemlistCursor.getInt(PodDBAdapter.KEY_READ_INDEX) > 0) ? true
|
||||
item.read = (itemlistCursor
|
||||
.getInt(PodDBAdapter.IDX_FI_SMALL_READ) > 0) ? true
|
||||
: false;
|
||||
item.setItemIdentifier(itemlistCursor
|
||||
.getString(PodDBAdapter.KEY_ITEM_IDENTIFIER_INDEX));
|
||||
.getString(PodDBAdapter.IDX_FI_SMALL_ITEM_IDENTIFIER));
|
||||
if (!item.read) {
|
||||
unreadItems.add(item);
|
||||
}
|
||||
|
||||
// extract chapters
|
||||
boolean hasSimpleChapters = itemlistCursor
|
||||
.getInt(PodDBAdapter.KEY_HAS_SIMPLECHAPTERS_INDEX) > 0;
|
||||
.getInt(PodDBAdapter.IDX_FI_SMALL_HAS_CHAPTERS) > 0;
|
||||
if (hasSimpleChapters) {
|
||||
Cursor chapterCursor = adapter
|
||||
.getSimpleChaptersOfFeedItemCursor(item);
|
||||
|
@ -1325,6 +1338,57 @@ public class FeedManager {
|
|||
cursor.close();
|
||||
}
|
||||
|
||||
public void loadExtraInformationOfItem(final Context context,
|
||||
final FeedItem item, FeedManager.TaskCallback callback) {
|
||||
if (AppConfig.DEBUG)
|
||||
Log.d(TAG,
|
||||
"Loading extra information of item with id " + item.getId());
|
||||
dbExec.execute(new FeedManager.Task(new Handler(), callback) {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
PodDBAdapter adapter = new PodDBAdapter(context);
|
||||
adapter.open();
|
||||
Cursor extraCursor = adapter.getExtraInformationOfItem(item);
|
||||
if (extraCursor.moveToFirst()) {
|
||||
item.setCachedDescription(extraCursor
|
||||
.getString(PodDBAdapter.IDX_FI_EXTRA_DESCRIPTION));
|
||||
item.setCachedContentEncoded(extraCursor
|
||||
.getString(PodDBAdapter.IDX_FI_EXTRA_CONTENT_ENCODED));
|
||||
}
|
||||
adapter.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void searchFeedItemDescription(final Context context,
|
||||
final Feed feed, final String query,
|
||||
FeedManager.QueryTaskCallback callback) {
|
||||
dbExec.execute(new FeedManager.QueryTask(context, new Handler(), callback) {
|
||||
|
||||
@Override
|
||||
public void execute(PodDBAdapter adapter) {
|
||||
Cursor searchResult = adapter.searchItemDescriptions(feed,
|
||||
query);
|
||||
setResult(searchResult);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void searchFeedItemContentEncoded(final Context context,
|
||||
final Feed feed, final String query,
|
||||
FeedManager.QueryTaskCallback callback) {
|
||||
dbExec.execute(new FeedManager.QueryTask(context, new Handler(), callback) {
|
||||
|
||||
@Override
|
||||
public void execute(PodDBAdapter adapter) {
|
||||
Cursor searchResult = adapter.searchItemContentEncoded(feed,
|
||||
query);
|
||||
setResult(searchResult);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public List<Feed> getFeeds() {
|
||||
return feeds;
|
||||
}
|
||||
|
@ -1345,4 +1409,102 @@ public class FeedManager {
|
|||
return playbackHistory;
|
||||
}
|
||||
|
||||
/** Is called by a FeedManagerTask after completion. */
|
||||
public interface TaskCallback {
|
||||
void onCompletion(Cursor result);
|
||||
}
|
||||
|
||||
/** Is called by a FeedManager.QueryTask after completion. */
|
||||
public interface QueryTaskCallback {
|
||||
void handleResult(Cursor result);
|
||||
void onCompletion();
|
||||
}
|
||||
|
||||
/** A runnable that can post a callback to a handler after completion. */
|
||||
abstract class Task implements Runnable {
|
||||
private Handler handler;
|
||||
private TaskCallback callback;
|
||||
|
||||
/**
|
||||
* Standard contructor. No callbacks are going to be posted to a
|
||||
* handler.
|
||||
*/
|
||||
public Task() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* The Task will post a Runnable to 'handler' that will execute the
|
||||
* 'callback' after completion.
|
||||
*/
|
||||
public Task(Handler handler, TaskCallback callback) {
|
||||
super();
|
||||
this.handler = handler;
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void run() {
|
||||
execute();
|
||||
if (handler != null && callback != null) {
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
callback.onCompletion(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/** This method will be executed in the same thread as the run() method. */
|
||||
public abstract void execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* A runnable which should be used for database queries. The onCompletion
|
||||
* method is executed on the database executor to handle Cursors correctly.
|
||||
* This class automatically creates a PodDBAdapter object and closes it when
|
||||
* it is no longer in use.
|
||||
*/
|
||||
abstract class QueryTask implements Runnable {
|
||||
private QueryTaskCallback callback;
|
||||
private Cursor result;
|
||||
private Context context;
|
||||
private Handler handler;
|
||||
|
||||
public QueryTask(Context context, Handler handler, QueryTaskCallback callback) {
|
||||
this.callback = callback;
|
||||
this.context = context;
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void run() {
|
||||
PodDBAdapter adapter = new PodDBAdapter(context);
|
||||
adapter.open();
|
||||
execute(adapter);
|
||||
callback.handleResult(result);
|
||||
if (result != null && !result.isClosed()) {
|
||||
result.close();
|
||||
}
|
||||
adapter.close();
|
||||
if (handler != null && callback != null) {
|
||||
handler.post(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
callback.onCompletion();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void execute(PodDBAdapter adapter);
|
||||
|
||||
protected void setResult(Cursor c) {
|
||||
result = c;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,10 +5,14 @@ import java.util.Collections;
|
|||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
import de.danoeh.antennapod.AppConfig;
|
||||
import de.danoeh.antennapod.PodcastApp;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.storage.PodDBAdapter;
|
||||
import de.danoeh.antennapod.util.comparator.SearchResultValueComparator;
|
||||
|
||||
/** Performs search on Feeds and FeedItems */
|
||||
|
@ -23,10 +27,10 @@ public class FeedSearcher {
|
|||
private static final int VALUE_WORD_MATCH = 4;
|
||||
|
||||
/** Performs a search in all feeds or one specific feed. */
|
||||
public static ArrayList<SearchResult> performSearch(final String query,
|
||||
Feed selectedFeed) {
|
||||
String lcQuery = query.toLowerCase();
|
||||
ArrayList<SearchResult> result = new ArrayList<SearchResult>();
|
||||
public static ArrayList<SearchResult> performSearch(final Context context,
|
||||
final String query, final Feed selectedFeed) {
|
||||
final String lcQuery = query.toLowerCase();
|
||||
final ArrayList<SearchResult> result = new ArrayList<SearchResult>();
|
||||
if (selectedFeed == null) {
|
||||
if (AppConfig.DEBUG)
|
||||
Log.d(TAG, "Performing global search");
|
||||
|
@ -45,14 +49,40 @@ public class FeedSearcher {
|
|||
Log.d(TAG, "Searching item-chaptertitles");
|
||||
searchFeedItemChapters(lcQuery, result, selectedFeed);
|
||||
|
||||
if (AppConfig.DEBUG)
|
||||
Log.d(TAG, "Searching item descriptions");
|
||||
searchFeedItemDescription(lcQuery, result, selectedFeed);
|
||||
final FeedManager manager = FeedManager.getInstance();
|
||||
Looper.prepare();
|
||||
manager.searchFeedItemDescription(context, selectedFeed, lcQuery,
|
||||
new FeedManager.QueryTaskCallback() {
|
||||
|
||||
if (AppConfig.DEBUG)
|
||||
Log.d(TAG, "Searching item content encoded data");
|
||||
searchFeedItemContentEncoded(lcQuery, result, selectedFeed);
|
||||
@Override
|
||||
public void handleResult(Cursor cResult) {
|
||||
searchFeedItemContentEncodedCursor(lcQuery, result,
|
||||
selectedFeed, cResult);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCompletion() {
|
||||
manager.searchFeedItemContentEncoded(context,
|
||||
selectedFeed, lcQuery,
|
||||
new FeedManager.QueryTaskCallback() {
|
||||
|
||||
@Override
|
||||
public void handleResult(Cursor cResult) {
|
||||
searchFeedItemDescriptionCursor(
|
||||
lcQuery, result, selectedFeed,
|
||||
cResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCompletion() {
|
||||
Looper.myLooper().quit();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Looper.loop();
|
||||
if (AppConfig.DEBUG)
|
||||
Log.d(TAG, "Sorting results");
|
||||
Collections.sort(result, new SearchResultValueComparator());
|
||||
|
@ -127,61 +157,74 @@ public class FeedSearcher {
|
|||
}
|
||||
}
|
||||
|
||||
private static void searchFeedItemDescription(String query,
|
||||
ArrayList<SearchResult> destination, Feed selectedFeed) {
|
||||
private static void searchFeedItemDescriptionCursor(String query,
|
||||
ArrayList<SearchResult> destination, Feed feed, Cursor cursor) {
|
||||
FeedManager manager = FeedManager.getInstance();
|
||||
if (selectedFeed == null) {
|
||||
for (Feed feed : manager.getFeeds()) {
|
||||
searchFeedItemDescriptionSingleFeed(query, destination, feed);
|
||||
}
|
||||
} else {
|
||||
searchFeedItemDescriptionSingleFeed(query, destination,
|
||||
selectedFeed);
|
||||
}
|
||||
}
|
||||
if (cursor.moveToFirst()) {
|
||||
do {
|
||||
final long itemId = cursor
|
||||
.getLong(PodDBAdapter.IDX_FI_EXTRA_ID);
|
||||
String content = cursor
|
||||
.getString(PodDBAdapter.IDX_FI_EXTRA_DESCRIPTION);
|
||||
if (content != null) {
|
||||
content = content.toLowerCase();
|
||||
final long feedId = cursor
|
||||
.getLong(PodDBAdapter.IDX_FI_EXTRA_FEED);
|
||||
FeedItem item = null;
|
||||
if (feed == null) {
|
||||
item = manager.getFeedItem(itemId, feedId);
|
||||
} else {
|
||||
item = manager.getFeedItem(itemId, feed);
|
||||
}
|
||||
if (item != null) {
|
||||
SearchResult searchResult = createSearchResult(item,
|
||||
query, content, VALUE_ITEM_DESCRIPTION);
|
||||
if (searchResult != null) {
|
||||
searchResult.setSubtitle(PodcastApp.getInstance()
|
||||
.getString(
|
||||
R.string.found_in_shownotes_label));
|
||||
destination.add(searchResult);
|
||||
|
||||
private static void searchFeedItemDescriptionSingleFeed(String query,
|
||||
ArrayList<SearchResult> destination, Feed feed) {
|
||||
for (FeedItem item : feed.getItems()) {
|
||||
if (item.getDescription() != null) {
|
||||
SearchResult result = createSearchResult(item, query, item
|
||||
.getDescription().toLowerCase(), VALUE_ITEM_DESCRIPTION);
|
||||
if (result != null) {
|
||||
result.setSubtitle(PodcastApp.getInstance().getString(
|
||||
R.string.found_in_shownotes_label));
|
||||
destination.add(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} while (cursor.moveToNext());
|
||||
}
|
||||
}
|
||||
|
||||
private static void searchFeedItemContentEncoded(String query,
|
||||
ArrayList<SearchResult> destination, Feed selectedFeed) {
|
||||
private static void searchFeedItemContentEncodedCursor(String query,
|
||||
ArrayList<SearchResult> destination, Feed feed, Cursor cursor) {
|
||||
FeedManager manager = FeedManager.getInstance();
|
||||
if (selectedFeed == null) {
|
||||
for (Feed feed : manager.getFeeds()) {
|
||||
searchFeedItemContentEncodedSingleFeed(query, destination, feed);
|
||||
}
|
||||
} else {
|
||||
searchFeedItemContentEncodedSingleFeed(query, destination,
|
||||
selectedFeed);
|
||||
}
|
||||
}
|
||||
if (cursor.moveToFirst()) {
|
||||
do {
|
||||
final long itemId = cursor
|
||||
.getLong(PodDBAdapter.IDX_FI_EXTRA_ID);
|
||||
String content = cursor
|
||||
.getString(PodDBAdapter.IDX_FI_EXTRA_CONTENT_ENCODED);
|
||||
if (content != null) {
|
||||
content = content.toLowerCase();
|
||||
|
||||
private static void searchFeedItemContentEncodedSingleFeed(String query,
|
||||
ArrayList<SearchResult> destination, Feed feed) {
|
||||
for (FeedItem item : feed.getItems()) {
|
||||
if (!destination.contains(item) && item.getContentEncoded() != null) {
|
||||
SearchResult result = createSearchResult(item, query, item
|
||||
.getContentEncoded().toLowerCase(),
|
||||
VALUE_ITEM_DESCRIPTION);
|
||||
if (result != null) {
|
||||
result.setSubtitle(PodcastApp.getInstance().getString(
|
||||
R.string.found_in_shownotes_label));
|
||||
destination.add(result);
|
||||
final long feedId = cursor
|
||||
.getLong(PodDBAdapter.IDX_FI_EXTRA_FEED);
|
||||
FeedItem item = null;
|
||||
if (feed == null) {
|
||||
item = manager.getFeedItem(itemId, feedId);
|
||||
} else {
|
||||
item = manager.getFeedItem(itemId, feed);
|
||||
}
|
||||
if (item != null) {
|
||||
SearchResult searchResult = createSearchResult(item,
|
||||
query, content, VALUE_ITEM_DESCRIPTION);
|
||||
if (searchResult != null) {
|
||||
searchResult.setSubtitle(PodcastApp.getInstance()
|
||||
.getString(
|
||||
R.string.found_in_shownotes_label));
|
||||
destination.add(searchResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (cursor.moveToNext());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import org.apache.commons.lang3.StringEscapeUtils;
|
|||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.database.Cursor;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
@ -104,16 +105,22 @@ public class ItemDescriptionFragment extends SherlockFragment {
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
if (item != null) {
|
||||
webViewLoader = createLoader();
|
||||
if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.GINGERBREAD_MR1) {
|
||||
webViewLoader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
if (item.getDescription() == null && item.getDescription() == null) {
|
||||
Log.i(TAG, "Loading data");
|
||||
FeedManager.getInstance().loadExtraInformationOfItem(
|
||||
getActivity(), item, new FeedManager.TaskCallback() {
|
||||
@Override
|
||||
public void onCompletion(Cursor result) {
|
||||
startLoader();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
webViewLoader.execute();
|
||||
Log.i(TAG, "Using cached data");
|
||||
startLoader();
|
||||
}
|
||||
} else {
|
||||
Log.e(TAG, "Error in onViewCreated: Item was null");
|
||||
|
@ -125,6 +132,16 @@ public class ItemDescriptionFragment extends SherlockFragment {
|
|||
super.onResume();
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
private void startLoader() {
|
||||
webViewLoader = createLoader();
|
||||
if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.GINGERBREAD_MR1) {
|
||||
webViewLoader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
} else {
|
||||
webViewLoader.execute();
|
||||
}
|
||||
}
|
||||
|
||||
private AsyncTask<Void, Void, Void> createLoader() {
|
||||
return new AsyncTask<Void, Void, Void>() {
|
||||
@Override
|
||||
|
@ -145,8 +162,10 @@ public class ItemDescriptionFragment extends SherlockFragment {
|
|||
// /webvDescription.loadData(url, "text/html", "utf-8");
|
||||
webvDescription.loadDataWithBaseURL(null, data, "text/html",
|
||||
"utf-8", "about:blank");
|
||||
getSherlockActivity()
|
||||
.setSupportProgressBarIndeterminateVisibility(false);
|
||||
if (getSherlockActivity() != null) {
|
||||
getSherlockActivity()
|
||||
.setSupportProgressBarIndeterminateVisibility(false);
|
||||
}
|
||||
if (AppConfig.DEBUG)
|
||||
Log.d(TAG, "Webview loaded");
|
||||
webViewLoader = null;
|
||||
|
@ -155,8 +174,10 @@ public class ItemDescriptionFragment extends SherlockFragment {
|
|||
@Override
|
||||
protected void onPreExecute() {
|
||||
super.onPreExecute();
|
||||
getSherlockActivity()
|
||||
.setSupportProgressBarIndeterminateVisibility(true);
|
||||
if (getSherlockActivity() != null) {
|
||||
getSherlockActivity()
|
||||
.setSupportProgressBarIndeterminateVisibility(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -180,6 +180,39 @@ public class PodDBAdapter {
|
|||
private final Context context;
|
||||
private PodDBHelper helper;
|
||||
|
||||
/**
|
||||
* Select all columns from the feeditems-table except description and
|
||||
* content-encoded.
|
||||
*/
|
||||
private static final String[] SEL_FI_SMALL = { KEY_ID, KEY_TITLE,
|
||||
KEY_PUBDATE, KEY_READ, KEY_LINK, KEY_PAYMENT_LINK, KEY_MEDIA,
|
||||
KEY_FEED, KEY_HAS_CHAPTERS, KEY_ITEM_IDENTIFIER };
|
||||
|
||||
// column indices for SEL_FI_SMALL
|
||||
|
||||
public static final int IDX_FI_SMALL_ID = 0;
|
||||
public static final int IDX_FI_SMALL_TITLE = 1;
|
||||
public static final int IDX_FI_SMALL_PUBDATE = 2;
|
||||
public static final int IDX_FI_SMALL_READ = 3;
|
||||
public static final int IDX_FI_SMALL_LINK = 4;
|
||||
public static final int IDX_FI_SMALL_PAYMENT_LINK = 5;
|
||||
public static final int IDX_FI_SMALL_MEDIA = 6;
|
||||
public static final int IDX_FI_SMALL_FEED = 7;
|
||||
public static final int IDX_FI_SMALL_HAS_CHAPTERS = 8;
|
||||
public static final int IDX_FI_SMALL_ITEM_IDENTIFIER = 9;
|
||||
|
||||
/** Select id, description and content-encoded column from feeditems. */
|
||||
public static final String[] SEL_FI_EXTRA = { KEY_ID, KEY_DESCRIPTION,
|
||||
KEY_CONTENT_ENCODED, KEY_FEED };
|
||||
|
||||
// column indices for SEL_FI_EXTRA
|
||||
|
||||
public static final int IDX_FI_EXTRA_ID = 0;
|
||||
public static final int IDX_FI_EXTRA_DESCRIPTION = 1;
|
||||
public static final int IDX_FI_EXTRA_CONTENT_ENCODED = 2;
|
||||
public static final int IDX_FI_EXTRA_FEED = 3;
|
||||
|
||||
|
||||
public PodDBAdapter(Context c) {
|
||||
this.context = c;
|
||||
helper = new PodDBHelper(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||
|
@ -280,7 +313,8 @@ public class PodDBAdapter {
|
|||
values.put(KEY_DOWNLOADED, media.isDownloaded());
|
||||
values.put(KEY_FILE_URL, media.getFile_url());
|
||||
if (media.getPlaybackCompletionDate() != null) {
|
||||
values.put(KEY_PLAYBACK_COMPLETION_DATE, media.getPlaybackCompletionDate().getTime());
|
||||
values.put(KEY_PLAYBACK_COMPLETION_DATE, media
|
||||
.getPlaybackCompletionDate().getTime());
|
||||
} else {
|
||||
values.put(KEY_PLAYBACK_COMPLETION_DATE, 0);
|
||||
}
|
||||
|
@ -324,8 +358,12 @@ public class PodDBAdapter {
|
|||
ContentValues values = new ContentValues();
|
||||
values.put(KEY_TITLE, item.getTitle());
|
||||
values.put(KEY_LINK, item.getLink());
|
||||
values.put(KEY_DESCRIPTION, item.getDescription());
|
||||
values.put(KEY_CONTENT_ENCODED, item.getContentEncoded());
|
||||
if (item.getDescription() != null) {
|
||||
values.put(KEY_DESCRIPTION, item.getDescription());
|
||||
}
|
||||
if (item.getContentEncoded() != null) {
|
||||
values.put(KEY_CONTENT_ENCODED, item.getContentEncoded());
|
||||
}
|
||||
values.put(KEY_PUBDATE, item.getPubDate().getTime());
|
||||
values.put(KEY_PAYMENT_LINK, item.getPaymentLink());
|
||||
if (item.getMedia() != null) {
|
||||
|
@ -471,17 +509,26 @@ public class PodDBAdapter {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns a cursor with all FeedItems of a Feed.
|
||||
* Returns a cursor with all FeedItems of a Feed. Uses SEL_FI_SMALL
|
||||
*
|
||||
* @param feed
|
||||
* The feed you want to get the FeedItems from.
|
||||
* @return The cursor of the query
|
||||
* */
|
||||
public final Cursor getAllItemsOfFeedCursor(final Feed feed) {
|
||||
open();
|
||||
Cursor c = db.query(TABLE_NAME_FEED_ITEMS, SEL_FI_SMALL, KEY_FEED
|
||||
+ "=?", new String[] { String.valueOf(feed.getId()) }, null,
|
||||
null, null);
|
||||
return c;
|
||||
}
|
||||
|
||||
/** Return a cursor with the SEL_FI_EXTRA selection of a single feeditem. */
|
||||
public final Cursor getExtraInformationOfItem(final FeedItem item) {
|
||||
open();
|
||||
Cursor c = db
|
||||
.query(TABLE_NAME_FEED_ITEMS, null, KEY_FEED + "=?",
|
||||
new String[] { String.valueOf(feed.getId()) }, null,
|
||||
.query(TABLE_NAME_FEED_ITEMS, SEL_FI_EXTRA, KEY_ID + "=?",
|
||||
new String[] { String.valueOf(item.getId()) }, null,
|
||||
null, null);
|
||||
return c;
|
||||
}
|
||||
|
@ -603,6 +650,47 @@ public class PodDBAdapter {
|
|||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for the given query in the description of all items or the items
|
||||
* of a specified feed.
|
||||
*
|
||||
* @return A cursor with all search results in SEL_FI_EXTRA selection.
|
||||
* */
|
||||
public Cursor searchItemDescriptions(Feed feed, String query) {
|
||||
if (feed != null) {
|
||||
// search items in specific feed
|
||||
return db.query(TABLE_NAME_FEED_ITEMS, SEL_FI_EXTRA, KEY_FEED
|
||||
+ "=? AND " + KEY_DESCRIPTION + " LIKE '%" + query + "%'", new String[] {
|
||||
String.valueOf(feed.getId()) }, null, null, null);
|
||||
} else {
|
||||
// search through all items
|
||||
return db.query(TABLE_NAME_FEED_ITEMS, SEL_FI_EXTRA,
|
||||
KEY_DESCRIPTION + " LIKE '%" + query + "%'", null, null,
|
||||
null, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for the given query in the content-encoded field of all items or
|
||||
* the items of a specified feed.
|
||||
*
|
||||
* @return A cursor with all search results in SEL_FI_EXTRA selection.
|
||||
* */
|
||||
public Cursor searchItemContentEncoded(Feed feed, String query) {
|
||||
if (feed != null) {
|
||||
// search items in specific feed
|
||||
return db.query(TABLE_NAME_FEED_ITEMS, SEL_FI_EXTRA, KEY_FEED
|
||||
+ "=? AND " + KEY_CONTENT_ENCODED + " LIKE '%" + query + "%'",
|
||||
new String[] { String.valueOf(feed.getId())}, null,
|
||||
null, null);
|
||||
} else {
|
||||
// search through all items
|
||||
return db.query(TABLE_NAME_FEED_ITEMS, SEL_FI_EXTRA,
|
||||
KEY_CONTENT_ENCODED + " LIKE '%" + query + "%'", null,
|
||||
null, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
/** Helper class for opening the Antennapod database. */
|
||||
private static class PodDBHelper extends SQLiteOpenHelper {
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue