diff options
-rw-r--r-- | AndroidManifest.xml | 4 | ||||
-rw-r--r-- | CHANGELOG.md | 4 | ||||
-rw-r--r-- | assets/about.html | 4 | ||||
-rw-r--r-- | build.gradle | 4 | ||||
-rw-r--r-- | pom.xml | 2 | ||||
-rw-r--r-- | proguard.cfg | 2 | ||||
-rw-r--r-- | res/layout/nav_feedlistitem.xml | 1 | ||||
-rw-r--r-- | res/layout/nav_listitem.xml | 21 | ||||
-rw-r--r-- | res/values-de/strings.xml | 2 | ||||
-rw-r--r-- | res/values-zh-rCN/strings.xml | 17 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/AppConfig.java | 3 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/activity/AudioplayerActivity.java | 34 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/activity/FeedInfoActivity.java | 1 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/activity/MainActivity.java | 49 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java | 66 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/adapter/NavListAdapter.java | 31 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/asynctask/ImageDiskCache.java | 8 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/storage/DBReader.java | 48 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/storage/PodDBAdapter.java | 12 | ||||
-rw-r--r-- | src/instrumentationTest/de/test/antennapod/storage/DBReaderTest.java | 40 |
20 files changed, 274 insertions, 79 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 4d7e8896d..b06a9b5c7 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="de.danoeh.antennapod" - android:versionCode="37" - android:versionName="0.9.9.0"> + android:versionCode="38" + android:versionName="0.9.9.1"> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> diff --git a/CHANGELOG.md b/CHANGELOG.md index 709b95fb1..1cce0c57a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ Change Log ========== +Version 0.9.9.1 +--------------- +* Several bugfixes and improvements + Version 0.9.9.0 --------------- * New user interface diff --git a/assets/about.html b/assets/about.html index e6ffdc2ed..4bd4870c6 100644 --- a/assets/about.html +++ b/assets/about.html @@ -41,9 +41,9 @@ <div id="header" align="center"> <img src="logo.png" alt="Logo" width="100px" height="100px"/> - <p>AntennaPod, Version 0.9.9.0</p> + <p>AntennaPod, Version 0.9.9.1</p> - <p>Copyright © 2012 Daniel Oeh</p> + <p>Copyright © 2014 Daniel Oeh</p> <p>Licensed under the MIT License <a href="LICENSE.html">(View)</a></p> </div> diff --git a/build.gradle b/build.gradle index 7ae35ae61..7e1f7809b 100644 --- a/build.gradle +++ b/build.gradle @@ -39,7 +39,7 @@ android { defaultConfig { minSdkVersion 10 targetSdkVersion 19 - testPackageName "de.test.antennapod" + testApplicationId "de.test.antennapod" testInstrumentationRunner "instrumentationTest.de.test.antennapod.AntennaPodTestRunner" } @@ -82,7 +82,7 @@ android { buildTypes { debug { - packageNameSuffix ".debug" + applicationIdSuffix ".debug" } release { runProguard true @@ -5,7 +5,7 @@ <groupId>de.danoeh</groupId> <artifactId>antennapod</artifactId> <packaging>apk</packaging> - <version>0.9.9.0</version> + <version>0.9.9.1</version> <name>AntennaPod</name> diff --git a/proguard.cfg b/proguard.cfg index 96111d41f..fd76cc73a 100644 --- a/proguard.cfg +++ b/proguard.cfg @@ -1,11 +1,9 @@ --printmapping out.map -renamesourcefileattribute SourceFile -keepattributes SourceFile,LineNumberTable -dontpreverify -repackageclasses '' -allowaccessmodification --optimizations !code/simplification/arithmetic -keepattributes *Annotation* #-injars libs/presto_client-0.8.5.jar diff --git a/res/layout/nav_feedlistitem.xml b/res/layout/nav_feedlistitem.xml index e01087077..d94c9ada1 100644 --- a/res/layout/nav_feedlistitem.xml +++ b/res/layout/nav_feedlistitem.xml @@ -24,6 +24,7 @@ android:id="@+id/txtvTitle" android:lines="1" android:ellipsize="end" + android:singleLine="true" android:layout_centerVertical="true" android:textColor="?android:attr/textColorPrimary" android:textSize="@dimen/text_size_navdrawer" diff --git a/res/layout/nav_listitem.xml b/res/layout/nav_listitem.xml index 585ee7528..9d70e7d7c 100644 --- a/res/layout/nav_listitem.xml +++ b/res/layout/nav_listitem.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:orientation="vertical" - android:layout_width="match_parent" - android:layout_height="match_parent"> + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent"> <ImageView android:id="@+id/imgvCover" @@ -24,6 +24,7 @@ android:id="@+id/txtvTitle" android:lines="1" android:ellipsize="end" + android:singleLine="true" android:layout_centerVertical="true" android:textColor="?android:attr/textColorPrimary" android:textSize="@dimen/text_size_navdrawer" @@ -35,4 +36,18 @@ android:layout_marginRight="48dp" android:layout_toRightOf="@id/imgvCover" /> + + <TextView + android:id="@+id/txtvCount" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:lines="1" + android:textColor="?android:attr/textColorTertiary" + android:textSize="@dimen/text_size_navdrawer" + android:layout_marginLeft="12dp" + android:layout_marginTop="14dp" + android:layout_marginBottom="14dp" + android:layout_marginRight="16dp" + android:layout_alignParentRight="true" + android:layout_centerVertical="true"/> </RelativeLayout>
\ No newline at end of file diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index c4236b59c..04565af86 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -289,7 +289,7 @@ <!--Directory chooser--> <string name="selected_folder_label">Ausgewählter Ordner</string> <string name="create_folder_label">Neuer Ordner</string> - <string name="choose_data_directory">Wähle Datenordner</string> + <string name="choose_data_directory">Datenordner auswählen</string> <string name="create_folder_msg">Neuen Ordner mit Namen \"%1$s\" erstellen?</string> <string name="create_folder_success">Neuer Ordner angelegt</string> <string name="create_folder_error_no_write_access">Kann in diesem Ordner nicht schreiben</string> diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index 354b58575..d58c76833 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -3,19 +3,26 @@ <!--Activitiy and fragment titles--> <string name="app_name">AntennaPod</string> <string name="feeds_label">订阅</string> + <string name="add_feed_label">添加博客</string> <string name="podcasts_label">播客</string> <string name="episodes_label">曲目</string> + <string name="new_episodes_label">新曲目</string> + <string name="all_episodes_label">所有曲目</string> <string name="new_label">最新</string> <string name="waiting_list_label">等待列表</string> <string name="settings_label">设置</string> <string name="add_new_feed_label">添加播客</string> <string name="downloads_label">下载</string> + <string name="downloads_running_label">正在运行</string> + <string name="downloads_completed_label">已完成</string> <string name="downloads_log_label">日志</string> <string name="cancel_download_label">取消下载</string> <string name="playback_history_label">播放历史</string> <string name="gpodnet_main_label">gpodder.net</string> <string name="gpodnet_auth_label">gpodder.net 登录</string> <!--New episodes fragment--> + <string name="recently_published_episodes_label">最近发布</string> + <string name="episode_filter_label">仅显示新曲目</string> <!--Main activity--> <string name="drawer_open">打开菜单</string> <string name="drawer_close">关闭菜单</string> @@ -53,9 +60,11 @@ <!--'Add Feed' Activity labels--> <string name="feedurl_label">订阅 URL</string> <string name="txtvfeedurl_label">添加播客 URL</string> + <string name="podcastdirectories_descr">您可以在 gpodder.net 通过名称、类别或热门来搜索新播客</string> <string name="browse_gpoddernet_label">浏览 gpodder.net</string> <!--Actions on feeds--> <string name="mark_all_read_label">全部标识已读</string> + <string name="mark_all_read_msg">将所有曲目标记为已读</string> <string name="show_info_label">查看信息</string> <string name="remove_feed_label">删除播客</string> <string name="share_link_label">分享网站链接</string> @@ -68,6 +77,7 @@ <string name="pause_label">暂停</string> <string name="stream_label">流媒体</string> <string name="remove_label">删除</string> + <string name="remove_episode_lable">移除曲目</string> <string name="mark_read_label">标记已读</string> <string name="mark_unread_label">标记未读</string> <string name="add_to_queue_label">添加到播放列表</string> @@ -91,6 +101,7 @@ <string name="download_error_unsupported_type">未提供的订阅类型</string> <string name="download_error_connection_error">链接错误</string> <string name="download_error_unknown_host">未知主机</string> + <string name="download_error_unauthorized">认证错误</string> <string name="cancel_all_downloads_label">取消所有下载</string> <string name="download_cancelled_msg">已取消下载</string> <string name="download_report_title">下载完成</string> @@ -99,6 +110,7 @@ <string name="download_error_request_error">请求出错</string> <string name="download_error_db_access">数据库访问错误</string> <string name="downloads_left">\u0020 下载剩余</string> + <string name="downloads_processing">正在处理下载</string> <string name="download_notification_title">下载播客数据</string> <string name="download_report_content">%1$d 下载成功, %2$d 失败</string> <string name="download_log_title_unknown">未知标题</string> @@ -106,6 +118,8 @@ <string name="download_type_media">媒体文件</string> <string name="download_type_image">图片</string> <string name="download_request_error_dialog_message_prefix">尝试下载文件:\u0020 时出错</string> + <string name="authentication_notification_title">需要认证</string> + <string name="authentication_notification_msg">您所请求的资源需要用户名和密码</string> <!--Mediaplayer messages--> <string name="player_error_msg">错误!</string> <string name="player_stopped_msg">没有可播放媒体</string> @@ -293,7 +307,10 @@ <string name="in_queue_label">曲目已经在播放列表中</string> <string name="new_episodes_count_label">新曲目数</string> <string name="in_progress_episodes_count_label">已收听曲目数</string> + <string name="drag_handle_content_description">拖动以变更本项目的位置</string> <!--Feed information screen--> <string name="authentication_label">验证</string> + <string name="authentication_descr">给本播客及曲目变更用户名及密码</string> <!--AntennaPodSP--> + <string name="sp_apps_importing_feeds_msg">正在从选定的应用中导入订阅...</string> </resources> diff --git a/src/de/danoeh/antennapod/AppConfig.java b/src/de/danoeh/antennapod/AppConfig.java index 1f55e73a6..cac946f84 100644 --- a/src/de/danoeh/antennapod/AppConfig.java +++ b/src/de/danoeh/antennapod/AppConfig.java @@ -2,5 +2,6 @@ package de.danoeh.antennapod; public final class AppConfig { /** Should be used when setting User-Agent header for HTTP-requests. */ - public final static String USER_AGENT = "AntennaPod/0.9.9.0"; + public final static String USER_AGENT = "AntennaPod/0.9.9.1"; + } diff --git a/src/de/danoeh/antennapod/activity/AudioplayerActivity.java b/src/de/danoeh/antennapod/activity/AudioplayerActivity.java index 2ffaae967..090c3f1f5 100644 --- a/src/de/danoeh/antennapod/activity/AudioplayerActivity.java +++ b/src/de/danoeh/antennapod/activity/AudioplayerActivity.java @@ -34,8 +34,6 @@ import de.danoeh.antennapod.storage.DBReader; import de.danoeh.antennapod.util.playback.ExternalMedia; import de.danoeh.antennapod.util.playback.Playable; -import java.util.List; - /** * Activity for playing audio files. */ @@ -624,20 +622,20 @@ public class AudioplayerActivity extends MediaplayerActivity { } } - private List<Feed> feeds; - private AsyncTask<Void, Void, List<Feed>> loadTask; + private DBReader.NavDrawerData navDrawerData; + private AsyncTask<Void, Void, DBReader.NavDrawerData> loadTask; private void loadData() { - loadTask = new AsyncTask<Void, Void, List<Feed>>() { + loadTask = new AsyncTask<Void, Void, DBReader.NavDrawerData>() { @Override - protected List<Feed> doInBackground(Void... params) { - return DBReader.getFeedList(AudioplayerActivity.this); + protected DBReader.NavDrawerData doInBackground(Void... params) { + return DBReader.getNavDrawerData(AudioplayerActivity.this); } @Override - protected void onPostExecute(List<Feed> result) { + protected void onPostExecute(DBReader.NavDrawerData result) { super.onPostExecute(result); - feeds = result; + navDrawerData = result; if (navAdapter != null) { navAdapter.notifyDataSetChanged(); } @@ -667,8 +665,8 @@ public class AudioplayerActivity extends MediaplayerActivity { private final NavListAdapter.ItemAccess itemAccess = new NavListAdapter.ItemAccess() { @Override public int getCount() { - if (feeds != null) { - return feeds.size(); + if (navDrawerData != null) { + return navDrawerData.feeds.size(); } else { return 0; } @@ -676,8 +674,8 @@ public class AudioplayerActivity extends MediaplayerActivity { @Override public Feed getItem(int position) { - if (feeds != null && position < feeds.size()) { - return feeds.get(position); + if (navDrawerData != null && position < navDrawerData.feeds.size()) { + return navDrawerData.feeds.get(position); } else { return null; } @@ -687,5 +685,15 @@ public class AudioplayerActivity extends MediaplayerActivity { public int getSelectedItemIndex() { return -1; } + + @Override + public int getQueueSize() { + return (navDrawerData != null) ? navDrawerData.queueSize : 0; + } + + @Override + public int getNumberOfUnreadItems() { + return (navDrawerData != null) ? navDrawerData.numUnreadItems : 0; + } }; } diff --git a/src/de/danoeh/antennapod/activity/FeedInfoActivity.java b/src/de/danoeh/antennapod/activity/FeedInfoActivity.java index f00ce13e8..7f60d0b10 100644 --- a/src/de/danoeh/antennapod/activity/FeedInfoActivity.java +++ b/src/de/danoeh/antennapod/activity/FeedInfoActivity.java @@ -166,6 +166,7 @@ public class FeedInfoActivity extends ActionBarActivity { menu.findItem(R.id.support_item).setVisible( feed != null && feed.getPaymentLink() != null); menu.findItem(R.id.share_link_item).setVisible(feed != null &&feed.getLink() != null); + menu.findItem(R.id.visit_website_item).setVisible(feed != null && feed.getLink() != null); return true; } diff --git a/src/de/danoeh/antennapod/activity/MainActivity.java b/src/de/danoeh/antennapod/activity/MainActivity.java index 898897bd8..257bea82d 100644 --- a/src/de/danoeh/antennapod/activity/MainActivity.java +++ b/src/de/danoeh/antennapod/activity/MainActivity.java @@ -39,7 +39,8 @@ public class MainActivity extends ActionBarActivity { private static final int EVENTS = EventDistributor.DOWNLOAD_HANDLED | EventDistributor.DOWNLOAD_QUEUED | EventDistributor.FEED_LIST_UPDATE - | EventDistributor.UNREAD_ITEMS_UPDATE; + | EventDistributor.UNREAD_ITEMS_UPDATE + | EventDistributor.QUEUE_UPDATE; public static final String PREF_NAME = "MainActivityPrefs"; public static final String PREF_IS_FIRST_LAUNCH = "prefMainActivityIsFirstLaunch"; @@ -147,7 +148,7 @@ public class MainActivity extends ActionBarActivity { } public List<Feed> getFeeds() { - return feeds; + return (navDrawerData != null) ? navDrawerData.feeds : null; } private void loadFragment(int viewType, int relPos, Bundle args) { @@ -207,9 +208,9 @@ public class MainActivity extends ActionBarActivity { } public void loadFeedFragment(long feedID) { - if (feeds != null) { - for (int i = 0; i < feeds.size(); i++) { - if (feeds.get(i).getId() == feedID) { + if (navDrawerData != null) { + for (int i = 0; i < navDrawerData.feeds.size(); i++) { + if (navDrawerData.feeds.get(i).getId() == feedID) { loadFragment(NavListAdapter.VIEW_TYPE_SUBSCRIPTION, i, null); break; } @@ -279,7 +280,7 @@ public class MainActivity extends ActionBarActivity { EventDistributor.getInstance().register(contentUpdate); Intent intent = getIntent(); - if (feeds != null && intent.hasExtra(EXTRA_NAV_INDEX) && intent.hasExtra(EXTRA_NAV_TYPE)) { + if (navDrawerData != null && intent.hasExtra(EXTRA_NAV_INDEX) && intent.hasExtra(EXTRA_NAV_TYPE)) { handleNavIntent(); } @@ -322,15 +323,15 @@ public class MainActivity extends ActionBarActivity { return true; } - private List<Feed> feeds; - private AsyncTask<Void, Void, List<Feed>> loadTask; + private DBReader.NavDrawerData navDrawerData; + private AsyncTask<Void, Void, DBReader.NavDrawerData> loadTask; private int selectedNavListIndex = 0; private NavListAdapter.ItemAccess itemAccess = new NavListAdapter.ItemAccess() { @Override public int getCount() { - if (feeds != null) { - return feeds.size(); + if (navDrawerData != null) { + return navDrawerData.feeds.size(); } else { return 0; } @@ -338,8 +339,8 @@ public class MainActivity extends ActionBarActivity { @Override public Feed getItem(int position) { - if (feeds != null && position < feeds.size()) { - return feeds.get(position); + if (navDrawerData != null && position < navDrawerData.feeds.size()) { + return navDrawerData.feeds.get(position); } else { return null; } @@ -350,23 +351,33 @@ public class MainActivity extends ActionBarActivity { return selectedNavListIndex; } + @Override + public int getQueueSize() { + return (navDrawerData != null) ? navDrawerData.queueSize : 0; + } + + @Override + public int getNumberOfUnreadItems() { + return (navDrawerData != null) ? navDrawerData.numUnreadItems : 0; + } + }; private void loadData() { cancelLoadTask(); - loadTask = new AsyncTask<Void, Void, List<Feed>>() { + loadTask = new AsyncTask<Void, Void, DBReader.NavDrawerData>() { @Override - protected List<Feed> doInBackground(Void... params) { - return DBReader.getFeedList(MainActivity.this); + protected DBReader.NavDrawerData doInBackground(Void... params) { + return DBReader.getNavDrawerData(MainActivity.this); } @Override - protected void onPostExecute(List<Feed> result) { - super.onPostExecute(result); - boolean handleIntent = (feeds == null); + protected void onPostExecute(DBReader.NavDrawerData result) { + super.onPostExecute(navDrawerData); + boolean handleIntent = (navDrawerData == null); - feeds = result; + navDrawerData = result; navAdapter.notifyDataSetChanged(); if (handleIntent) { diff --git a/src/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java b/src/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java index 271cc19d5..e397ff2ca 100644 --- a/src/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java +++ b/src/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java @@ -61,6 +61,8 @@ public abstract class OnlineFeedViewActivity extends ActionBarActivity { private Map<String, String> alternateFeedUrls; private Downloader downloader; + private boolean isPaused; + @Override protected void onCreate(Bundle savedInstanceState) { setTheme(UserPreferences.getTheme()); @@ -97,6 +99,18 @@ public abstract class OnlineFeedViewActivity extends ActionBarActivity { } @Override + protected void onResume() { + super.onResume(); + isPaused = false; + } + + @Override + protected void onPause() { + super.onPause(); + isPaused = true; + } + + @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); if (feed != null && feed.getPreferences() != null) { @@ -126,9 +140,11 @@ public abstract class OnlineFeedViewActivity extends ActionBarActivity { if (status.isSuccessful()) { parseFeed(); } else if (status.getReason() == DownloadError.ERROR_UNAUTHORIZED) { - Dialog dialog = new FeedViewAuthenticationDialog(OnlineFeedViewActivity.this, - R.string.authentication_notification_title, downloader.getDownloadRequest().getSource()); - dialog.show(); + if (!isFinishing() && !isPaused) { + Dialog dialog = new FeedViewAuthenticationDialog(OnlineFeedViewActivity.this, + R.string.authentication_notification_title, downloader.getDownloadRequest().getSource()); + dialog.show(); + } } else { String errorMsg = status.getReason().getErrorString( OnlineFeedViewActivity.this); @@ -276,32 +292,30 @@ public abstract class OnlineFeedViewActivity extends ActionBarActivity { } private void showErrorDialog(String errorMsg) { - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(R.string.error_label); - if (errorMsg != null) { - builder.setMessage(getString(R.string.error_msg_prefix) + errorMsg); - } else { - builder.setMessage(R.string.error_msg_prefix); - } - builder.setNeutralButton(android.R.string.ok, - new DialogInterface.OnClickListener() { + if (!isFinishing() && !isPaused) { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(R.string.error_label); + if (errorMsg != null) { + builder.setMessage(getString(R.string.error_msg_prefix) + errorMsg); + } else { + builder.setMessage(R.string.error_msg_prefix); + } + builder.setNeutralButton(android.R.string.ok, + new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.cancel(); + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.cancel(); + } } + ); + builder.setOnCancelListener(new OnCancelListener() { + @Override + public void onCancel(DialogInterface dialog) { + setResult(RESULT_ERROR); + finish(); } - ); - builder.setOnCancelListener(new OnCancelListener() { - @Override - public void onCancel(DialogInterface dialog) { - setResult(RESULT_ERROR); - finish(); - } - }); - - if (!isFinishing()) { - builder.show(); + }); } } diff --git a/src/de/danoeh/antennapod/adapter/NavListAdapter.java b/src/de/danoeh/antennapod/adapter/NavListAdapter.java index 928ec5dde..536bf80e3 100644 --- a/src/de/danoeh/antennapod/adapter/NavListAdapter.java +++ b/src/de/danoeh/antennapod/adapter/NavListAdapter.java @@ -36,9 +36,9 @@ public class NavListAdapter extends BaseAdapter { this.itemAccess = itemAccess; this.context = context; - TypedArray ta = context.obtainStyledAttributes(new int[] {R.attr.ic_new, R.attr.stat_playlist, + TypedArray ta = context.obtainStyledAttributes(new int[]{R.attr.ic_new, R.attr.stat_playlist, R.attr.av_download, R.attr.device_access_time, R.attr.content_new}); - drawables = new Drawable[] {ta.getDrawable(0), ta.getDrawable(1), ta.getDrawable(2), + drawables = new Drawable[]{ta.getDrawable(0), ta.getDrawable(1), ta.getDrawable(2), ta.getDrawable(3), ta.getDrawable(4)}; ta.recycle(); } @@ -113,6 +113,7 @@ public class NavListAdapter extends BaseAdapter { convertView = inflater.inflate(R.layout.nav_listitem, null); holder.title = (TextView) convertView.findViewById(R.id.txtvTitle); + holder.count = (TextView) convertView.findViewById(R.id.txtvCount); holder.image = (ImageView) convertView.findViewById(R.id.imgvCover); convertView.setTag(holder); } else { @@ -120,6 +121,27 @@ public class NavListAdapter extends BaseAdapter { } holder.title.setText(title); + + if (NAV_TITLES[position] == R.string.queue_label) { + int queueSize = itemAccess.getQueueSize(); + if (queueSize > 0) { + holder.count.setVisibility(View.VISIBLE); + holder.count.setText(String.valueOf(queueSize)); + } else { + holder.count.setVisibility(View.GONE); + } + } else if (NAV_TITLES[position] == R.string.all_episodes_label) { + int unreadItems = itemAccess.getNumberOfUnreadItems(); + if (unreadItems > 0) { + holder.count.setVisibility(View.VISIBLE); + holder.count.setText(String.valueOf(unreadItems)); + } else { + holder.count.setVisibility(View.GONE); + } + } else { + holder.count.setVisibility(View.GONE); + } + holder.image.setImageDrawable(drawables[position]); return convertView; @@ -174,6 +196,7 @@ public class NavListAdapter extends BaseAdapter { static class NavHolder { TextView title; + TextView count; ImageView image; } @@ -193,6 +216,10 @@ public class NavListAdapter extends BaseAdapter { public Feed getItem(int position); public int getSelectedItemIndex(); + + public int getQueueSize(); + + public int getNumberOfUnreadItems(); } } diff --git a/src/de/danoeh/antennapod/asynctask/ImageDiskCache.java b/src/de/danoeh/antennapod/asynctask/ImageDiskCache.java index b90d78c14..1d069daa5 100644 --- a/src/de/danoeh/antennapod/asynctask/ImageDiskCache.java +++ b/src/de/danoeh/antennapod/asynctask/ImageDiskCache.java @@ -189,6 +189,10 @@ public class ImageDiskCache { * The image will be stored in the thumbnail cache. */ public void loadThumbnailBitmap(final String url, final ImageView target, final int length) { + if (url == null) { + Log.w(TAG, "loadThumbnailBitmap: Call was ignored because url = null"); + return; + } final ImageLoader il = ImageLoader.getInstance(); target.setTag(R.id.image_disk_cache_key, url); if (diskCache != null) { @@ -217,6 +221,10 @@ public class ImageDiskCache { * The image will be stored in the cover cache. */ public void loadCoverBitmap(final String url, final ImageView target, final int length) { + if (url == null) { + Log.w(TAG, "loadCoverBitmap: Call was ignored because url = null"); + return; + } final ImageLoader il = ImageLoader.getInstance(); target.setTag(R.id.image_disk_cache_key, url); if (diskCache != null) { diff --git a/src/de/danoeh/antennapod/storage/DBReader.java b/src/de/danoeh/antennapod/storage/DBReader.java index 4aeca7cd6..e49ea4f83 100644 --- a/src/de/danoeh/antennapod/storage/DBReader.java +++ b/src/de/danoeh/antennapod/storage/DBReader.java @@ -56,6 +56,14 @@ public final class DBReader { PodDBAdapter adapter = new PodDBAdapter(context); adapter.open(); + List<Feed> result = getFeedList(adapter); + adapter.close(); + return result; + } + + private static List<Feed> getFeedList(PodDBAdapter adapter) { + if (BuildConfig.DEBUG) + Log.d(TAG, "Extracting Feedlist"); Cursor feedlistCursor = adapter.getAllFeedsCursor(); List<Feed> feeds = new ArrayList<Feed>(feedlistCursor.getCount()); @@ -509,8 +517,8 @@ public final class DBReader { * Loads a list of FeedItems sorted by pubDate in descending order. * * @param context A context that is used for opening a database connection. - * @param limit The maximum number of episodes that should be loaded. - * */ + * @param limit The maximum number of episodes that should be loaded. + */ public static List<FeedItem> getRecentlyPublishedEpisodes(Context context, int limit) { if (BuildConfig.DEBUG) Log.d(TAG, "Extracting recently published items list"); @@ -596,7 +604,8 @@ public final class DBReader { .getString(PodDBAdapter.KEY_DOWNLOADSTATUS_TITLE_INDEX); Date completionDate = new Date( logCursor - .getLong(PodDBAdapter.KEY_COMPLETION_DATE_INDEX)); + .getLong(PodDBAdapter.KEY_COMPLETION_DATE_INDEX) + ); downloadLog.add(new DownloadStatus(id, title, feedfileId, feedfileType, successful, DownloadError.fromCode(reason), completionDate, reasonDetailed)); @@ -787,7 +796,8 @@ public final class DBReader { cursor.getString(cursor .getColumnIndex(PodDBAdapter.KEY_DOWNLOAD_URL)), cursor.getInt(cursor - .getColumnIndex(PodDBAdapter.KEY_DOWNLOADED)) > 0); + .getColumnIndex(PodDBAdapter.KEY_DOWNLOADED)) > 0 + ); cursor.close(); return image; } @@ -865,4 +875,34 @@ public final class DBReader { adapter.close(); return empty; } + + /** + * Returns data necessary for displaying the navigation drawer. This includes + * the list of subscriptions, the number of items in the queue and the number of unread + * items. + * + * @param context A context that is used for opening a database connection. + */ + public static NavDrawerData getNavDrawerData(Context context) { + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + List<Feed> feeds = getFeedList(adapter); + int queueSize = adapter.getQueueSize(); + int numUnreadItems = adapter.getNumberOfUnreadItems(); + NavDrawerData result = new NavDrawerData(feeds, queueSize, numUnreadItems); + adapter.close(); + return result; + } + + public static class NavDrawerData { + public List<Feed> feeds; + public int queueSize; + public int numUnreadItems; + + public NavDrawerData(List<Feed> feeds, int queueSize, int numUnreadItems) { + this.feeds = feeds; + this.queueSize = queueSize; + this.numUnreadItems = numUnreadItems; + } + } } diff --git a/src/de/danoeh/antennapod/storage/PodDBAdapter.java b/src/de/danoeh/antennapod/storage/PodDBAdapter.java index 285709537..06c8b1fc9 100644 --- a/src/de/danoeh/antennapod/storage/PodDBAdapter.java +++ b/src/de/danoeh/antennapod/storage/PodDBAdapter.java @@ -1,6 +1,5 @@ package de.danoeh.antennapod.storage; -import android.app.backup.BackupManager; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; @@ -1107,6 +1106,17 @@ public class PodDBAdapter { } + public int getQueueSize() { + final String query = String.format("SELECT COUNT(%s) FROM %s", KEY_ID, TABLE_NAME_QUEUE); + Cursor c = db.rawQuery(query, null); + int result = 0; + if (c.moveToFirst()) { + result = c.getInt(0); + } + c.close(); + return result; + } + public final int getNumberOfUnreadItems() { final String query = "SELECT COUNT(DISTINCT " + KEY_ID + ") AS count FROM " + TABLE_NAME_FEED_ITEMS + " WHERE " + KEY_READ + " = 0"; diff --git a/src/instrumentationTest/de/test/antennapod/storage/DBReaderTest.java b/src/instrumentationTest/de/test/antennapod/storage/DBReaderTest.java index cb854b88d..c42c7a0cc 100644 --- a/src/instrumentationTest/de/test/antennapod/storage/DBReaderTest.java +++ b/src/instrumentationTest/de/test/antennapod/storage/DBReaderTest.java @@ -365,4 +365,44 @@ public class DBReaderTest extends InstrumentationTestCase { assertEquals("Wrong entry at index " + i, feeds.get(i).getId(), statistics.get(i).getFeedID()); } } + + public void testGetNavDrawerDataQueueEmptyNoUnreadItems() { + final Context context = getInstrumentation().getTargetContext(); + final int NUM_FEEDS = 10; + final int NUM_ITEMS = 10; + List<Feed> feeds = DBTestUtils.saveFeedlist(context, NUM_FEEDS, NUM_ITEMS, true); + DBReader.NavDrawerData navDrawerData = DBReader.getNavDrawerData(context); + assertEquals(NUM_FEEDS, navDrawerData.feeds.size()); + assertEquals(0, navDrawerData.numUnreadItems); + assertEquals(0, navDrawerData.queueSize); + } + + public void testGetNavDrawerDataQueueNotEmptyWithUnreadItems() { + final Context context = getInstrumentation().getTargetContext(); + final int NUM_FEEDS = 10; + final int NUM_ITEMS = 10; + final int NUM_QUEUE = 1; + final int NUM_UNREAD = 2; + List<Feed> feeds = DBTestUtils.saveFeedlist(context, NUM_FEEDS, NUM_ITEMS, true); + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + for (int i = 0; i < NUM_UNREAD; i++) { + FeedItem item = feeds.get(0).getItems().get(i); + item.setRead(false); + adapter.setSingleFeedItem(item); + } + List<FeedItem> queue = new ArrayList<FeedItem>(); + for (int i = 0; i < NUM_QUEUE; i++) { + FeedItem item = feeds.get(1).getItems().get(i); + queue.add(item); + } + adapter.setQueue(queue); + + adapter.close(); + + DBReader.NavDrawerData navDrawerData = DBReader.getNavDrawerData(context); + assertEquals(NUM_FEEDS, navDrawerData.feeds.size()); + assertEquals(NUM_UNREAD, navDrawerData.numUnreadItems); + assertEquals(NUM_QUEUE, navDrawerData.queueSize); + } } |