summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/StatisticsActivity.java70
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/StatisticsListAdapter.java7
-rw-r--r--app/src/main/res/layout/statistics_mode_select_dialog.xml25
-rw-r--r--app/src/main/res/menu/statistics.xml12
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java96
-rw-r--r--core/src/main/res/values/strings.xml4
6 files changed, 185 insertions, 29 deletions
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/StatisticsActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/StatisticsActivity.java
index 9bb8f8856..b2ff43c43 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/StatisticsActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/StatisticsActivity.java
@@ -1,14 +1,18 @@
package de.danoeh.antennapod.activity;
+import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
+import android.view.Menu;
+import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.ProgressBar;
+import android.widget.RadioButton;
import android.widget.TextView;
import de.danoeh.antennapod.R;
@@ -28,12 +32,16 @@ public class StatisticsActivity extends AppCompatActivity
implements AdapterView.OnItemClickListener {
private static final String TAG = StatisticsActivity.class.getSimpleName();
+ private static final String PREF_NAME = "StatisticsActivityPrefs";
+ private static final String PREF_COUNT_ALL = "countAll";
private Subscription subscription;
private TextView totalTimeTextView;
private ListView feedStatisticsList;
private ProgressBar progressBar;
private StatisticsListAdapter listAdapter;
+ private boolean countAll = false;
+ private SharedPreferences prefs;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -42,10 +50,14 @@ public class StatisticsActivity extends AppCompatActivity
getSupportActionBar().setDisplayShowHomeEnabled(true);
setContentView(R.layout.statistics_activity);
+ prefs = getSharedPreferences(PREF_NAME, MODE_PRIVATE);
+ countAll = prefs.getBoolean(PREF_COUNT_ALL, false);
+
totalTimeTextView = (TextView) findViewById(R.id.total_time);
feedStatisticsList = (ListView) findViewById(R.id.statistics_list);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
listAdapter = new StatisticsListAdapter(this);
+ listAdapter.setCountAll(countAll);
feedStatisticsList.setAdapter(listAdapter);
feedStatisticsList.setOnItemClickListener(this);
}
@@ -53,10 +65,15 @@ public class StatisticsActivity extends AppCompatActivity
@Override
public void onResume() {
super.onResume();
- progressBar.setVisibility(View.VISIBLE);
- totalTimeTextView.setVisibility(View.GONE);
- feedStatisticsList.setVisibility(View.GONE);
- loadStats();
+ refreshStatistics();
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ super.onCreateOptionsMenu(menu);
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.statistics, menu);
+ return true;
}
@Override
@@ -64,22 +81,54 @@ public class StatisticsActivity extends AppCompatActivity
if (item.getItemId() == android.R.id.home) {
finish();
return true;
+ } else if (item.getItemId() == R.id.statistics_mode) {
+ selectStatisticsMode();
+ return true;
} else {
return super.onOptionsItemSelected(item);
}
}
- private void loadStats() {
- if(subscription != null) {
+ private void selectStatisticsMode() {
+ View contentView = View.inflate(this, R.layout.statistics_mode_select_dialog, null);
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setView(contentView);
+ builder.setTitle(R.string.statistics_mode);
+
+ if (countAll) {
+ ((RadioButton) contentView.findViewById(R.id.statistics_mode_count_all)).setChecked(true);
+ } else {
+ ((RadioButton) contentView.findViewById(R.id.statistics_mode_normal)).setChecked(true);
+ }
+
+ builder.setPositiveButton(android.R.string.ok, (dialog, which) -> {
+ countAll = ((RadioButton) contentView.findViewById(R.id.statistics_mode_count_all)).isChecked();
+ listAdapter.setCountAll(countAll);
+ prefs.edit().putBoolean(PREF_COUNT_ALL, countAll).apply();
+ refreshStatistics();
+ });
+
+ builder.show();
+ }
+
+ private void refreshStatistics() {
+ progressBar.setVisibility(View.VISIBLE);
+ totalTimeTextView.setVisibility(View.GONE);
+ feedStatisticsList.setVisibility(View.GONE);
+ loadStatistics();
+ }
+
+ private void loadStatistics() {
+ if (subscription != null) {
subscription.unsubscribe();
}
- subscription = Observable.fromCallable(() -> DBReader.getStatistics())
+ subscription = Observable.fromCallable(() -> DBReader.getStatistics(countAll))
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> {
if (result != null) {
totalTimeTextView.setText(Converter
- .shortLocalizedDuration(this, result.totalTime));
+ .shortLocalizedDuration(this, countAll ? result.totalTimeCountAll : result.totalTime));
listAdapter.update(result.feedTime);
progressBar.setVisibility(View.GONE);
totalTimeTextView.setVisibility(View.VISIBLE);
@@ -95,9 +144,10 @@ public class StatisticsActivity extends AppCompatActivity
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setTitle(stats.feed.getTitle());
dialog.setMessage(getString(R.string.statistics_details_dialog,
- stats.episodesStarted,
+ countAll ? stats.episodesStartedIncludingMarked : stats.episodesStarted,
stats.episodes,
- Converter.shortLocalizedDuration(this, stats.timePlayed),
+ Converter.shortLocalizedDuration(this, countAll ?
+ stats.timePlayedCountAll : 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
index fe891281b..c060083a6 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/StatisticsListAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/StatisticsListAdapter.java
@@ -25,11 +25,15 @@ import de.danoeh.antennapod.core.util.Converter;
public class StatisticsListAdapter extends BaseAdapter {
private Context context;
List<DBReader.StatisticsItem> feedTime = new ArrayList<>();
+ private boolean countAll = true;
public StatisticsListAdapter(Context context) {
this.context = context;
}
+ public void setCountAll(boolean countAll) {
+ this.countAll = countAll;
+ }
@Override
public int getCount() {
@@ -77,7 +81,8 @@ public class StatisticsListAdapter extends BaseAdapter {
holder.title.setText(feed.getTitle());
holder.time.setText(Converter.shortLocalizedDuration(context,
- feedTime.get(position).timePlayed));
+ countAll ? feedTime.get(position).timePlayedCountAll
+ : feedTime.get(position).timePlayed));
return convertView;
}
diff --git a/app/src/main/res/layout/statistics_mode_select_dialog.xml b/app/src/main/res/layout/statistics_mode_select_dialog.xml
new file mode 100644
index 000000000..8f8e1e657
--- /dev/null
+++ b/app/src/main/res/layout/statistics_mode_select_dialog.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RadioGroup xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:padding="16dp">
+
+ <TextView
+ android:text="@string/statistics_speed_not_counted"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="16dp"/>
+
+ <RadioButton
+ android:id="@+id/statistics_mode_normal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/statistics_mode_normal"/>
+
+ <RadioButton
+ android:id="@+id/statistics_mode_count_all"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/statistics_mode_count_all"/>
+</RadioGroup>
diff --git a/app/src/main/res/menu/statistics.xml b/app/src/main/res/menu/statistics.xml
new file mode 100644
index 000000000..6ecc70707
--- /dev/null
+++ b/app/src/main/res/menu/statistics.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:custom="http://schemas.android.com/apk/res-auto">
+
+ <item
+ android:id="@+id/statistics_mode"
+ android:icon="?attr/ic_filter"
+ android:title="@string/statistics_mode"
+ custom:showAsAction="never">
+ </item>
+
+</menu>
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 7bda08b7a..8ed6718c0 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
@@ -927,64 +927,107 @@ public final class DBReader {
/**
* Searches the DB for statistics
*
+ * @param sortByCountAll If true, the statistic items will be sorted according to the
+ * countAll calculation time
* @return The StatisticsInfo object
*/
- public static StatisticsData getStatistics() {
+ public static StatisticsData getStatistics(boolean sortByCountAll) {
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
+ long totalTimeCountAll = 0;
long totalTime = 0;
List<StatisticsItem> feedTime = new ArrayList<>();
List<Feed> feeds = getFeedList();
for (Feed feed : feeds) {
+ long feedPlayedTimeCountAll = 0;
long feedPlayedTime = 0;
long feedTotalTime = 0;
long episodes = 0;
long episodesStarted = 0;
+ long episodesStartedIncludingMarked = 0;
List<FeedItem> items = getFeed(feed.getId()).getItems();
- for(FeedItem item : items) {
+ for (FeedItem item : items) {
FeedMedia media = item.getMedia();
- if(media == null) {
+ if (media == null) {
continue;
}
// played duration used to be reset when the item is added to the playback history
- if(media.getPlaybackCompletionDate() != null) {
+ if (media.getPlaybackCompletionDate() != null) {
feedPlayedTime += media.getDuration() / 1000;
}
feedPlayedTime += media.getPlayedDuration() / 1000;
+
+ if (item.isPlayed()) {
+ feedPlayedTimeCountAll += media.getDuration() / 1000;
+ } else {
+ feedPlayedTimeCountAll += media.getPosition() / 1000;
+ }
+
if (media.getPlaybackCompletionDate() != null || media.getPlayedDuration() > 0) {
episodesStarted++;
}
+
+ if (item.isPlayed() || media.getPosition() != 0) {
+ episodesStartedIncludingMarked++;
+ }
+
feedTotalTime += media.getDuration() / 1000;
episodes++;
}
feedTime.add(new StatisticsItem(
- feed, feedTotalTime, feedPlayedTime, episodes, episodesStarted));
+ feed, feedTotalTime, feedPlayedTime, feedPlayedTimeCountAll, episodes,
+ episodesStarted, episodesStartedIncludingMarked));
totalTime += feedPlayedTime;
+ totalTimeCountAll += feedPlayedTimeCountAll;
}
- Collections.sort(feedTime, (item1, item2) -> {
- if(item1.timePlayed > item2.timePlayed) {
- return -1;
- } else if(item1.timePlayed < item2.timePlayed) {
- return 1;
- } else {
- return 0;
- }
- });
+ if (sortByCountAll) {
+ Collections.sort(feedTime, (item1, item2) ->
+ compareLong(item1.timePlayedCountAll, item2.timePlayedCountAll));
+ } else {
+ Collections.sort(feedTime, (item1, item2) ->
+ compareLong(item1.timePlayed, item2.timePlayed));
+ }
adapter.close();
- return new StatisticsData(totalTime, feedTime);
+ return new StatisticsData(totalTime, totalTimeCountAll, feedTime);
+ }
+
+ /**
+ * Compares two {@code long} values. Long.compare() is not available before API 19
+ *
+ * @return 0 if long1 = long2, less than 0 if long1 &lt; long2,
+ * and greater than 0 if long1 &gt; long2.
+ */
+ private static int compareLong(long long1, long long2) {
+ if (long1 > long2) {
+ return -1;
+ } else if (long1 < long2) {
+ return 1;
+ } else {
+ return 0;
+ }
}
public static class StatisticsData {
+ /**
+ * Simply sums up time of podcasts that are marked as played
+ */
+ public long totalTimeCountAll;
+
+ /**
+ * Respects speed, listening twice, ...
+ */
public long totalTime;
+
public List<StatisticsItem> feedTime;
- public StatisticsData(long totalTime, List<StatisticsItem> feedTime) {
+ public StatisticsData(long totalTime, long totalTimeCountAll, List<StatisticsItem> feedTime) {
this.totalTime = totalTime;
+ this.totalTimeCountAll = totalTimeCountAll;
this.feedTime = feedTime;
}
}
@@ -992,17 +1035,34 @@ public final class DBReader {
public static class StatisticsItem {
public Feed feed;
public long time;
+
+ /**
+ * Respects speed, listening twice, ...
+ */
public long timePlayed;
+ /**
+ * Simply sums up time of podcasts that are marked as played
+ */
+ public long timePlayedCountAll;
public long episodes;
+ /**
+ * Episodes that are actually played
+ */
public long episodesStarted;
+ /**
+ * All episodes that are marked as played (or have position != 0)
+ */
+ public long episodesStartedIncludingMarked;
- public StatisticsItem(Feed feed, long time, long timePlayed,
- long episodes, long episodesStarted) {
+ public StatisticsItem(Feed feed, long time, long timePlayed, long timePlayedCountAll,
+ long episodes, long episodesStarted, long episodesStartedIncludingMarked) {
this.feed = feed;
this.time = time;
this.timePlayed = timePlayed;
+ this.timePlayedCountAll = timePlayedCountAll;
this.episodes = episodes;
this.episodesStarted = episodesStarted;
+ this.episodesStartedIncludingMarked = episodesStartedIncludingMarked;
}
}
diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml
index 974c5a7f8..b82a03801 100644
--- a/core/src/main/res/values/strings.xml
+++ b/core/src/main/res/values/strings.xml
@@ -31,6 +31,10 @@
<!-- Statistics fragment -->
<string name="total_time_listened_to_podcasts">Total time of podcasts played:</string>
<string name="statistics_details_dialog">%1$d out of %2$d episodes started.\n\nPlayed %3$s out of %4$s.</string>
+ <string name="statistics_mode">Statistics mode</string>
+ <string name="statistics_mode_normal">Calculate duration that was actually played. Playing twice is counted twice, while marking as played is not counted</string>
+ <string name="statistics_mode_count_all">Sum up all podcasts marked as played</string>
+ <string name="statistics_speed_not_counted">Notice: Playback speed is never taken into account.</string>
<!-- Main activity -->
<string name="drawer_open">Open menu</string>