summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorByteHamster <info@bytehamster.com>2022-02-20 12:07:21 +0100
committerByteHamster <info@bytehamster.com>2022-02-21 22:54:40 +0100
commit7ab6d08ea589aae7db2f7bdf1b28833f45ba9943 (patch)
tree3cb1943e5640e65f8876e4053d131f88a3df66fe
parentb6d23168707bd55e5bb4060a9cd8e8ecf96a9716 (diff)
downloadAntennaPod-7ab6d08ea589aae7db2f7bdf1b28833f45ba9943.zip
Add line graph to statistics screen
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/YearStatisticsListAdapter.java121
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/preferences/StatisticsFragment.java22
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/preferences/SubscriptionStatisticsFragment.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/preferences/PlaybackStatisticsFragment.java)4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/preferences/YearsStatisticsFragment.java87
-rw-r--r--app/src/main/java/de/danoeh/antennapod/view/LineChartView.java138
-rw-r--r--app/src/main/res/layout/statistics_listitem_linechart.xml22
-rw-r--r--app/src/main/res/layout/statistics_year_listitem.xml32
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java27
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java11
-rw-r--r--core/src/main/res/values/strings.xml3
10 files changed, 455 insertions, 12 deletions
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/YearStatisticsListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/YearStatisticsListAdapter.java
new file mode 100644
index 000000000..ad20574b3
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/YearStatisticsListAdapter.java
@@ -0,0 +1,121 @@
+package de.danoeh.antennapod.adapter;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.core.storage.DBReader;
+import de.danoeh.antennapod.core.util.LongList;
+import de.danoeh.antennapod.view.LineChartView;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Adapter for the yearly playback statistics list.
+ */
+public class YearStatisticsListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
+ private static final int TYPE_HEADER = 0;
+ private static final int TYPE_FEED = 1;
+ final Context context;
+ private List<DBReader.MonthlyStatisticsItem> statisticsData = new ArrayList<>();
+ LineChartView.LineChartData lineChartData;
+
+ public YearStatisticsListAdapter(Context context) {
+ this.context = context;
+ }
+
+ @Override
+ public int getItemCount() {
+ return statisticsData.size() + 1;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return position == 0 ? TYPE_HEADER : TYPE_FEED;
+ }
+
+ @NonNull
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ LayoutInflater inflater = LayoutInflater.from(context);
+ if (viewType == TYPE_HEADER) {
+ return new HeaderHolder(inflater.inflate(R.layout.statistics_listitem_linechart, parent, false));
+ }
+ return new StatisticsHolder(inflater.inflate(R.layout.statistics_year_listitem, parent, false));
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull RecyclerView.ViewHolder h, int position) {
+ if (getItemViewType(position) == TYPE_HEADER) {
+ HeaderHolder holder = (HeaderHolder) h;
+ holder.lineChart.setData(lineChartData);
+ } else {
+ StatisticsHolder holder = (StatisticsHolder) h;
+ DBReader.MonthlyStatisticsItem statsItem = statisticsData.get(position - 1);
+ holder.year.setText(String.format(Locale.getDefault(), "%d ", statsItem.year));
+ holder.hours.setText(String.format(Locale.getDefault(), "%.1f ", statsItem.timePlayed / 3600000.0f)
+ + context.getString(R.string.time_hours));
+ }
+ }
+
+ public void update(List<DBReader.MonthlyStatisticsItem> statistics) {
+ int lastYear = statistics.size() > 0 ? statistics.get(0).year : 0;
+ int lastDataPoint = statistics.size() > 0 ? (statistics.get(0).month - 1) + lastYear * 12 : 0;
+ long yearSum = 0;
+ statisticsData.clear();
+ LongList lineChartValues = new LongList();
+ LongList lineChartHorizontalLines = new LongList();
+ for (DBReader.MonthlyStatisticsItem statistic : statistics) {
+ if (statistic.year != lastYear) {
+ DBReader.MonthlyStatisticsItem yearAggregate = new DBReader.MonthlyStatisticsItem();
+ yearAggregate.year = lastYear;
+ yearAggregate.timePlayed = yearSum;
+ statisticsData.add(yearAggregate);
+ yearSum = 0;
+ lastYear = statistic.year;
+ lineChartHorizontalLines.add(lineChartValues.size());
+ }
+ yearSum += statistic.timePlayed;
+ while (lastDataPoint + 1 < (statistic.month - 1) + statistic.year * 12) {
+ lineChartValues.add(0); // Compensate for months without playback
+ lastDataPoint++;
+ }
+ lineChartValues.add(statistic.timePlayed);
+ lastDataPoint = (statistic.month - 1) + statistic.year * 12;
+ }
+ DBReader.MonthlyStatisticsItem yearAggregate = new DBReader.MonthlyStatisticsItem();
+ yearAggregate.year = lastYear;
+ yearAggregate.timePlayed = yearSum;
+ statisticsData.add(yearAggregate);
+ Collections.reverse(statisticsData);
+ lineChartData = new LineChartView.LineChartData(lineChartValues.toArray(), lineChartHorizontalLines.toArray());
+ notifyDataSetChanged();
+ }
+
+ static class HeaderHolder extends RecyclerView.ViewHolder {
+ LineChartView lineChart;
+
+ HeaderHolder(View itemView) {
+ super(itemView);
+ lineChart = itemView.findViewById(R.id.lineChart);
+ }
+ }
+
+ static class StatisticsHolder extends RecyclerView.ViewHolder {
+ TextView year;
+ TextView hours;
+
+ StatisticsHolder(View itemView) {
+ super(itemView);
+ year = itemView.findViewById(R.id.yearLabel);
+ hours = itemView.findViewById(R.id.hoursLabel);
+ }
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/StatisticsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/StatisticsFragment.java
index 5a280ac81..1c5a6acd4 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/StatisticsFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/StatisticsFragment.java
@@ -25,9 +25,10 @@ public class StatisticsFragment extends PagedToolbarFragment {
public static final String TAG = "StatisticsFragment";
- private static final int POS_LISTENED_HOURS = 0;
- private static final int POS_SPACE_TAKEN = 1;
- private static final int TOTAL_COUNT = 2;
+ private static final int POS_SUBSCRIPTIONS = 0;
+ private static final int POS_YEARS = 1;
+ private static final int POS_SPACE_TAKEN = 2;
+ private static final int TOTAL_COUNT = 3;
private TabLayout tabLayout;
private ViewPager2 viewPager;
@@ -51,11 +52,14 @@ public class StatisticsFragment extends PagedToolbarFragment {
super.setupPagedToolbar(toolbar, viewPager);
new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> {
switch (position) {
- case POS_LISTENED_HOURS:
- tab.setText(R.string.playback_statistics_label);
+ case POS_SUBSCRIPTIONS:
+ tab.setText(R.string.subscriptions_label);
+ break;
+ case POS_YEARS:
+ tab.setText(R.string.years_statistics_label);
break;
case POS_SPACE_TAKEN:
- tab.setText(R.string.download_statistics_label);
+ tab.setText(R.string.downloads_label);
break;
default:
break;
@@ -82,8 +86,10 @@ public class StatisticsFragment extends PagedToolbarFragment {
@Override
public Fragment createFragment(int position) {
switch (position) {
- case POS_LISTENED_HOURS:
- return new PlaybackStatisticsFragment();
+ case POS_SUBSCRIPTIONS:
+ return new SubscriptionStatisticsFragment();
+ case POS_YEARS:
+ return new YearsStatisticsFragment();
default:
case POS_SPACE_TAKEN:
return new DownloadStatisticsFragment();
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/PlaybackStatisticsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/SubscriptionStatisticsFragment.java
index 31c96a2ff..ef701d35c 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/PlaybackStatisticsFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/SubscriptionStatisticsFragment.java
@@ -43,8 +43,8 @@ import java.util.Locale;
/**
* Displays the 'playback statistics' screen
*/
-public class PlaybackStatisticsFragment extends Fragment {
- private static final String TAG = PlaybackStatisticsFragment.class.getSimpleName();
+public class SubscriptionStatisticsFragment extends Fragment {
+ private static final String TAG = SubscriptionStatisticsFragment.class.getSimpleName();
private static final String PREF_NAME = "StatisticsActivityPrefs";
private static final String PREF_INCLUDE_MARKED_PLAYED = "countAll";
private static final String PREF_FILTER_FROM = "filterFrom";
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/YearsStatisticsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/YearsStatisticsFragment.java
new file mode 100644
index 000000000..c58a59801
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/YearsStatisticsFragment.java
@@ -0,0 +1,87 @@
+package de.danoeh.antennapod.fragment.preferences;
+
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ProgressBar;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.adapter.YearStatisticsListAdapter;
+import de.danoeh.antennapod.core.storage.DBReader;
+import io.reactivex.Observable;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.disposables.Disposable;
+import io.reactivex.schedulers.Schedulers;
+
+/**
+ * Displays the yearly statistics screen
+ */
+public class YearsStatisticsFragment extends Fragment {
+ private static final String TAG = YearsStatisticsFragment.class.getSimpleName();
+
+ private Disposable disposable;
+ private RecyclerView yearStatisticsList;
+ private ProgressBar progressBar;
+ private YearStatisticsListAdapter listAdapter;
+
+ @Nullable
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
+ @Nullable Bundle savedInstanceState) {
+ View root = inflater.inflate(R.layout.statistics_activity, container, false);
+ yearStatisticsList = root.findViewById(R.id.statistics_list);
+ progressBar = root.findViewById(R.id.progressBar);
+ listAdapter = new YearStatisticsListAdapter(getContext());
+ yearStatisticsList.setLayoutManager(new LinearLayoutManager(getContext()));
+ yearStatisticsList.setAdapter(listAdapter);
+ return root;
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ refreshStatistics();
+ }
+
+ @Override
+ public void onDestroyView() {
+ super.onDestroyView();
+ if (disposable != null) {
+ disposable.dispose();
+ }
+ }
+
+ @Override
+ public void onPrepareOptionsMenu(@NonNull Menu menu) {
+ super.onPrepareOptionsMenu(menu);
+ menu.findItem(R.id.statistics_reset).setVisible(false);
+ menu.findItem(R.id.statistics_filter).setVisible(false);
+ }
+
+ private void refreshStatistics() {
+ progressBar.setVisibility(View.VISIBLE);
+ yearStatisticsList.setVisibility(View.GONE);
+ loadStatistics();
+ }
+
+ private void loadStatistics() {
+ if (disposable != null) {
+ disposable.dispose();
+ }
+ disposable = Observable.fromCallable(DBReader::getMonthlyTimeStatistics)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(result -> {
+ listAdapter.update(result);
+ progressBar.setVisibility(View.GONE);
+ yearStatisticsList.setVisibility(View.VISIBLE);
+ }, error -> Log.e(TAG, Log.getStackTraceString(error)));
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/view/LineChartView.java b/app/src/main/java/de/danoeh/antennapod/view/LineChartView.java
new file mode 100644
index 000000000..0eb225e8e
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/view/LineChartView.java
@@ -0,0 +1,138 @@
+package de.danoeh.antennapod.view;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ColorFilter;
+import android.graphics.DashPathEffect;
+import android.graphics.LinearGradient;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.PixelFormat;
+import android.graphics.Shader;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import androidx.annotation.NonNull;
+import androidx.appcompat.widget.AppCompatImageView;
+import androidx.appcompat.widget.ThemeUtils;
+import de.danoeh.antennapod.R;
+import io.reactivex.annotations.Nullable;
+
+public class LineChartView extends AppCompatImageView {
+ private LineChartDrawable drawable;
+
+ public LineChartView(Context context) {
+ super(context);
+ setup();
+ }
+
+ public LineChartView(Context context, @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ setup();
+ }
+
+ public LineChartView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ setup();
+ }
+
+ @SuppressLint("ClickableViewAccessibility")
+ private void setup() {
+ drawable = new LineChartDrawable();
+ setImageDrawable(drawable);
+ }
+
+ /**
+ * Set of data values to display.
+ */
+ public void setData(LineChartData data) {
+ drawable.data = data;
+ }
+
+ public static class LineChartData {
+ private final long valueMax;
+ private final long[] values;
+ private final long[] verticalLines;
+
+ public LineChartData(long[] values, long[] verticalLines) {
+ this.values = values;
+ long valueMax = 0;
+ for (long datum : values) {
+ valueMax = Math.max(datum, valueMax);
+ }
+ this.valueMax = valueMax;
+ this.verticalLines = verticalLines;
+ }
+
+ public float getHeight(int item) {
+ return (float) values[item] / valueMax;
+ }
+ }
+
+ private class LineChartDrawable extends Drawable {
+ private LineChartData data;
+ private final Paint paintLine;
+ private final Paint paintBackground;
+ private final Paint paintVerticalLines;
+
+ private LineChartDrawable() {
+ paintLine = new Paint();
+ paintLine.setFlags(Paint.ANTI_ALIAS_FLAG);
+ paintLine.setStyle(Paint.Style.STROKE);
+ paintLine.setStrokeJoin(Paint.Join.ROUND);
+ paintLine.setStrokeCap(Paint.Cap.ROUND);
+ paintLine.setColor(ThemeUtils.getThemeAttrColor(getContext(), R.attr.colorAccent));
+ paintBackground = new Paint();
+ paintBackground.setStyle(Paint.Style.FILL);
+ paintVerticalLines = new Paint();
+ paintVerticalLines.setStyle(Paint.Style.STROKE);
+ paintVerticalLines.setPathEffect(new DashPathEffect(new float[] {10f, 10f}, 0f));
+ paintVerticalLines.setColor(0x66777777);
+ }
+
+ @Override
+ public void draw(@NonNull Canvas canvas) {
+ float width = getBounds().width();
+ float height = getBounds().height();
+ float usableHeight = height * 0.9f;
+ float stepSize = width / (data.values.length + 1);
+
+ paintVerticalLines.setStrokeWidth(height * 0.005f);
+ for (long line : data.verticalLines) {
+ canvas.drawLine((line + 1) * stepSize, 0, (line + 1) * stepSize, height, paintVerticalLines);
+ }
+
+ paintLine.setStrokeWidth(height * 0.015f);
+ Path path = new Path();
+ for (int i = 0; i < data.values.length; i++) {
+ if (i == 0) {
+ path.moveTo((i + 1) * stepSize, (1 - data.getHeight(i)) * usableHeight + height * 0.05f);
+ } else {
+ path.lineTo((i + 1) * stepSize, (1 - data.getHeight(i)) * usableHeight + height * 0.05f);
+ }
+ }
+ canvas.drawPath(path, paintLine);
+
+ path.lineTo(data.values.length * stepSize, height);
+ path.lineTo(stepSize, height);
+ paintBackground.setShader(new LinearGradient(0, 0, 0, height,
+ (ThemeUtils.getThemeAttrColor(getContext(), R.attr.colorAccent) & 0xffffff) + 0x66000000,
+ Color.TRANSPARENT, Shader.TileMode.CLAMP));
+ canvas.drawPath(path, paintBackground);
+ }
+
+ @Override
+ public int getOpacity() {
+ return PixelFormat.TRANSLUCENT;
+ }
+
+ @Override
+ public void setAlpha(int alpha) {
+ }
+
+ @Override
+ public void setColorFilter(ColorFilter cf) {
+ }
+ }
+}
diff --git a/app/src/main/res/layout/statistics_listitem_linechart.xml b/app/src/main/res/layout/statistics_listitem_linechart.xml
new file mode 100644
index 000000000..0794a1c09
--- /dev/null
+++ b/app/src/main/res/layout/statistics_listitem_linechart.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+ 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">
+
+ <de.danoeh.antennapod.view.LineChartView
+ android:id="@+id/lineChart"
+ android:layout_width="match_parent"
+ android:layout_height="200dp"
+ android:layout_marginStart="8dp"
+ android:layout_marginEnd="8dp" />
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:layout_marginTop="16dp"
+ android:background="?android:attr/dividerVertical" />
+
+</LinearLayout>
diff --git a/app/src/main/res/layout/statistics_year_listitem.xml b/app/src/main/res/layout/statistics_year_listitem.xml
new file mode 100644
index 000000000..48b910c7f
--- /dev/null
+++ b/app/src/main/res/layout/statistics_year_listitem.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingLeft="16dp"
+ android:paddingRight="16dp"
+ android:paddingTop="16dp"
+ android:paddingBottom="8dp"
+ android:background="?android:attr/selectableItemBackground">
+
+ <TextView
+ android:id="@+id/yearLabel"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:lines="1"
+ android:textColor="?android:attr/textColorPrimary"
+ android:textSize="16sp"
+ tools:text="2020" />
+
+ <TextView
+ android:id="@+id/hoursLabel"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:lines="1"
+ android:textColor="?android:attr/textColorTertiary"
+ android:textSize="14sp"
+ tools:text="23 hours" />
+
+</LinearLayout>
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 5ea3f1e14..11ff813a9 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
@@ -771,6 +771,33 @@ public final class DBReader {
}
}
+ public static class MonthlyStatisticsItem {
+ public int year = 0;
+ public int month = 0;
+ public long timePlayed = 0;
+ }
+
+ @NonNull
+ public static List<MonthlyStatisticsItem> getMonthlyTimeStatistics() {
+ List<MonthlyStatisticsItem> months = new ArrayList<>();
+ PodDBAdapter adapter = PodDBAdapter.getInstance();
+ adapter.open();
+ try (Cursor cursor = adapter.getMonthlyStatisticsCursor()) {
+ int indexMonth = cursor.getColumnIndexOrThrow("month");
+ int indexYear = cursor.getColumnIndexOrThrow("year");
+ int indexTotalDuration = cursor.getColumnIndexOrThrow("total_duration");
+ while (cursor.moveToNext()) {
+ MonthlyStatisticsItem item = new MonthlyStatisticsItem();
+ item.month = Integer.parseInt(cursor.getString(indexMonth));
+ item.year = Integer.parseInt(cursor.getString(indexYear));
+ item.timePlayed = cursor.getLong(indexTotalDuration);
+ months.add(item);
+ }
+ }
+ adapter.close();
+ return months;
+ }
+
public static class StatisticsResult {
public List<StatisticsItem> feedTime = new ArrayList<>();
public long oldestDate = System.currentTimeMillis();
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java
index 43d9c7f11..ea4617f16 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java
@@ -1133,6 +1133,17 @@ public class PodDBAdapter {
return db.rawQuery(query, null);
}
+ public final Cursor getMonthlyStatisticsCursor() {
+ final String query = "SELECT SUM(" + KEY_PLAYED_DURATION + ") AS total_duration"
+ + ", strftime('%m', datetime(" + KEY_LAST_PLAYED_TIME + "/1000, 'unixepoch')) AS month"
+ + ", strftime('%Y', datetime(" + KEY_LAST_PLAYED_TIME + "/1000, 'unixepoch')) AS year"
+ + " FROM " + TABLE_NAME_FEED_MEDIA
+ + " WHERE " + KEY_LAST_PLAYED_TIME + " > 0 AND " + KEY_PLAYED_DURATION + " > 0"
+ + " GROUP BY year, month"
+ + " ORDER BY year, month";
+ return db.rawQuery(query, null);
+ }
+
public int getQueueSize() {
final String query = String.format("SELECT COUNT(%s) FROM %s", KEY_ID, TABLE_NAME_QUEUE);
Cursor c = db.rawQuery(query, null);
diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml
index 67dd3b3e4..783065178 100644
--- a/core/src/main/res/values/strings.xml
+++ b/core/src/main/res/values/strings.xml
@@ -28,8 +28,7 @@
<string name="gpodnet_main_label">gpodder.net</string>
<string name="episode_cache_full_title">Episode cache full</string>
<string name="episode_cache_full_message">The episode cache limit has been reached. You can increase the cache size in the Settings.</string>
- <string name="playback_statistics_label">Playback</string>
- <string name="download_statistics_label">Downloads</string>
+ <string name="years_statistics_label">Years</string>
<string name="notification_pref_fragment">Notifications</string>
<!-- Google Assistant -->