From aa56d6822aee8a1a98555aa9c0203c3efd4608b5 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Mon, 21 Mar 2016 13:00:12 +0100 Subject: Added statistics function Fixes #1743 --- app/src/main/AndroidManifest.xml | 7 ++ .../antennapod/activity/StatisticsActivity.java | 107 +++++++++++++++++++++ .../antennapod/adapter/StatisticsListAdapter.java | 97 +++++++++++++++++++ .../preferences/PreferenceController.java | 8 ++ app/src/main/res/layout/statistics_activity.xml | 41 ++++++++ app/src/main/res/layout/statistics_listitem.xml | 57 +++++++++++ app/src/main/res/xml/preferences.xml | 3 + .../danoeh/antennapod/core/storage/DBReader.java | 82 ++++++++++++++++ .../de/danoeh/antennapod/core/util/Converter.java | 12 +++ core/src/main/res/values/strings.xml | 5 + 10 files changed, 419 insertions(+) create mode 100644 app/src/main/java/de/danoeh/antennapod/activity/StatisticsActivity.java create mode 100644 app/src/main/java/de/danoeh/antennapod/adapter/StatisticsListAdapter.java create mode 100644 app/src/main/res/layout/statistics_activity.xml create mode 100644 app/src/main/res/layout/statistics_listitem.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index af23c287c..75f3c6989 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -144,6 +144,13 @@ android:name="android.support.PARENT_ACTIVITY" android:value="de.danoeh.antennapod.activity.PreferenceActivity"/> + + + DBReader.getStatistics()) + .subscribeOn(Schedulers.newThread()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(result -> { + if (result != null) { + totalTimeTextView.setText(Converter + .shortLocalizedDuration(this, result.totalTime)); + listAdapter.update(result.feedTime); + progressBar.setVisibility(View.GONE); + totalTimeTextView.setVisibility(View.VISIBLE); + feedStatisticsList.setVisibility(View.VISIBLE); + } + }, error -> { + Log.e(TAG, Log.getStackTraceString(error)); + }); + } + + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + DBReader.StatisticsItem stats = listAdapter.getItem(position); + + AlertDialog.Builder dialog = new AlertDialog.Builder(this); + dialog.setTitle(stats.feed.getTitle()); + dialog.setMessage(getString(R.string.statistics_details_dialog, + stats.episodesStarted, + stats.episodes, + Converter.shortLocalizedDuration(this, stats.timePlayed), + Converter.shortLocalizedDuration(this, stats.time))); + dialog.setPositiveButton(android.R.string.ok, null); + dialog.show(); + } +} diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/StatisticsListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/StatisticsListAdapter.java new file mode 100644 index 000000000..7fb1472ad --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/adapter/StatisticsListAdapter.java @@ -0,0 +1,97 @@ +package de.danoeh.antennapod.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; +import android.widget.TextView; + +import com.bumptech.glide.Glide; +import com.joanzapata.iconify.widget.IconTextView; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.core.feed.Feed; +import de.danoeh.antennapod.core.glide.ApGlideSettings; +import de.danoeh.antennapod.core.storage.DBReader; +import de.danoeh.antennapod.core.util.Converter; + +/** + * Adapter for the statistics list + */ +public class StatisticsListAdapter extends BaseAdapter { + private Context context; + List feedTime = new ArrayList<>(); + + public StatisticsListAdapter(Context context) { + this.context = context; + } + + + @Override + public int getCount() { + return feedTime.size(); + } + + @Override + public DBReader.StatisticsItem getItem(int position) { + return feedTime.get(position); + } + + @Override + public long getItemId(int position) { + return feedTime.get(position).feed.getId(); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + StatisticsHolder holder; + Feed feed = feedTime.get(position).feed; + + if (convertView == null) { + holder = new StatisticsHolder(); + LayoutInflater inflater = (LayoutInflater) context + .getSystemService(Context.LAYOUT_INFLATER_SERVICE); + + convertView = inflater.inflate(R.layout.statistics_listitem, parent, false); + + holder.image = (ImageView) convertView.findViewById(R.id.imgvCover); + holder.title = (TextView) convertView.findViewById(R.id.txtvTitle); + holder.time = (TextView) convertView.findViewById(R.id.txtvTime); + convertView.setTag(holder); + } else { + holder = (StatisticsHolder) convertView.getTag(); + } + + Glide.with(context) + .load(feed.getImageUri()) + .placeholder(R.color.light_gray) + .error(R.color.light_gray) + .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) + .fitCenter() + .dontAnimate() + .into(holder.image); + + holder.title.setText(feed.getTitle()); + holder.time.setText(Converter.shortLocalizedDuration(context, + feedTime.get(position).timePlayed)); + return convertView; + } + + public void update(List feedTime) { + this.feedTime = feedTime; + notifyDataSetChanged(); + } + + static class StatisticsHolder { + ImageView image; + TextView title; + TextView time; + } + +} diff --git a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java index 152412089..5ad1b624a 100644 --- a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java +++ b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java @@ -49,6 +49,7 @@ import de.danoeh.antennapod.activity.DirectoryChooserActivity; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.activity.PreferenceActivity; import de.danoeh.antennapod.activity.PreferenceActivityGingerbread; +import de.danoeh.antennapod.activity.StatisticsActivity; import de.danoeh.antennapod.asynctask.OpmlExportWorker; import de.danoeh.antennapod.core.preferences.GpodnetPreferences; import de.danoeh.antennapod.core.preferences.UserPreferences; @@ -75,6 +76,7 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc public static final String PREF_FLATTR_REVOKE = "prefRevokeAccess"; public static final String PREF_AUTO_FLATTR_PREFS = "prefAutoFlattrPrefs"; public static final String PREF_OPML_EXPORT = "prefOpmlExport"; + public static final String STATISTICS = "statistics"; public static final String PREF_ABOUT = "prefAbout"; public static final String PREF_CHOOSE_DATA_DIR = "prefChooseDataDir"; public static final String AUTO_DL_PREF_SCREEN = "prefAutoDownloadSettings"; @@ -153,6 +155,12 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc return true; } ); + ui.findPreference(PreferenceController.STATISTICS).setOnPreferenceClickListener( + preference -> { + activity.startActivity(new Intent(activity, StatisticsActivity.class)); + return true; + } + ); ui.findPreference(PreferenceController.PREF_OPML_EXPORT).setOnPreferenceClickListener( preference -> { new OpmlExportWorker(activity).executeAsync(); diff --git a/app/src/main/res/layout/statistics_activity.xml b/app/src/main/res/layout/statistics_activity.xml new file mode 100644 index 000000000..4a72dc7de --- /dev/null +++ b/app/src/main/res/layout/statistics_activity.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/layout/statistics_listitem.xml b/app/src/main/res/layout/statistics_listitem.xml new file mode 100644 index 000000000..20e01bf32 --- /dev/null +++ b/app/src/main/res/layout/statistics_listitem.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index e0671e67b..1e70a62d3 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -268,6 +268,9 @@ + diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java index 4f2400e1d..fd832a8cb 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java @@ -917,6 +917,88 @@ public final class DBReader { return media; } + /** + * Searches the DB for statistics + * + * @return The StatisticsInfo object + */ + public static StatisticsData getStatistics() { + PodDBAdapter adapter = PodDBAdapter.getInstance(); + adapter.open(); + + long totalTime = 0; + List feedTime = new ArrayList<>(); + + List feeds = getFeedList(); + for (Feed feed : feeds) { + long feedPlayedTime = 0; + long feedTotalTime = 0; + long episodes = 0; + long episodesStarted = 0; + List items = getFeed(feed.getId()).getItems(); + for(FeedItem item : items) { + FeedMedia media = item.getMedia(); + if(media == null) { + continue; + } + + if(item.isPlayed()) { + feedPlayedTime += media.getDuration() / 1000; + } else { + feedPlayedTime += media.getPosition() / 1000; + } + if(item.isPlayed() || media.getPosition() != 0) { + episodesStarted++; + } + feedTotalTime += media.getDuration() / 1000; + episodes++; + } + feedTime.add(new StatisticsItem( + feed, feedTotalTime, feedPlayedTime, episodes, episodesStarted)); + totalTime += feedPlayedTime; + } + + Collections.sort(feedTime, (item1, item2) -> { + if(item1.timePlayed > item2.timePlayed) { + return -1; + } else if(item1.timePlayed < item2.timePlayed) { + return 1; + } else { + return 0; + } + }); + + adapter.close(); + return new StatisticsData(totalTime, feedTime); + } + + public static class StatisticsData { + public long totalTime; + public List feedTime; + + public StatisticsData(long totalTime, List feedTime) { + this.totalTime = totalTime; + this.feedTime = feedTime; + } + } + + public static class StatisticsItem { + public Feed feed; + public long time; + public long timePlayed; + public long episodes; + public long episodesStarted; + + public StatisticsItem(Feed feed, long time, long timePlayed, + long episodes, long episodesStarted) { + this.feed = feed; + this.time = time; + this.timePlayed = timePlayed; + this.episodes = episodes; + this.episodesStarted = episodesStarted; + } + } + /** * Returns the flattr queue as a List of FlattrThings. The list consists of Feeds and FeedItems. * diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/Converter.java b/core/src/main/java/de/danoeh/antennapod/core/util/Converter.java index 5b046d7a7..70a180913 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/Converter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/Converter.java @@ -3,6 +3,8 @@ package de.danoeh.antennapod.core.util; import android.content.Context; import android.util.Log; +import java.util.Locale; + import de.danoeh.antennapod.core.R; /** Provides methods for converting various units. */ @@ -119,6 +121,16 @@ public final class Converter { return result; } + /** + * Converts seconds to a localized representation + * @param time The time in seconds + * @return "HH:MM hours" + */ + public static String shortLocalizedDuration(Context context, long time) { + float hours = (float) time / 3600f; + return String.format(Locale.getDefault(), "%.1f ", hours) + context.getString(R.string.time_hours); + } + /** * Converts the volume as read as the progress from a SeekBar scaled to 100 and as saved in * UserPreferences to the format taken by setVolume methods. diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index 777db5046..d7948c0a3 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -6,6 +6,7 @@ AntennaPod Feeds + Statistics Add Podcast PODCASTS Episodes @@ -33,6 +34,10 @@ Recently published Show only new Episodes + + Total time of podcasts played: + %1$d out of %2$d episodes started.\n\nPlayed %3$s out of %4$s. + Open menu Close menu -- cgit v1.2.3