Nav drawer subscriptions context menu
This commit is contained in:
parent
5643933a51
commit
936ecc2b8e
|
@ -1,5 +1,6 @@
|
|||
package de.danoeh.antennapod.activity;
|
||||
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Configuration;
|
||||
|
@ -13,6 +14,8 @@ import android.support.v4.widget.DrawerLayout;
|
|||
import android.support.v7.app.ActionBarDrawerToggle;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
|
@ -31,6 +34,8 @@ import org.apache.commons.lang3.StringUtils;
|
|||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.adapter.ChapterListAdapter;
|
||||
import de.danoeh.antennapod.adapter.NavListAdapter;
|
||||
import de.danoeh.antennapod.core.asynctask.FeedRemover;
|
||||
import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
|
||||
import de.danoeh.antennapod.core.feed.Chapter;
|
||||
import de.danoeh.antennapod.core.feed.EventDistributor;
|
||||
import de.danoeh.antennapod.core.feed.Feed;
|
||||
|
@ -39,6 +44,7 @@ import de.danoeh.antennapod.core.feed.SimpleChapter;
|
|||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.core.service.playback.PlaybackService;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
import de.danoeh.antennapod.core.storage.DBWriter;
|
||||
import de.danoeh.antennapod.core.util.playback.ExternalMedia;
|
||||
import de.danoeh.antennapod.core.util.playback.Playable;
|
||||
import de.danoeh.antennapod.core.util.playback.PlaybackController;
|
||||
|
@ -430,6 +436,7 @@ public class AudioplayerActivity extends MediaplayerActivity implements ItemDesc
|
|||
drawerLayout.closeDrawer(navDrawer);
|
||||
}
|
||||
});
|
||||
registerForContextMenu(navList);
|
||||
drawerToggle.syncState();
|
||||
|
||||
findViewById(R.id.nav_settings).setOnClickListener(new View.OnClickListener() {
|
||||
|
@ -634,6 +641,65 @@ public class AudioplayerActivity extends MediaplayerActivity implements ItemDesc
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
|
||||
super.onCreateContextMenu(menu, v, menuInfo);
|
||||
if(v.getId() != R.id.nav_list) {
|
||||
return;
|
||||
}
|
||||
AdapterView.AdapterContextMenuInfo adapterInfo = (AdapterView.AdapterContextMenuInfo) menuInfo;
|
||||
int position = adapterInfo.position;
|
||||
if(position < navAdapter.getSubscriptionOffset()) {
|
||||
return;
|
||||
}
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.nav_feed_context, menu);
|
||||
Feed feed = navDrawerData.feeds.get(position - navAdapter.getSubscriptionOffset());
|
||||
menu.setHeaderTitle(feed.getTitle());
|
||||
// episodes are not loaded, so we cannot check if the podcast has new or unplayed ones!
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onContextItemSelected(MenuItem item) {
|
||||
AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
|
||||
if(menuInfo.targetView.getParent() instanceof ListView == false
|
||||
|| ((ListView)menuInfo.targetView.getParent()).getId() != R.id.nav_list) {
|
||||
return false;
|
||||
}
|
||||
int position = menuInfo.position;
|
||||
Feed feed = navDrawerData.feeds.get(position - navAdapter.getSubscriptionOffset());
|
||||
switch(item.getItemId()) {
|
||||
case R.id.mark_all_seen_item:
|
||||
DBWriter.markFeedSeen(this, feed.getId());
|
||||
return true;
|
||||
case R.id.mark_all_read_item:
|
||||
DBWriter.markFeedRead(this, feed.getId());
|
||||
return true;
|
||||
case R.id.remove_item:
|
||||
final FeedRemover remover = new FeedRemover(this, feed) {
|
||||
@Override
|
||||
protected void onPostExecute(Void result) {
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
};
|
||||
ConfirmationDialog conDialog = new ConfirmationDialog(this,
|
||||
R.string.remove_feed_label,
|
||||
R.string.feed_delete_confirmation_msg) {
|
||||
@Override
|
||||
public void onConfirmButtonPressed(
|
||||
DialogInterface dialog) {
|
||||
dialog.dismiss();
|
||||
remover.executeAsync();
|
||||
}
|
||||
};
|
||||
conDialog.createNewDialog().show();
|
||||
return true;
|
||||
default:
|
||||
return super.onContextItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private DBReader.NavDrawerData navDrawerData;
|
||||
private AsyncTask<Void, Void, DBReader.NavDrawerData> loadTask;
|
||||
|
||||
|
@ -708,8 +774,8 @@ public class AudioplayerActivity extends MediaplayerActivity implements ItemDesc
|
|||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfUnreadFeedItems(long feedId) {
|
||||
return (navDrawerData != null) ? navDrawerData.numUnreadFeedItems.get(feedId) : 0;
|
||||
public int getFeedCounter(long feedId) {
|
||||
return navDrawerData != null ? navDrawerData.feedCounters.get(feedId) : 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@ import android.support.v7.app.ActionBarActivity;
|
|||
import android.support.v7.app.ActionBarDrawerToggle;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
|
@ -32,12 +34,15 @@ import java.util.List;
|
|||
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.adapter.NavListAdapter;
|
||||
import de.danoeh.antennapod.core.asynctask.FeedRemover;
|
||||
import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
|
||||
import de.danoeh.antennapod.core.event.ProgressEvent;
|
||||
import de.danoeh.antennapod.core.feed.EventDistributor;
|
||||
import de.danoeh.antennapod.core.feed.Feed;
|
||||
import de.danoeh.antennapod.core.feed.QueueEvent;
|
||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
import de.danoeh.antennapod.core.storage.DBWriter;
|
||||
import de.danoeh.antennapod.core.util.StorageUtils;
|
||||
import de.danoeh.antennapod.fragment.AddFeedFragment;
|
||||
import de.danoeh.antennapod.fragment.AllEpisodesFragment;
|
||||
|
@ -140,6 +145,7 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
|
|||
navList.setAdapter(navAdapter);
|
||||
navList.setOnItemClickListener(navListClickListener);
|
||||
navList.setOnItemLongClickListener(newListLongClickListener);
|
||||
registerForContextMenu(navList);
|
||||
|
||||
navAdapter.registerDataSetObserver(new DataSetObserver() {
|
||||
@Override
|
||||
|
@ -493,6 +499,64 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
|
||||
super.onCreateContextMenu(menu, v, menuInfo);
|
||||
if(v.getId() != R.id.nav_list) {
|
||||
return;
|
||||
}
|
||||
AdapterView.AdapterContextMenuInfo adapterInfo = (AdapterView.AdapterContextMenuInfo) menuInfo;
|
||||
int position = adapterInfo.position;
|
||||
if(position < navAdapter.getSubscriptionOffset()) {
|
||||
return;
|
||||
}
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.nav_feed_context, menu);
|
||||
Feed feed = navDrawerData.feeds.get(position - navAdapter.getSubscriptionOffset());
|
||||
menu.setHeaderTitle(feed.getTitle());
|
||||
// episodes are not loaded, so we cannot check if the podcast has new or unplayed ones!
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onContextItemSelected(MenuItem item) {
|
||||
AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
|
||||
if(menuInfo.targetView.getParent() instanceof ListView == false
|
||||
|| ((ListView)menuInfo.targetView.getParent()).getId() != R.id.nav_list) {
|
||||
return false;
|
||||
}
|
||||
int position = menuInfo.position;
|
||||
Feed feed = navDrawerData.feeds.get(position - navAdapter.getSubscriptionOffset());
|
||||
switch(item.getItemId()) {
|
||||
case R.id.mark_all_seen_item:
|
||||
DBWriter.markFeedSeen(this, feed.getId());
|
||||
return true;
|
||||
case R.id.mark_all_read_item:
|
||||
DBWriter.markFeedRead(this, feed.getId());
|
||||
return true;
|
||||
case R.id.remove_item:
|
||||
final FeedRemover remover = new FeedRemover(this, feed) {
|
||||
@Override
|
||||
protected void onPostExecute(Void result) {
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
};
|
||||
ConfirmationDialog conDialog = new ConfirmationDialog(this,
|
||||
R.string.remove_feed_label,
|
||||
R.string.feed_delete_confirmation_msg) {
|
||||
@Override
|
||||
public void onConfirmButtonPressed(
|
||||
DialogInterface dialog) {
|
||||
dialog.dismiss();
|
||||
remover.executeAsync();
|
||||
}
|
||||
};
|
||||
conDialog.createNewDialog().show();
|
||||
return true;
|
||||
default:
|
||||
return super.onContextItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
private DBReader.NavDrawerData navDrawerData;
|
||||
private AsyncTask<Void, Void, DBReader.NavDrawerData> loadTask;
|
||||
private int selectedNavListIndex = 0;
|
||||
|
@ -532,8 +596,8 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
|
|||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfUnreadFeedItems(long feedId) {
|
||||
return (navDrawerData != null) ? navDrawerData.numUnreadFeedItems.get(feedId) : 0;
|
||||
public int getFeedCounter(long feedId) {
|
||||
return navDrawerData != null ? navDrawerData.feedCounters.get(feedId) : 0;
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -276,10 +276,10 @@ public class NavListAdapter extends BaseAdapter
|
|||
p.addRule(RelativeLayout.LEFT_OF, R.id.txtvCount);
|
||||
holder.failure.setVisibility(View.GONE);
|
||||
}
|
||||
int feedUnreadItems = itemAccess.getNumberOfUnreadFeedItems(feed.getId());
|
||||
if(feedUnreadItems > 0) {
|
||||
int counter = itemAccess.getFeedCounter(feed.getId());
|
||||
if(counter > 0) {
|
||||
holder.count.setVisibility(View.VISIBLE);
|
||||
holder.count.setText(String.valueOf(feedUnreadItems));
|
||||
holder.count.setText(String.valueOf(counter));
|
||||
holder.count.setTypeface(holder.title.getTypeface());
|
||||
} else {
|
||||
holder.count.setVisibility(View.GONE);
|
||||
|
@ -306,7 +306,7 @@ public class NavListAdapter extends BaseAdapter
|
|||
int getSelectedItemIndex();
|
||||
int getQueueSize();
|
||||
int getNumberOfNewItems();
|
||||
int getNumberOfUnreadFeedItems(long feedId);
|
||||
int getFeedCounter(long feedId);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ public class ClientConfigurator {
|
|||
ClientConfig.downloadServiceCallbacks = new DownloadServiceCallbacksImpl();
|
||||
ClientConfig.gpodnetCallbacks = new GpodnetCallbacksImpl();
|
||||
ClientConfig.playbackServiceCallbacks = new PlaybackServiceCallbacksImpl();
|
||||
ClientConfig.storageCallbacks = new StorageCallbacksImpl();
|
||||
ClientConfig.flattrCallbacks = new FlattrCallbacksImpl();
|
||||
ClientConfig.dbTasksCallbacks = new DBTasksCallbacksImpl();
|
||||
}
|
||||
|
|
|
@ -1,206 +0,0 @@
|
|||
package de.danoeh.antennapod.config;
|
||||
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.media.MediaMetadataRetriever;
|
||||
import android.util.Log;
|
||||
|
||||
import de.danoeh.antennapod.core.StorageCallbacks;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.storage.PodDBAdapter;
|
||||
|
||||
public class StorageCallbacksImpl implements StorageCallbacks {
|
||||
|
||||
@Override
|
||||
public int getDatabaseVersion() {
|
||||
return 17;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpgrade(final SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||
Log.w("DBAdapter", "Upgrading from version " + oldVersion + " to "
|
||||
+ newVersion + ".");
|
||||
if (oldVersion <= 1) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + " ADD COLUMN "
|
||||
+ PodDBAdapter.KEY_TYPE + " TEXT");
|
||||
}
|
||||
if (oldVersion <= 2) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_LINK + " TEXT");
|
||||
}
|
||||
if (oldVersion <= 3) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_ITEM_IDENTIFIER + " TEXT");
|
||||
}
|
||||
if (oldVersion <= 4) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + " ADD COLUMN "
|
||||
+ PodDBAdapter.KEY_FEED_IDENTIFIER + " TEXT");
|
||||
}
|
||||
if (oldVersion <= 5) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_DOWNLOAD_LOG
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_REASON_DETAILED + " TEXT");
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_DOWNLOAD_LOG
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_DOWNLOADSTATUS_TITLE + " TEXT");
|
||||
}
|
||||
if (oldVersion <= 6) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_CHAPTER_TYPE + " INTEGER");
|
||||
}
|
||||
if (oldVersion <= 7) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_PLAYBACK_COMPLETION_DATE
|
||||
+ " INTEGER");
|
||||
}
|
||||
if (oldVersion <= 8) {
|
||||
final int KEY_ID_POSITION = 0;
|
||||
final int KEY_MEDIA_POSITION = 1;
|
||||
|
||||
// Add feeditem column to feedmedia table
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_FEEDITEM
|
||||
+ " INTEGER");
|
||||
Cursor feeditemCursor = db.query(PodDBAdapter.TABLE_NAME_FEED_ITEMS,
|
||||
new String[]{PodDBAdapter.KEY_ID, PodDBAdapter.KEY_MEDIA}, "? > 0",
|
||||
new String[]{PodDBAdapter.KEY_MEDIA}, null, null, null);
|
||||
if (feeditemCursor.moveToFirst()) {
|
||||
db.beginTransaction();
|
||||
ContentValues contentValues = new ContentValues();
|
||||
do {
|
||||
long mediaId = feeditemCursor.getLong(KEY_MEDIA_POSITION);
|
||||
contentValues.put(PodDBAdapter.KEY_FEEDITEM, feeditemCursor.getLong(KEY_ID_POSITION));
|
||||
db.update(PodDBAdapter.TABLE_NAME_FEED_MEDIA, contentValues, PodDBAdapter.KEY_ID + "=?", new String[]{String.valueOf(mediaId)});
|
||||
contentValues.clear();
|
||||
} while (feeditemCursor.moveToNext());
|
||||
db.setTransactionSuccessful();
|
||||
db.endTransaction();
|
||||
}
|
||||
feeditemCursor.close();
|
||||
}
|
||||
if (oldVersion <= 9) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_AUTO_DOWNLOAD
|
||||
+ " INTEGER DEFAULT 1");
|
||||
}
|
||||
if (oldVersion <= 10) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_FLATTR_STATUS
|
||||
+ " INTEGER");
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_FLATTR_STATUS
|
||||
+ " INTEGER");
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_PLAYED_DURATION
|
||||
+ " INTEGER");
|
||||
}
|
||||
if (oldVersion <= 11) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_USERNAME
|
||||
+ " TEXT");
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_PASSWORD
|
||||
+ " TEXT");
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_IMAGE
|
||||
+ " INTEGER");
|
||||
}
|
||||
if (oldVersion <= 12) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_IS_PAGED + " INTEGER DEFAULT 0");
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_NEXT_PAGE_LINK + " TEXT");
|
||||
}
|
||||
if (oldVersion <= 13) {
|
||||
// remove duplicate rows in "Chapters" table that were created because of a bug.
|
||||
db.execSQL(String.format("DELETE FROM %s WHERE %s NOT IN " +
|
||||
"(SELECT MIN(%s) as %s FROM %s GROUP BY %s,%s,%s,%s,%s)",
|
||||
PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS,
|
||||
PodDBAdapter.KEY_ID,
|
||||
PodDBAdapter.KEY_ID,
|
||||
PodDBAdapter.KEY_ID,
|
||||
PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS,
|
||||
PodDBAdapter.KEY_TITLE,
|
||||
PodDBAdapter.KEY_START,
|
||||
PodDBAdapter.KEY_FEEDITEM,
|
||||
PodDBAdapter.KEY_LINK,
|
||||
PodDBAdapter.KEY_CHAPTER_TYPE));
|
||||
}
|
||||
if(oldVersion <= 14) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_AUTO_DOWNLOAD + " INTEGER");
|
||||
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
|
||||
+ " SET " + PodDBAdapter.KEY_AUTO_DOWNLOAD + " = "
|
||||
+ "(SELECT " + PodDBAdapter.KEY_AUTO_DOWNLOAD
|
||||
+ " FROM " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " WHERE " + PodDBAdapter.TABLE_NAME_FEEDS + "." + PodDBAdapter.KEY_ID
|
||||
+ " = " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + PodDBAdapter.KEY_FEED + ")");
|
||||
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_HIDE + " TEXT");
|
||||
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_LAST_UPDATE_FAILED + " INTEGER DEFAULT 0");
|
||||
|
||||
// create indexes
|
||||
db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_FEED);
|
||||
db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_IMAGE);
|
||||
db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDMEDIA_FEEDITEM);
|
||||
db.execSQL(PodDBAdapter.CREATE_INDEX_QUEUE_FEEDITEM);
|
||||
db.execSQL(PodDBAdapter.CREATE_INDEX_SIMPLECHAPTERS_FEEDITEM);
|
||||
}
|
||||
if(oldVersion <= 15) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_HAS_EMBEDDED_PICTURE + " INTEGER DEFAULT -1");
|
||||
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
|
||||
+ " SET " + PodDBAdapter.KEY_HAS_EMBEDDED_PICTURE + "=0"
|
||||
+ " WHERE " + PodDBAdapter.KEY_DOWNLOADED + "=0");
|
||||
Cursor c = db.rawQuery("SELECT " + PodDBAdapter.KEY_FILE_URL
|
||||
+ " FROM " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
|
||||
+ " WHERE " + PodDBAdapter.KEY_DOWNLOADED + "=1 "
|
||||
+ " AND " + PodDBAdapter.KEY_HAS_EMBEDDED_PICTURE + "=-1", null);
|
||||
if(c.moveToFirst()) {
|
||||
MediaMetadataRetriever mmr = new MediaMetadataRetriever();
|
||||
do {
|
||||
String fileUrl = c.getString(0);
|
||||
try {
|
||||
mmr.setDataSource(fileUrl);
|
||||
byte[] image = mmr.getEmbeddedPicture();
|
||||
if (image != null) {
|
||||
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
|
||||
+ " SET " + PodDBAdapter.KEY_HAS_EMBEDDED_PICTURE + "=1"
|
||||
+ " WHERE " + PodDBAdapter.KEY_FILE_URL + "='"+ fileUrl + "'");
|
||||
} else {
|
||||
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
|
||||
+ " SET " + PodDBAdapter.KEY_HAS_EMBEDDED_PICTURE + "=0"
|
||||
+ " WHERE " + PodDBAdapter.KEY_FILE_URL + "='"+ fileUrl + "'");
|
||||
}
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} while(c.moveToNext());
|
||||
}
|
||||
c.close();
|
||||
}
|
||||
if(oldVersion <= 17) {
|
||||
String selectNew = "SELECT " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + PodDBAdapter.KEY_ID
|
||||
+ " FROM " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
|
||||
+ " INNER JOIN " + PodDBAdapter.TABLE_NAME_FEED_MEDIA + " ON "
|
||||
+ PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + PodDBAdapter.KEY_ID + "="
|
||||
+ PodDBAdapter.TABLE_NAME_FEED_MEDIA + "." + PodDBAdapter.KEY_FEEDITEM
|
||||
+ " LEFT OUTER JOIN " + PodDBAdapter.TABLE_NAME_QUEUE + " ON "
|
||||
+ PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + PodDBAdapter.KEY_ID + "="
|
||||
+ PodDBAdapter.TABLE_NAME_QUEUE + "." + PodDBAdapter.KEY_FEEDITEM
|
||||
+ " WHERE "
|
||||
+ PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + PodDBAdapter.KEY_READ + " = 0 AND " // unplayed
|
||||
+ PodDBAdapter.TABLE_NAME_FEED_MEDIA + "." + PodDBAdapter.KEY_DOWNLOADED + " = 0 AND " // undownloaded
|
||||
+ PodDBAdapter.TABLE_NAME_FEED_MEDIA + "." + PodDBAdapter.KEY_POSITION + " = 0 AND " // not partially played
|
||||
+ PodDBAdapter.TABLE_NAME_QUEUE + "." + PodDBAdapter.KEY_ID + " IS NULL"; // not in queue
|
||||
String sql = "UPDATE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
|
||||
+ " SET " + PodDBAdapter.KEY_READ + "=" + FeedItem.NEW
|
||||
+ " WHERE " + PodDBAdapter.KEY_ID + " IN (" + selectNew + ")";
|
||||
Log.d("Migration", "SQL: " + sql);
|
||||
db.execSQL(sql);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,8 +5,6 @@ import android.graphics.Color;
|
|||
import android.os.Bundle;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
|
@ -316,7 +314,7 @@ public class EpisodesApplyActionFragment extends Fragment {
|
|||
|
||||
private void checkPlayed(boolean isPlayed) {
|
||||
for (FeedItem episode : episodes) {
|
||||
if(episode.isRead() == isPlayed) {
|
||||
if(episode.isPlayed() == isPlayed) {
|
||||
if(!checkedIds.contains(episode.getId())) {
|
||||
checkedIds.add(episode.getId());
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item
|
||||
android:id="@+id/mark_all_seen_item"
|
||||
android:menuCategory="container"
|
||||
android:title="@string/mark_all_seen_label" />
|
||||
|
||||
<item
|
||||
android:id="@+id/mark_all_read_item"
|
||||
android:menuCategory="container"
|
||||
android:title="@string/mark_all_read_label" />
|
||||
|
||||
<item
|
||||
android:id="@+id/remove_item"
|
||||
android:menuCategory="container"
|
||||
android:title="@string/remove_feed_label" />
|
||||
|
||||
</menu>
|
|
@ -21,7 +21,5 @@ public class ClientConfig {
|
|||
|
||||
public static FlattrCallbacks flattrCallbacks;
|
||||
|
||||
public static StorageCallbacks storageCallbacks;
|
||||
|
||||
public static DBTasksCallbacks dbTasksCallbacks;
|
||||
}
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
package de.danoeh.antennapod.core;
|
||||
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
|
||||
/**
|
||||
* Callbacks for the classes in the storage package of the core module.
|
||||
*/
|
||||
public interface StorageCallbacks {
|
||||
|
||||
/**
|
||||
* Returns the current version of the database.
|
||||
*
|
||||
* @return The non-negative version number of the database.
|
||||
*/
|
||||
public int getDatabaseVersion();
|
||||
|
||||
/**
|
||||
* Upgrades the given database from an old version to a newer version.
|
||||
*
|
||||
* @param db The database that is supposed to be upgraded.
|
||||
* @param oldVersion The old version of the database.
|
||||
* @param newVersion The version that the database is supposed to be upgraded to.
|
||||
*/
|
||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion);
|
||||
|
||||
|
||||
}
|
|
@ -177,10 +177,21 @@ public class Feed extends FeedFile implements FlattrThing, PicassoImageResource
|
|||
*/
|
||||
public boolean hasNewItems() {
|
||||
for (FeedItem item : items) {
|
||||
if (item.getState() == FeedItem.State.UNREAD) {
|
||||
if (item.getMedia() != null) {
|
||||
return true;
|
||||
}
|
||||
if (item.isNew()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if at least one item in the itemlist is unread.
|
||||
*
|
||||
*/
|
||||
public boolean hasUnplayedItems() {
|
||||
for (FeedItem item : items) {
|
||||
if (false == item.isNew() && false == item.isPlayed()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -1,139 +0,0 @@
|
|||
package de.danoeh.antennapod.core.storage;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
|
||||
/**
|
||||
* Implementation of the EpisodeCleanupAlgorithm interface used by AntennaPodSP apps.
|
||||
*/
|
||||
public class APSPCleanupAlgorithm implements EpisodeCleanupAlgorithm<Integer> {
|
||||
private static final String TAG = "APSPCleanupAlgorithm";
|
||||
|
||||
final int numberOfNewAutomaticallyDownloadedEpisodes;
|
||||
|
||||
public APSPCleanupAlgorithm(int numberOfNewAutomaticallyDownloadedEpisodes) {
|
||||
this.numberOfNewAutomaticallyDownloadedEpisodes = numberOfNewAutomaticallyDownloadedEpisodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs an automatic cleanup. Episodes that have been downloaded first will also be deleted first.
|
||||
* The episode that is currently playing as well as the n most recent episodes (the exact value is determined
|
||||
* by AppPreferences.numberOfNewAutomaticallyDownloadedEpisodes) will never be deleted.
|
||||
*
|
||||
* @param context
|
||||
* @param episodeSize The maximum amount of space that should be freed by this method
|
||||
* @return The number of episodes that have been deleted
|
||||
*/
|
||||
@Override
|
||||
public int performCleanup(Context context, Integer episodeSize) {
|
||||
Log.i(TAG, String.format("performAutoCleanup(%d)", episodeSize));
|
||||
if (episodeSize <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
List<FeedItem> candidates = getAutoCleanupCandidates(context);
|
||||
List<FeedItem> deleteList = new ArrayList<FeedItem>();
|
||||
long deletedEpisodesSize = 0;
|
||||
Collections.sort(candidates, new Comparator<FeedItem>() {
|
||||
@Override
|
||||
public int compare(FeedItem lhs, FeedItem rhs) {
|
||||
File lFile = new File(lhs.getMedia().getFile_url());
|
||||
File rFile = new File(rhs.getMedia().getFile_url());
|
||||
if (!lFile.exists() || !rFile.exists()) {
|
||||
return 0;
|
||||
}
|
||||
if (FileUtils.isFileOlder(lFile, rFile)) {
|
||||
return -1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
});
|
||||
// listened episodes will be deleted first
|
||||
Iterator<FeedItem> it = candidates.iterator();
|
||||
if (it.hasNext()) {
|
||||
for (FeedItem i = it.next(); it.hasNext() && deletedEpisodesSize <= episodeSize; i = it.next()) {
|
||||
if (!i.getMedia().isPlaying() && i.getMedia().getPlaybackCompletionDate() != null) {
|
||||
it.remove();
|
||||
deleteList.add(i);
|
||||
deletedEpisodesSize += i.getMedia().getSize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// delete unlistened old episodes if necessary
|
||||
it = candidates.iterator();
|
||||
if (it.hasNext()) {
|
||||
for (FeedItem i = it.next(); it.hasNext() && deletedEpisodesSize <= episodeSize; i = it.next()) {
|
||||
if (!i.getMedia().isPlaying()) {
|
||||
it.remove();
|
||||
deleteList.add(i);
|
||||
deletedEpisodesSize += i.getMedia().getSize();
|
||||
}
|
||||
}
|
||||
}
|
||||
for (FeedItem item : deleteList) {
|
||||
try {
|
||||
DBWriter.deleteFeedMediaOfItem(context, item.getMedia().getId()).get();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
Log.i(TAG, String.format("performAutoCleanup(%d) deleted %d episodes and freed %d bytes of memory",
|
||||
episodeSize, deleteList.size(), deletedEpisodesSize));
|
||||
return deleteList.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getDefaultCleanupParameter(Context context) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getPerformCleanupParameter(Context context, List<FeedItem> items) {
|
||||
int episodeSize = 0;
|
||||
for (FeedItem item : items) {
|
||||
if (item.hasMedia() && !item.getMedia().isDownloaded()) {
|
||||
episodeSize += item.getMedia().getSize();
|
||||
}
|
||||
}
|
||||
return episodeSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of FeedItems that have been downloaded, but are not one of the
|
||||
* [numberOfNewAutomaticallyDownloadedEpisodes] most recent items.
|
||||
*/
|
||||
private List<FeedItem> getAutoCleanupCandidates(Context context) {
|
||||
List<FeedItem> downloaded = new ArrayList<FeedItem>(DBReader.getDownloadedItems(context));
|
||||
List<FeedItem> recent = new ArrayList<FeedItem>(DBReader.getRecentlyPublishedEpisodes(context,
|
||||
numberOfNewAutomaticallyDownloadedEpisodes));
|
||||
for (FeedItem r : recent) {
|
||||
if (r.hasMedia() && r.getMedia().isDownloaded()) {
|
||||
for (int i = 0; i < downloaded.size(); i++) {
|
||||
if (downloaded.get(i).getId() == r.getId()) {
|
||||
downloaded.remove(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return downloaded;
|
||||
|
||||
}
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
package de.danoeh.antennapod.core.storage;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import de.danoeh.antennapod.core.BuildConfig;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.core.util.NetworkUtils;
|
||||
|
||||
/**
|
||||
* Implements the automatic download algorithm used by AntennaPodSP apps.
|
||||
*/
|
||||
public class APSPDownloadAlgorithm implements AutomaticDownloadAlgorithm {
|
||||
private static final String TAG = "APSPDownloadAlgorithm";
|
||||
|
||||
private final int numberOfNewAutomaticallyDownloadedEpisodes;
|
||||
|
||||
public APSPDownloadAlgorithm(int numberOfNewAutomaticallyDownloadedEpisodes) {
|
||||
this.numberOfNewAutomaticallyDownloadedEpisodes = numberOfNewAutomaticallyDownloadedEpisodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Downloads the most recent episodes automatically. The exact number of
|
||||
* episodes that will be downloaded can be set in the AppPreferences.
|
||||
*
|
||||
* @param context Used for accessing the DB.
|
||||
* @return A Runnable that will be submitted to an ExecutorService.
|
||||
*/
|
||||
@Override
|
||||
public Runnable autoDownloadUndownloadedItems(final Context context, final long... mediaIds) {
|
||||
return new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (BuildConfig.DEBUG)
|
||||
Log.d(TAG, "Performing auto-dl of undownloaded episodes");
|
||||
if (NetworkUtils.autodownloadNetworkAvailable(context)
|
||||
&& UserPreferences.isEnableAutodownload()) {
|
||||
|
||||
Arrays.sort(mediaIds);
|
||||
List<FeedItem> itemsToDownload = DBReader.getRecentlyPublishedEpisodes(context,
|
||||
numberOfNewAutomaticallyDownloadedEpisodes);
|
||||
Iterator<FeedItem> it = itemsToDownload.iterator();
|
||||
|
||||
for (FeedItem item = it.next(); it.hasNext(); item = it.next()) {
|
||||
if (!item.hasMedia()
|
||||
|| item.getMedia().isDownloaded()
|
||||
|| Arrays.binarySearch(mediaIds, item.getMedia().getId()) < 0) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
if (BuildConfig.DEBUG)
|
||||
Log.d(TAG, "Enqueueing " + itemsToDownload.size()
|
||||
+ " items for automatic download");
|
||||
if (!itemsToDownload.isEmpty()) {
|
||||
try {
|
||||
DBTasks.downloadFeedItems(false, context,
|
||||
itemsToDownload.toArray(new FeedItem[itemsToDownload
|
||||
.size()]));
|
||||
} catch (DownloadRequestException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -22,6 +22,7 @@ import de.danoeh.antennapod.core.feed.FeedPreferences;
|
|||
import de.danoeh.antennapod.core.feed.ID3Chapter;
|
||||
import de.danoeh.antennapod.core.feed.SimpleChapter;
|
||||
import de.danoeh.antennapod.core.feed.VorbisCommentChapter;
|
||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.core.service.download.DownloadStatus;
|
||||
import de.danoeh.antennapod.core.util.DownloadError;
|
||||
import de.danoeh.antennapod.core.util.LongIntMap;
|
||||
|
@ -1139,27 +1140,42 @@ public final class DBReader {
|
|||
for(int i=0; i < feeds.size(); i++) {
|
||||
feedIds[i] = feeds.get(i).getId();
|
||||
}
|
||||
final LongIntMap numUnreadFeedItems = adapter.getNumberOfUnreadFeedItems(feedIds);
|
||||
Collections.sort(feeds, new Comparator<Feed>() {
|
||||
@Override
|
||||
public int compare(Feed lhs, Feed rhs) {
|
||||
long numUnreadLhs = numUnreadFeedItems.get(lhs.getId());
|
||||
Log.d(TAG, "feed with id " + lhs.getId() + " has " + numUnreadLhs + " unread items");
|
||||
long numUnreadRhs = numUnreadFeedItems.get(rhs.getId());
|
||||
Log.d(TAG, "feed with id " + rhs.getId() + " has " + numUnreadRhs + " unread items");
|
||||
if(numUnreadLhs > numUnreadRhs) {
|
||||
// reverse natural order: podcast with most unplayed episodes first
|
||||
return -1;
|
||||
} else if(numUnreadLhs == numUnreadRhs) {
|
||||
return lhs.getTitle().compareTo(rhs.getTitle());
|
||||
} else {
|
||||
return 1;
|
||||
final LongIntMap feedCounters = adapter.getFeedCounters(feedIds);
|
||||
|
||||
Comparator<Feed> comparator;
|
||||
int feedOrder = UserPreferences.getFeedOrder();
|
||||
if(feedOrder == UserPreferences.ORDER_UNPLAYED_EPISODES) {
|
||||
comparator = new Comparator<Feed>() {
|
||||
@Override
|
||||
public int compare(Feed lhs, Feed rhs) {
|
||||
long counterLhs = feedCounters.get(lhs.getId());
|
||||
long counterRhs = feedCounters.get(rhs.getId());
|
||||
if(counterLhs > counterRhs) {
|
||||
// reverse natural order: podcast with most unplayed episodes first
|
||||
return -1;
|
||||
} else if(counterLhs == counterRhs) {
|
||||
return lhs.getTitle().compareTo(rhs.getTitle());
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
} else {
|
||||
comparator = new Comparator<Feed>() {
|
||||
@Override
|
||||
public int compare(Feed lhs, Feed rhs) {
|
||||
if(lhs.getTitle() == null) {
|
||||
return 1;
|
||||
}
|
||||
return lhs.getTitle().compareTo(rhs.getTitle());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Collections.sort(feeds, comparator);
|
||||
int queueSize = adapter.getQueueSize();
|
||||
int numNewItems = adapter.getNumberOfNewItems();
|
||||
NavDrawerData result = new NavDrawerData(feeds, queueSize, numNewItems, numUnreadFeedItems);
|
||||
NavDrawerData result = new NavDrawerData(feeds, queueSize, numNewItems, feedCounters);
|
||||
adapter.close();
|
||||
return result;
|
||||
}
|
||||
|
@ -1168,14 +1184,16 @@ public final class DBReader {
|
|||
public List<Feed> feeds;
|
||||
public int queueSize;
|
||||
public int numNewItems;
|
||||
public LongIntMap numUnreadFeedItems;
|
||||
public LongIntMap feedCounters;
|
||||
|
||||
public NavDrawerData(List<Feed> feeds, int queueSize, int numNewItems,
|
||||
LongIntMap numUnreadFeedItems) {
|
||||
public NavDrawerData(List<Feed> feeds,
|
||||
int queueSize,
|
||||
int numNewItems,
|
||||
LongIntMap feedIndicatorValues) {
|
||||
this.feeds = feeds;
|
||||
this.queueSize = queueSize;
|
||||
this.numNewItems = numNewItems;
|
||||
this.numUnreadFeedItems = numUnreadFeedItems;
|
||||
this.feedCounters = feedIndicatorValues;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -409,8 +409,8 @@ public class DBWriter {
|
|||
if (item != null) {
|
||||
// add item to either front ot back of queue
|
||||
boolean addToFront = UserPreferences.enqueueAtFront();
|
||||
if(addToFront){
|
||||
queue.add(0+i, item);
|
||||
if (addToFront) {
|
||||
queue.add(0 + i, item);
|
||||
} else {
|
||||
queue.add(item);
|
||||
}
|
||||
|
@ -610,7 +610,8 @@ public class DBWriter {
|
|||
public void run() {
|
||||
final PodDBAdapter adapter = new PodDBAdapter(context);
|
||||
adapter.open();
|
||||
adapter.setFeedItemRead(read, itemIds);
|
||||
int played = read ? FeedItem.PLAYED : FeedItem.UNPLAYED;
|
||||
adapter.setFeedItemRead(played, itemIds);
|
||||
adapter.close();
|
||||
EventDistributor.getInstance().sendUnreadItemsUpdateBroadcast();
|
||||
}
|
||||
|
@ -650,6 +651,35 @@ public class DBWriter {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the 'read'-attribute of all FeedItems of a specific Feed to true.
|
||||
*
|
||||
* @param context A context that is used for opening a database connection.
|
||||
* @param feedId ID of the Feed.
|
||||
*/
|
||||
public static Future<?> markFeedSeen(final Context context, final long feedId) {
|
||||
return dbExec.submit(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
final PodDBAdapter adapter = new PodDBAdapter(context);
|
||||
adapter.open();
|
||||
Cursor itemCursor = adapter.getNewItemsIdsCursor(feedId);
|
||||
long[] ids = new long[itemCursor.getCount()];
|
||||
itemCursor.moveToFirst();
|
||||
for (int i = 0; i < ids.length; i++) {
|
||||
ids[i] = itemCursor.getLong(0);
|
||||
itemCursor.moveToNext();
|
||||
}
|
||||
itemCursor.close();
|
||||
adapter.setFeedItemRead(FeedItem.UNPLAYED, ids);
|
||||
adapter.close();
|
||||
|
||||
EventDistributor.getInstance().sendUnreadItemsUpdateBroadcast();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the 'read'-attribute of all FeedItems of a specific Feed to true.
|
||||
*
|
||||
|
@ -677,7 +707,6 @@ public class DBWriter {
|
|||
EventDistributor.getInstance().sendUnreadItemsUpdateBroadcast();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -9,6 +9,7 @@ import android.database.SQLException;
|
|||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteDatabase.CursorFactory;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.media.MediaMetadataRetriever;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
|
@ -18,7 +19,6 @@ import java.util.Arrays;
|
|||
import java.util.List;
|
||||
|
||||
import de.danoeh.antennapod.core.BuildConfig;
|
||||
import de.danoeh.antennapod.core.ClientConfig;
|
||||
import de.danoeh.antennapod.core.R;
|
||||
import de.danoeh.antennapod.core.event.ProgressEvent;
|
||||
import de.danoeh.antennapod.core.feed.Chapter;
|
||||
|
@ -28,13 +28,12 @@ import de.danoeh.antennapod.core.feed.FeedImage;
|
|||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||
import de.danoeh.antennapod.core.feed.FeedPreferences;
|
||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.core.service.download.DownloadStatus;
|
||||
import de.danoeh.antennapod.core.util.LongIntMap;
|
||||
import de.danoeh.antennapod.core.util.flattr.FlattrStatus;
|
||||
import de.greenrobot.event.EventBus;
|
||||
|
||||
;
|
||||
|
||||
// TODO Remove media column from feeditem table
|
||||
|
||||
/**
|
||||
|
@ -369,8 +368,7 @@ public class PodDBAdapter {
|
|||
|
||||
private static synchronized PodDBHelper getDbHelperSingleton(Context appContext) {
|
||||
if (dbHelperSingleton == null) {
|
||||
dbHelperSingleton = new PodDBHelper(appContext, DATABASE_NAME, null,
|
||||
ClientConfig.storageCallbacks.getDatabaseVersion());
|
||||
dbHelperSingleton = new PodDBHelper(appContext, DATABASE_NAME, null);
|
||||
}
|
||||
return dbHelperSingleton;
|
||||
}
|
||||
|
@ -1113,6 +1111,20 @@ public class PodDBAdapter {
|
|||
return db.rawQuery(query, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a cursor which contains all items of a feed that are considered new.
|
||||
* The returned cursor uses the FEEDITEM_SEL_FI_SMALL selection.
|
||||
*/
|
||||
public final Cursor getNewItemsIdsCursor(long feedId) {
|
||||
final String query = "SELECT " + KEY_ID
|
||||
+ " FROM " + TABLE_NAME_FEED_ITEMS
|
||||
+ " WHERE " + KEY_FEED + "=" + feedId
|
||||
+ " AND " + KEY_READ + "=" + FeedItem.NEW
|
||||
+ " ORDER BY " + KEY_PUBDATE + " DESC";
|
||||
Cursor c = db.rawQuery(query, null);
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a cursor which contains all feed items that are considered new.
|
||||
* The returned cursor uses the FEEDITEM_SEL_FI_SMALL selection.
|
||||
|
@ -1282,7 +1294,20 @@ public class PodDBAdapter {
|
|||
return result;
|
||||
}
|
||||
|
||||
public final LongIntMap getNumberOfUnreadFeedItems(long... feedIds) {
|
||||
public final LongIntMap getFeedCounters(long... feedIds) {
|
||||
int indicator = UserPreferences.getFeedIndicator();
|
||||
String whereRead;
|
||||
if(indicator == UserPreferences.SHOW_NEW_UNPLAYED_SUM) {
|
||||
whereRead = "(" + KEY_READ + "=" + FeedItem.NEW
|
||||
+ " OR " + KEY_READ + "=" + FeedItem.UNPLAYED + ")";
|
||||
} else if(indicator == UserPreferences.SHOW_NEW) {
|
||||
whereRead = KEY_READ + "=" + FeedItem.NEW;
|
||||
} else if(indicator == UserPreferences.SHOW_UNPLAYED) {
|
||||
whereRead = KEY_READ + "=" + FeedItem.UNPLAYED;
|
||||
} else {
|
||||
return new LongIntMap(0);
|
||||
}
|
||||
|
||||
// work around TextUtils.join wanting only boxed items
|
||||
// and StringUtils.join() causing NoSuchMethodErrors on MIUI
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
@ -1298,9 +1323,8 @@ public class PodDBAdapter {
|
|||
final String query = "SELECT " + KEY_FEED + ", COUNT(" + KEY_ID + ") AS count "
|
||||
+ " FROM " + TABLE_NAME_FEED_ITEMS
|
||||
+ " WHERE " + KEY_FEED + " IN (" + builder.toString() + ") "
|
||||
+ " AND (" + KEY_READ + "=" + FeedItem.NEW
|
||||
+ " OR " + KEY_READ + "=" + FeedItem.UNPLAYED + ")"
|
||||
+ " GROUP BY " + KEY_FEED;
|
||||
+ " AND " + whereRead + " GROUP BY " + KEY_FEED;
|
||||
|
||||
Cursor c = db.rawQuery(query, null);
|
||||
LongIntMap result = new LongIntMap(c.getCount());
|
||||
if (c.moveToFirst()) {
|
||||
|
@ -1454,6 +1478,8 @@ public class PodDBAdapter {
|
|||
*/
|
||||
private static class PodDBHelper extends SQLiteOpenHelper {
|
||||
|
||||
private final static int VERSION = 17;
|
||||
|
||||
private Context context;
|
||||
|
||||
/**
|
||||
|
@ -1462,11 +1488,10 @@ public class PodDBAdapter {
|
|||
* @param context Context to use
|
||||
* @param name Name of the database
|
||||
* @param factory to use for creating cursor objects
|
||||
* @param version number of the database
|
||||
*/
|
||||
public PodDBHelper(final Context context, final String name,
|
||||
final CursorFactory factory, final int version) {
|
||||
super(context, name, factory, version);
|
||||
final CursorFactory factory) {
|
||||
super(context, name, factory, VERSION);
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
|
@ -1492,7 +1517,188 @@ public class PodDBAdapter {
|
|||
public void onUpgrade(final SQLiteDatabase db, final int oldVersion,
|
||||
final int newVersion) {
|
||||
EventBus.getDefault().post(ProgressEvent.start(context.getString(R.string.progress_upgrading_database)));
|
||||
ClientConfig.storageCallbacks.onUpgrade(db, oldVersion, newVersion);
|
||||
Log.w("DBAdapter", "Upgrading from version " + oldVersion + " to "
|
||||
+ newVersion + ".");
|
||||
if (oldVersion <= 1) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + " ADD COLUMN "
|
||||
+ KEY_TYPE + " TEXT");
|
||||
}
|
||||
if (oldVersion <= 2) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS
|
||||
+ " ADD COLUMN " + KEY_LINK + " TEXT");
|
||||
}
|
||||
if (oldVersion <= 3) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
|
||||
+ " ADD COLUMN " + KEY_ITEM_IDENTIFIER + " TEXT");
|
||||
}
|
||||
if (oldVersion <= 4) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + " ADD COLUMN "
|
||||
+ KEY_FEED_IDENTIFIER + " TEXT");
|
||||
}
|
||||
if (oldVersion <= 5) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_DOWNLOAD_LOG
|
||||
+ " ADD COLUMN " + KEY_REASON_DETAILED + " TEXT");
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_DOWNLOAD_LOG
|
||||
+ " ADD COLUMN " + KEY_DOWNLOADSTATUS_TITLE + " TEXT");
|
||||
}
|
||||
if (oldVersion <= 6) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS
|
||||
+ " ADD COLUMN " + KEY_CHAPTER_TYPE + " INTEGER");
|
||||
}
|
||||
if (oldVersion <= 7) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
|
||||
+ " ADD COLUMN " + KEY_PLAYBACK_COMPLETION_DATE
|
||||
+ " INTEGER");
|
||||
}
|
||||
if (oldVersion <= 8) {
|
||||
final int KEY_ID_POSITION = 0;
|
||||
final int KEY_MEDIA_POSITION = 1;
|
||||
|
||||
// Add feeditem column to feedmedia table
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
|
||||
+ " ADD COLUMN " + KEY_FEEDITEM
|
||||
+ " INTEGER");
|
||||
Cursor feeditemCursor = db.query(PodDBAdapter.TABLE_NAME_FEED_ITEMS,
|
||||
new String[]{KEY_ID, KEY_MEDIA}, "? > 0",
|
||||
new String[]{KEY_MEDIA}, null, null, null);
|
||||
if (feeditemCursor.moveToFirst()) {
|
||||
db.beginTransaction();
|
||||
ContentValues contentValues = new ContentValues();
|
||||
do {
|
||||
long mediaId = feeditemCursor.getLong(KEY_MEDIA_POSITION);
|
||||
contentValues.put(KEY_FEEDITEM, feeditemCursor.getLong(KEY_ID_POSITION));
|
||||
db.update(PodDBAdapter.TABLE_NAME_FEED_MEDIA, contentValues, KEY_ID + "=?", new String[]{String.valueOf(mediaId)});
|
||||
contentValues.clear();
|
||||
} while (feeditemCursor.moveToNext());
|
||||
db.setTransactionSuccessful();
|
||||
db.endTransaction();
|
||||
}
|
||||
feeditemCursor.close();
|
||||
}
|
||||
if (oldVersion <= 9) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + KEY_AUTO_DOWNLOAD
|
||||
+ " INTEGER DEFAULT 1");
|
||||
}
|
||||
if (oldVersion <= 10) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + KEY_FLATTR_STATUS
|
||||
+ " INTEGER");
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
|
||||
+ " ADD COLUMN " + KEY_FLATTR_STATUS
|
||||
+ " INTEGER");
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
|
||||
+ " ADD COLUMN " + KEY_PLAYED_DURATION
|
||||
+ " INTEGER");
|
||||
}
|
||||
if (oldVersion <= 11) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + KEY_USERNAME
|
||||
+ " TEXT");
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + KEY_PASSWORD
|
||||
+ " TEXT");
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
|
||||
+ " ADD COLUMN " + KEY_IMAGE
|
||||
+ " INTEGER");
|
||||
}
|
||||
if (oldVersion <= 12) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + KEY_IS_PAGED + " INTEGER DEFAULT 0");
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + KEY_NEXT_PAGE_LINK + " TEXT");
|
||||
}
|
||||
if (oldVersion <= 13) {
|
||||
// remove duplicate rows in "Chapters" table that were created because of a bug.
|
||||
db.execSQL(String.format("DELETE FROM %s WHERE %s NOT IN " +
|
||||
"(SELECT MIN(%s) as %s FROM %s GROUP BY %s,%s,%s,%s,%s)",
|
||||
PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS,
|
||||
KEY_ID,
|
||||
KEY_ID,
|
||||
KEY_ID,
|
||||
PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS,
|
||||
KEY_TITLE,
|
||||
KEY_START,
|
||||
KEY_FEEDITEM,
|
||||
KEY_LINK,
|
||||
KEY_CHAPTER_TYPE));
|
||||
}
|
||||
if(oldVersion <= 14) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
|
||||
+ " ADD COLUMN " + KEY_AUTO_DOWNLOAD + " INTEGER");
|
||||
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
|
||||
+ " SET " + KEY_AUTO_DOWNLOAD + " = "
|
||||
+ "(SELECT " + KEY_AUTO_DOWNLOAD
|
||||
+ " FROM " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " WHERE " + PodDBAdapter.TABLE_NAME_FEEDS + "." + KEY_ID
|
||||
+ " = " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + KEY_FEED + ")");
|
||||
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + KEY_HIDE + " TEXT");
|
||||
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + KEY_LAST_UPDATE_FAILED + " INTEGER DEFAULT 0");
|
||||
|
||||
// create indexes
|
||||
db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_FEED);
|
||||
db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_IMAGE);
|
||||
db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDMEDIA_FEEDITEM);
|
||||
db.execSQL(PodDBAdapter.CREATE_INDEX_QUEUE_FEEDITEM);
|
||||
db.execSQL(PodDBAdapter.CREATE_INDEX_SIMPLECHAPTERS_FEEDITEM);
|
||||
}
|
||||
if(oldVersion <= 15) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
|
||||
+ " ADD COLUMN " + KEY_HAS_EMBEDDED_PICTURE + " INTEGER DEFAULT -1");
|
||||
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
|
||||
+ " SET " + KEY_HAS_EMBEDDED_PICTURE + "=0"
|
||||
+ " WHERE " + KEY_DOWNLOADED + "=0");
|
||||
Cursor c = db.rawQuery("SELECT " + KEY_FILE_URL
|
||||
+ " FROM " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
|
||||
+ " WHERE " + KEY_DOWNLOADED + "=1 "
|
||||
+ " AND " + KEY_HAS_EMBEDDED_PICTURE + "=-1", null);
|
||||
if(c.moveToFirst()) {
|
||||
MediaMetadataRetriever mmr = new MediaMetadataRetriever();
|
||||
do {
|
||||
String fileUrl = c.getString(0);
|
||||
try {
|
||||
mmr.setDataSource(fileUrl);
|
||||
byte[] image = mmr.getEmbeddedPicture();
|
||||
if (image != null) {
|
||||
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
|
||||
+ " SET " + KEY_HAS_EMBEDDED_PICTURE + "=1"
|
||||
+ " WHERE " + KEY_FILE_URL + "='"+ fileUrl + "'");
|
||||
} else {
|
||||
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
|
||||
+ " SET " + KEY_HAS_EMBEDDED_PICTURE + "=0"
|
||||
+ " WHERE " + KEY_FILE_URL + "='"+ fileUrl + "'");
|
||||
}
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} while(c.moveToNext());
|
||||
}
|
||||
c.close();
|
||||
}
|
||||
if(oldVersion <= 16) {
|
||||
String selectNew = "SELECT " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + KEY_ID
|
||||
+ " FROM " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
|
||||
+ " INNER JOIN " + PodDBAdapter.TABLE_NAME_FEED_MEDIA + " ON "
|
||||
+ PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + KEY_ID + "="
|
||||
+ PodDBAdapter.TABLE_NAME_FEED_MEDIA + "." + KEY_FEEDITEM
|
||||
+ " LEFT OUTER JOIN " + PodDBAdapter.TABLE_NAME_QUEUE + " ON "
|
||||
+ PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + KEY_ID + "="
|
||||
+ PodDBAdapter.TABLE_NAME_QUEUE + "." + KEY_FEEDITEM
|
||||
+ " WHERE "
|
||||
+ PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + KEY_READ + " = 0 AND " // unplayed
|
||||
+ PodDBAdapter.TABLE_NAME_FEED_MEDIA + "." + KEY_DOWNLOADED + " = 0 AND " // undownloaded
|
||||
+ PodDBAdapter.TABLE_NAME_FEED_MEDIA + "." + KEY_POSITION + " = 0 AND " // not partially played
|
||||
+ PodDBAdapter.TABLE_NAME_QUEUE + "." + KEY_ID + " IS NULL"; // not in queue
|
||||
String sql = "UPDATE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
|
||||
+ " SET " + KEY_READ + "=" + FeedItem.NEW
|
||||
+ " WHERE " + KEY_ID + " IN (" + selectNew + ")";
|
||||
Log.d("Migration", "SQL: " + sql);
|
||||
db.execSQL(sql);
|
||||
}
|
||||
EventBus.getDefault().post(ProgressEvent.end());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue