summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/build.gradle2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java14
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java3
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/MediaplayerInfoActivity.java14
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/OpmlFeedChooserActivity.java6
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/OpmlImportBaseActivity.java5
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/OpmlImportHolder.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivity.java13
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivityGingerbread.java10
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/itunes/ItunesAdapter.java67
-rw-r--r--app/src/main/java/de/danoeh/antennapod/asynctask/ExportWorker.java65
-rw-r--r--app/src/main/java/de/danoeh/antennapod/asynctask/OpmlExportWorker.java122
-rw-r--r--app/src/main/java/de/danoeh/antennapod/asynctask/OpmlFeedQueuer.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/asynctask/OpmlImportWorker.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java46
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java5
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/FyydSearchFragment.java191
-rw-r--r--app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java100
-rw-r--r--app/src/main/res/layout-v14/time_dialog.xml44
-rw-r--r--app/src/main/res/layout/addfeed.xml56
-rw-r--r--app/src/main/res/layout/time_dialog.xml40
-rw-r--r--app/src/main/res/xml/preferences.xml3
-rw-r--r--build.gradle6
-rw-r--r--core/src/free/java/de/danoeh/antennapod/core/ClientConfig.java3
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/asynctask/FeedRemover.java7
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/backup/OpmlBackupAgent.java22
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/event/MessageEvent.java21
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/export/CommonSymbols.java24
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/export/ExportWriter.java29
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/export/html/HtmlSymbols.java30
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/export/html/HtmlWriter.java82
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/export/opml/OpmlElement.java (renamed from core/src/main/java/de/danoeh/antennapod/core/opml/OpmlElement.java)2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/export/opml/OpmlReader.java (renamed from core/src/main/java/de/danoeh/antennapod/core/opml/OpmlReader.java)2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/export/opml/OpmlSymbols.java21
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/export/opml/OpmlWriter.java (renamed from core/src/main/java/de/danoeh/antennapod/core/opml/OpmlWriter.java)30
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/opml/OpmlSymbols.java22
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/preferences/SleepTimerPreferences.java80
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java16
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java3
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java11
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java51
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java2
-rw-r--r--core/src/main/res/values/arrays.xml2
-rw-r--r--core/src/main/res/values/strings.xml9
-rw-r--r--core/src/main/res/values/styles.xml10
-rw-r--r--core/src/play/java/de/danoeh/antennapod/core/ClientConfig.java2
46 files changed, 913 insertions, 390 deletions
diff --git a/app/build.gradle b/app/build.gradle
index f83b405f7..d15427aef 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -160,6 +160,8 @@ dependencies {
compile "com.github.shts:TriangleLabelView:$triangleLabelViewVersion"
compile "com.github.AntennaPod:AntennaPod-AudioPlayer:$audioPlayerVersion"
+
+ compile 'com.github.mfietz:fyydlin:v0.1'
}
play {
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
index 15313d772..1e03f99fa 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
@@ -10,6 +10,7 @@ import android.database.DataSetObserver;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
+import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
@@ -38,6 +39,7 @@ 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.MessageEvent;
import de.danoeh.antennapod.core.event.ProgressEvent;
import de.danoeh.antennapod.core.event.QueueEvent;
import de.danoeh.antennapod.core.feed.EventDistributor;
@@ -733,6 +735,18 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi
}
}
+ public void onEventMainThread(MessageEvent event) {
+ Log.d(TAG, "onEvent(" + event + ")");
+ View parentLayout = findViewById(R.id.drawer_layout);
+ Snackbar snackbar = Snackbar.make(parentLayout, event.message, Snackbar.LENGTH_SHORT);
+ if(event.action != null) {
+ snackbar.setAction(getString(R.string.undo), v -> {
+ event.action.run();
+ });
+ }
+ snackbar.show();
+ }
+
private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
@Override
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java
index 48b578be7..1cb936296 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java
@@ -47,6 +47,7 @@ import de.danoeh.antennapod.core.util.playback.Playable;
import de.danoeh.antennapod.core.util.playback.PlaybackController;
import de.danoeh.antennapod.dialog.SleepTimerDialog;
import de.danoeh.antennapod.dialog.VariableSpeedDialog;
+import de.greenrobot.event.EventBus;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
@@ -217,6 +218,7 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
controller.pause();
}
super.onPause();
+ EventBus.getDefault().unregister(this);
}
/**
@@ -580,6 +582,7 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
if(controller != null) {
controller.init();
}
+ EventBus.getDefault().register(this);
}
/**
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerInfoActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerInfoActivity.java
index d9b2d10da..4a24f0329 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerInfoActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerInfoActivity.java
@@ -8,6 +8,7 @@ import android.content.res.Configuration;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.design.widget.AppBarLayout;
+import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
@@ -36,6 +37,7 @@ import de.danoeh.antennapod.adapter.ChaptersListAdapter;
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.MessageEvent;
import de.danoeh.antennapod.core.feed.EventDistributor;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedMedia;
@@ -464,7 +466,17 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem
}, error -> Log.e(TAG, Log.getStackTraceString(error)));
}
-
+ public void onEventMainThread(MessageEvent event) {
+ Log.d(TAG, "onEvent(" + event + ")");
+ View parentLayout = findViewById(R.id.drawer_layout);
+ Snackbar snackbar = Snackbar.make(parentLayout, event.message, Snackbar.LENGTH_SHORT);
+ if (event.action != null) {
+ snackbar.setAction(getString(R.string.undo), v -> {
+ event.action.run();
+ });
+ }
+ snackbar.show();
+ }
private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/OpmlFeedChooserActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/OpmlFeedChooserActivity.java
index bc1a40b11..355e0f372 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/OpmlFeedChooserActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/OpmlFeedChooserActivity.java
@@ -15,7 +15,7 @@ import java.util.ArrayList;
import java.util.List;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.core.opml.OpmlElement;
+import de.danoeh.antennapod.core.export.opml.OpmlElement;
import de.danoeh.antennapod.core.preferences.UserPreferences;
/**
@@ -23,10 +23,8 @@ import de.danoeh.antennapod.core.preferences.UserPreferences;
* which feeds he wants to import.
*/
public class OpmlFeedChooserActivity extends AppCompatActivity {
- private static final String TAG = "OpmlFeedChooserActivity";
-
public static final String EXTRA_SELECTED_ITEMS = "de.danoeh.antennapod.selectedItems";
-
+ private static final String TAG = "OpmlFeedChooserActivity";
private Button butConfirm;
private Button butCancel;
private ListView feedlist;
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportBaseActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportBaseActivity.java
index 8726af281..8b87aaaaf 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportBaseActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportBaseActivity.java
@@ -20,7 +20,7 @@ import java.util.ArrayList;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.asynctask.OpmlFeedQueuer;
import de.danoeh.antennapod.asynctask.OpmlImportWorker;
-import de.danoeh.antennapod.core.opml.OpmlElement;
+import de.danoeh.antennapod.core.export.opml.OpmlElement;
import de.danoeh.antennapod.core.util.LangUtils;
/**
@@ -29,9 +29,8 @@ import de.danoeh.antennapod.core.util.LangUtils;
public class OpmlImportBaseActivity extends AppCompatActivity {
private static final String TAG = "OpmlImportBaseActivity";
- private OpmlImportWorker importWorker;
-
private static final int PERMISSION_REQUEST_READ_EXTERNAL_STORAGE = 5;
+ private OpmlImportWorker importWorker;
@Nullable private Uri uri;
/**
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportHolder.java b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportHolder.java
index 7afa270cc..b01cf43e4 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportHolder.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportHolder.java
@@ -1,9 +1,9 @@
package de.danoeh.antennapod.activity;
-import de.danoeh.antennapod.core.opml.OpmlElement;
-
import java.util.ArrayList;
+import de.danoeh.antennapod.core.export.opml.OpmlElement;
+
/**
* Hold infos gathered by Ompl-Import
* <p/>
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivity.java
index 61765d6b7..dd932814f 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivity.java
@@ -26,11 +26,9 @@ import de.danoeh.antennapod.preferences.PreferenceController;
*/
public class PreferenceActivity extends AppCompatActivity {
+ private static WeakReference<PreferenceActivity> instance;
private PreferenceController preferenceController;
private MainFragment prefFragment;
- private static WeakReference<PreferenceActivity> instance;
-
-
private final PreferenceController.PreferenceUI preferenceUI = new PreferenceController.PreferenceUI() {
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
@@ -128,5 +126,14 @@ public class PreferenceActivity extends AppCompatActivity {
}
super.onPause();
}
+
+ @Override
+ public void onStop() {
+ PreferenceActivity activity = instance.get();
+ if(activity != null && activity.preferenceController != null) {
+ activity.preferenceController.onStop();
+ }
+ super.onStop();
+ }
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivityGingerbread.java b/app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivityGingerbread.java
index 4af988ea0..390bec15c 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivityGingerbread.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivityGingerbread.java
@@ -18,9 +18,6 @@ import de.danoeh.antennapod.preferences.PreferenceController;
*/
public class PreferenceActivityGingerbread extends android.preference.PreferenceActivity {
private static final String TAG = "PreferenceActivity";
-
- private PreferenceController preferenceController;
-
private final PreferenceController.PreferenceUI preferenceUI = new PreferenceController.PreferenceUI() {
@SuppressWarnings("deprecation")
@@ -34,6 +31,7 @@ public class PreferenceActivityGingerbread extends android.preference.Preference
return PreferenceActivityGingerbread.this;
}
};
+ private PreferenceController preferenceController;
@SuppressLint("NewApi")
@SuppressWarnings("deprecation")
@@ -61,6 +59,12 @@ public class PreferenceActivityGingerbread extends android.preference.Preference
}
@Override
+ protected void onStop() {
+ preferenceController.onStop();
+ super.onStop();
+ }
+
+ @Override
protected void onApplyThemeResource(Theme theme, int resid, boolean first) {
theme.applyStyle(UserPreferences.getTheme(), true);
}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/itunes/ItunesAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/itunes/ItunesAdapter.java
index e9756b467..e381b4651 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/itunes/ItunesAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/itunes/ItunesAdapter.java
@@ -1,6 +1,7 @@
package de.danoeh.antennapod.adapter.itunes;
import android.content.Context;
+import android.support.annotation.NonNull;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
@@ -18,6 +19,7 @@ import java.util.List;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
+import de.mfietz.fyydlin.SearchHit;
public class ItunesAdapter extends ArrayAdapter<ItunesAdapter.Podcast> {
/**
@@ -42,8 +44,9 @@ public class ItunesAdapter extends ArrayAdapter<ItunesAdapter.Podcast> {
this.context = context;
}
+ @NonNull
@Override
- public View getView(int position, View convertView, ViewGroup parent) {
+ public View getView(int position, View convertView, @NonNull ViewGroup parent) {
//Current podcast
Podcast podcast = data.get(position);
@@ -87,35 +90,6 @@ public class ItunesAdapter extends ArrayAdapter<ItunesAdapter.Podcast> {
}
/**
- * View holder object for the GridView
- */
- class PodcastViewHolder {
-
- /**
- * ImageView holding the Podcast image
- */
- public final ImageView coverView;
-
- /**
- * TextView holding the Podcast title
- */
- public final TextView titleView;
-
- public final TextView urlView;
-
-
- /**
- * Constructor
- * @param view GridView cell
- */
- PodcastViewHolder(View view){
- coverView = (ImageView) view.findViewById(R.id.imgvCover);
- titleView = (TextView) view.findViewById(R.id.txtvTitle);
- urlView = (TextView) view.findViewById(R.id.txtvUrl);
- }
- }
-
- /**
* Represents an individual podcast on the iTunes Store.
*/
public static class Podcast { //TODO: Move this out eventually. Possibly to core.itunes.model
@@ -154,6 +128,10 @@ public class ItunesAdapter extends ArrayAdapter<ItunesAdapter.Podcast> {
return new Podcast(title, imageUrl, feedUrl);
}
+ public static Podcast fromSearch(SearchHit searchHit) {
+ return new Podcast(searchHit.getTitle(), searchHit.getImageUrl(), searchHit.getXmlUrl());
+ }
+
/**
* Constructs a Podcast instance from iTunes toplist entry
*
@@ -177,4 +155,33 @@ public class ItunesAdapter extends ArrayAdapter<ItunesAdapter.Podcast> {
}
}
+
+ /**
+ * View holder object for the GridView
+ */
+ class PodcastViewHolder {
+
+ /**
+ * ImageView holding the Podcast image
+ */
+ final ImageView coverView;
+
+ /**
+ * TextView holding the Podcast title
+ */
+ final TextView titleView;
+
+ final TextView urlView;
+
+
+ /**
+ * Constructor
+ * @param view GridView cell
+ */
+ PodcastViewHolder(View view){
+ coverView = (ImageView) view.findViewById(R.id.imgvCover);
+ titleView = (TextView) view.findViewById(R.id.txtvTitle);
+ urlView = (TextView) view.findViewById(R.id.txtvUrl);
+ }
+ }
}
diff --git a/app/src/main/java/de/danoeh/antennapod/asynctask/ExportWorker.java b/app/src/main/java/de/danoeh/antennapod/asynctask/ExportWorker.java
new file mode 100644
index 000000000..192df8ca5
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/asynctask/ExportWorker.java
@@ -0,0 +1,65 @@
+package de.danoeh.antennapod.asynctask;
+
+import android.support.annotation.NonNull;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+
+import de.danoeh.antennapod.core.export.ExportWriter;
+import de.danoeh.antennapod.core.preferences.UserPreferences;
+import de.danoeh.antennapod.core.storage.DBReader;
+import de.danoeh.antennapod.core.util.LangUtils;
+import rx.Observable;
+
+/**
+ * Writes an OPML file into the export directory in the background.
+ */
+public class ExportWorker {
+
+ private static final String EXPORT_DIR = "export/";
+ private static final String TAG = "ExportWorker";
+ private static final String DEFAULT_OUTPUT_NAME = "antennapod-feeds";
+
+ private ExportWriter exportWriter;
+ private File output;
+
+ public ExportWorker(ExportWriter exportWriter) {
+ this(exportWriter, new File(UserPreferences.getDataFolder(EXPORT_DIR),
+ DEFAULT_OUTPUT_NAME + "." + exportWriter.fileExtension()));
+ }
+
+ public ExportWorker(ExportWriter exportWriter, @NonNull File output) {
+ this.exportWriter = exportWriter;
+ this.output = output;
+ }
+
+ public Observable<File> exportObservable() {
+ if (output.exists()) {
+ Log.w(TAG, "Overwriting previously exported file.");
+ output.delete();
+ }
+ return Observable.create(subscriber -> {
+ OutputStreamWriter writer = null;
+ try {
+ writer = new OutputStreamWriter(new FileOutputStream(output), LangUtils.UTF_8);
+ exportWriter.writeDocument(DBReader.getFeedList(), writer);
+ subscriber.onNext(output);
+ } catch (IOException e) {
+ subscriber.onError(e);
+ } finally {
+ if (writer != null) {
+ try {
+ writer.close();
+ } catch (IOException e) {
+ subscriber.onError(e);
+ }
+ }
+ subscriber.onCompleted();
+ }
+ });
+ }
+
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlExportWorker.java b/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlExportWorker.java
deleted file mode 100644
index 13abb26ea..000000000
--- a/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlExportWorker.java
+++ /dev/null
@@ -1,122 +0,0 @@
-package de.danoeh.antennapod.asynctask;
-
-import android.annotation.SuppressLint;
-import android.app.ProgressDialog;
-import android.content.Context;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.support.v7.app.AlertDialog;
-import android.util.Log;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-
-import de.danoeh.antennapod.core.R;
-import de.danoeh.antennapod.core.opml.OpmlWriter;
-import de.danoeh.antennapod.core.preferences.UserPreferences;
-import de.danoeh.antennapod.core.storage.DBReader;
-import de.danoeh.antennapod.core.util.LangUtils;
-
-/**
- * Writes an OPML file into the export directory in the background.
- */
-public class OpmlExportWorker extends AsyncTask<Void, Void, Void> {
- private static final String TAG = "OpmlExportWorker";
- private static final String DEFAULT_OUTPUT_NAME = "antennapod-feeds.opml";
- public static final String EXPORT_DIR = "export/";
-
- private Context context;
- private File output;
-
- private ProgressDialog progDialog;
- private Exception exception;
-
- public OpmlExportWorker(Context context, File output) {
- this.context = context;
- this.output = output;
- }
-
- public OpmlExportWorker(Context context) {
- this.context = context;
- }
-
- @Override
- protected Void doInBackground(Void... params) {
- OpmlWriter opmlWriter = new OpmlWriter();
- if (output == null) {
- output = new File(
- UserPreferences.getDataFolder(EXPORT_DIR),
- DEFAULT_OUTPUT_NAME);
- if (output.exists()) {
- Log.w(TAG, "Overwriting previously exported file.");
- output.delete();
- }
- }
- OutputStreamWriter writer = null;
- try {
- writer = new OutputStreamWriter(new FileOutputStream(output), LangUtils.UTF_8);
- opmlWriter.writeDocument(DBReader.getFeedList(), writer);
- } catch (IOException e) {
- e.printStackTrace();
- exception = e;
- } finally {
- if (writer != null) {
- try {
- writer.close();
- } catch (IOException ioe) {
- exception = ioe;
- }
- }
- }
- return null;
- }
-
- @Override
- protected void onPostExecute(Void result) {
- progDialog.dismiss();
- AlertDialog.Builder alert = new AlertDialog.Builder(context)
- .setNeutralButton(android.R.string.ok,
- (dialog, which) -> dialog.dismiss());
- if (exception != null) {
- alert.setTitle(R.string.export_error_label);
- alert.setMessage(exception.getMessage());
- } else {
- alert.setTitle(R.string.opml_export_success_title);
- alert.setMessage(context
- .getString(R.string.opml_export_success_sum)
- + output.toString())
- .setPositiveButton(R.string.send_label, (dialog, which) -> {
- Uri outputUri = Uri.fromFile(output);
- Intent sendIntent = new Intent(Intent.ACTION_SEND);
- sendIntent.putExtra(Intent.EXTRA_SUBJECT,
- context.getResources().getText(R.string.opml_export_label));
- sendIntent.putExtra(Intent.EXTRA_STREAM, outputUri);
- sendIntent.setType("text/plain");
- context.startActivity(Intent.createChooser(sendIntent,
- context.getResources().getText(R.string.send_label)));
- });
- }
- alert.create().show();
- }
-
- @Override
- protected void onPreExecute() {
- progDialog = new ProgressDialog(context);
- progDialog.setMessage(context.getString(R.string.exporting_label));
- progDialog.setIndeterminate(true);
- progDialog.show();
- }
-
- @SuppressLint("NewApi")
- public void executeAsync() {
- if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.GINGERBREAD_MR1) {
- executeOnExecutor(THREAD_POOL_EXECUTOR);
- } else {
- execute();
- }
- }
-
-}
diff --git a/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlFeedQueuer.java b/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlFeedQueuer.java
index 1cb653f01..4449d82c2 100644
--- a/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlFeedQueuer.java
+++ b/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlFeedQueuer.java
@@ -9,8 +9,8 @@ import java.util.Arrays;
import de.danoeh.antennapod.activity.OpmlImportHolder;
import de.danoeh.antennapod.core.R;
+import de.danoeh.antennapod.core.export.opml.OpmlElement;
import de.danoeh.antennapod.core.feed.Feed;
-import de.danoeh.antennapod.core.opml.OpmlElement;
import de.danoeh.antennapod.core.storage.DownloadRequestException;
import de.danoeh.antennapod.core.storage.DownloadRequester;
diff --git a/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlImportWorker.java b/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlImportWorker.java
index f3b3aeca9..62ea85811 100644
--- a/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlImportWorker.java
+++ b/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlImportWorker.java
@@ -14,8 +14,8 @@ import java.io.Reader;
import java.util.ArrayList;
import de.danoeh.antennapod.core.R;
-import de.danoeh.antennapod.core.opml.OpmlElement;
-import de.danoeh.antennapod.core.opml.OpmlReader;
+import de.danoeh.antennapod.core.export.opml.OpmlElement;
+import de.danoeh.antennapod.core.export.opml.OpmlReader;
public class OpmlImportWorker extends
AsyncTask<Void, Void, ArrayList<OpmlElement>> {
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java
index 8a13a75d9..0ddee9f61 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java
@@ -1,7 +1,6 @@
package de.danoeh.antennapod.dialog;
import android.content.Context;
-import android.content.SharedPreferences;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
@@ -16,36 +15,25 @@ import android.widget.Toast;
import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
-import java.util.concurrent.TimeUnit;
-
import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.core.preferences.SleepTimerPreferences;
public abstract class SleepTimerDialog {
private static final String TAG = SleepTimerDialog.class.getSimpleName();
- private static final int DEFAULT_SPINNER_POSITION = 1;
-
private Context context;
- private String PREF_NAME = "SleepTimerDialog";
- private String PREF_VALUE = "LastValue";
- private String PREF_TIME_UNIT = "LastTimeUnit";
- private String PREF_VIBRATE = "Vibrate";
- private String PREF_SHAKE_TO_RESET = "ShakeToReset";
- private SharedPreferences prefs;
private MaterialDialog dialog;
private EditText etxtTime;
private Spinner spTimeUnit;
private CheckBox cbShakeToReset;
private CheckBox cbVibrate;
+ private CheckBox chAutoEnable;
- private TimeUnit[] units = { TimeUnit.SECONDS, TimeUnit.MINUTES, TimeUnit.HOURS };
-
public SleepTimerDialog(Context context) {
this.context = context;
- prefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
}
public MaterialDialog createNewDialog() {
@@ -58,7 +46,7 @@ public abstract class SleepTimerDialog {
builder.onPositive((dialog, which) -> {
try {
savePreferences();
- long input = readTimeMillis();
+ long input = SleepTimerPreferences.timerMillis();
onTimerSet(input, cbShakeToReset.isChecked(), cbVibrate.isChecked());
dialog.dismiss();
} catch (NumberFormatException e) {
@@ -75,8 +63,9 @@ public abstract class SleepTimerDialog {
spTimeUnit = (Spinner) view.findViewById(R.id.spTimeUnit);
cbShakeToReset = (CheckBox) view.findViewById(R.id.cbShakeToReset);
cbVibrate = (CheckBox) view.findViewById(R.id.cbVibrate);
+ chAutoEnable = (CheckBox) view.findViewById(R.id.chAutoEnable);
- etxtTime.setText(prefs.getString(PREF_VALUE, "15"));
+ etxtTime.setText(SleepTimerPreferences.lastTimerValue());
etxtTime.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
@@ -104,11 +93,11 @@ public abstract class SleepTimerDialog {
android.R.layout.simple_spinner_item, spinnerContent);
spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spTimeUnit.setAdapter(spinnerAdapter);
- int selection = prefs.getInt(PREF_TIME_UNIT, DEFAULT_SPINNER_POSITION);
- spTimeUnit.setSelection(selection);
+ spTimeUnit.setSelection(SleepTimerPreferences.lastTimerTimeUnit());
- cbShakeToReset.setChecked(prefs.getBoolean(PREF_SHAKE_TO_RESET, true));
- cbVibrate.setChecked(prefs.getBoolean(PREF_VIBRATE, true));
+ cbShakeToReset.setChecked(SleepTimerPreferences.shakeToReset());
+ cbVibrate.setChecked(SleepTimerPreferences.vibrate());
+ chAutoEnable.setChecked(SleepTimerPreferences.autoEnable());
return dialog;
}
@@ -125,19 +114,12 @@ public abstract class SleepTimerDialog {
public abstract void onTimerSet(long millis, boolean shakeToReset, boolean vibrate);
- private long readTimeMillis() {
- TimeUnit selectedUnit = units[spTimeUnit.getSelectedItemPosition()];
- long value = Long.parseLong(etxtTime.getText().toString());
- return selectedUnit.toMillis(value);
- }
-
private void savePreferences() {
- prefs.edit()
- .putString(PREF_VALUE, etxtTime.getText().toString())
- .putInt(PREF_TIME_UNIT, spTimeUnit.getSelectedItemPosition())
- .putBoolean(PREF_SHAKE_TO_RESET, cbShakeToReset.isChecked())
- .putBoolean(PREF_VIBRATE, cbVibrate.isChecked())
- .apply();
+ SleepTimerPreferences.setLastTimer(etxtTime.getText().toString(),
+ spTimeUnit.getSelectedItemPosition());
+ SleepTimerPreferences.setShakeToReset(cbShakeToReset.isChecked());
+ SleepTimerPreferences.setVibrate(cbVibrate.isChecked());
+ SleepTimerPreferences.setAutoEnable(chAutoEnable.isChecked());
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java
index 45364ca07..f14ebbdaf 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java
@@ -39,10 +39,11 @@ public class AddFeedFragment extends Fragment {
etxtFeedurl.setText(args.getString(ARG_FEED_URL));
}
+ Button butSearchITunes = (Button) root.findViewById(R.id.butSearchItunes);
Button butBrowserGpoddernet = (Button) root.findViewById(R.id.butBrowseGpoddernet);
+ Button butSearchFyyd = (Button) root.findViewById(R.id.butSearchFyyd);
Button butOpmlImport = (Button) root.findViewById(R.id.butOpmlImport);
Button butConfirm = (Button) root.findViewById(R.id.butConfirm);
- Button butSearchITunes = (Button) root.findViewById(R.id.butSearchItunes);
final MainActivity activity = (MainActivity) getActivity();
activity.getSupportActionBar().setTitle(R.string.add_feed_label);
@@ -51,6 +52,8 @@ public class AddFeedFragment extends Fragment {
butBrowserGpoddernet.setOnClickListener(v -> activity.loadChildFragment(new GpodnetMainFragment()));
+ butSearchFyyd.setOnClickListener(v -> activity.loadChildFragment(new FyydSearchFragment()));
+
butOpmlImport.setOnClickListener(v -> startActivity(new Intent(getActivity(),
OpmlImportFromPathActivity.class)));
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FyydSearchFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/FyydSearchFragment.java
new file mode 100644
index 000000000..7fcf9c93d
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/FyydSearchFragment.java
@@ -0,0 +1,191 @@
+package de.danoeh.antennapod.fragment;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.view.MenuItemCompat;
+import android.support.v7.widget.SearchView;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.GridView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.activity.OnlineFeedViewActivity;
+import de.danoeh.antennapod.adapter.itunes.ItunesAdapter;
+import de.danoeh.antennapod.menuhandler.MenuItemUtils;
+import de.mfietz.fyydlin.FyydClient;
+import de.mfietz.fyydlin.FyydResponse;
+import de.mfietz.fyydlin.SearchHit;
+import rx.Subscription;
+import rx.android.schedulers.AndroidSchedulers;
+import rx.schedulers.Schedulers;
+
+import static de.danoeh.antennapod.adapter.itunes.ItunesAdapter.Podcast;
+import static java.util.Collections.emptyList;
+
+public class FyydSearchFragment extends Fragment {
+
+ private static final String TAG = "FyydSearchFragment";
+
+ /**
+ * Adapter responsible with the search results
+ */
+ private ItunesAdapter adapter;
+ private GridView gridView;
+ private ProgressBar progressBar;
+ private TextView txtvError;
+ private Button butRetry;
+ private TextView txtvEmpty;
+
+ private FyydClient client = new FyydClient();
+
+ /**
+ * List of podcasts retreived from the search
+ */
+ private List<Podcast> searchResults;
+ private Subscription subscription;
+
+ /**
+ * Constructor
+ */
+ public FyydSearchFragment() {
+ // Required empty public constructor
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setHasOptionsMenu(true);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ // Inflate the layout for this fragment
+ View root = inflater.inflate(R.layout.fragment_itunes_search, container, false);
+ gridView = (GridView) root.findViewById(R.id.gridView);
+ adapter = new ItunesAdapter(getActivity(), new ArrayList<>());
+ gridView.setAdapter(adapter);
+
+ //Show information about the podcast when the list item is clicked
+ gridView.setOnItemClickListener((parent, view1, position, id) -> {
+ Podcast podcast = searchResults.get(position);
+ Intent intent = new Intent(getActivity(), OnlineFeedViewActivity.class);
+ intent.putExtra(OnlineFeedViewActivity.ARG_FEEDURL, podcast.feedUrl);
+ intent.putExtra(OnlineFeedViewActivity.ARG_TITLE, podcast.title);
+ startActivity(intent);
+ });
+ progressBar = (ProgressBar) root.findViewById(R.id.progressBar);
+ txtvError = (TextView) root.findViewById(R.id.txtvError);
+ butRetry = (Button) root.findViewById(R.id.butRetry);
+ txtvEmpty = (TextView) root.findViewById(android.R.id.empty);
+
+ return root;
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ if (subscription != null) {
+ subscription.unsubscribe();
+ }
+ adapter = null;
+ }
+
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ super.onCreateOptionsMenu(menu, inflater);
+ inflater.inflate(R.menu.itunes_search, menu);
+ MenuItem searchItem = menu.findItem(R.id.action_search);
+ final SearchView sv = (SearchView) MenuItemCompat.getActionView(searchItem);
+ MenuItemUtils.adjustTextColor(getActivity(), sv);
+ sv.setQueryHint(getString(R.string.search_fyyd_label));
+ sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
+ @Override
+ public boolean onQueryTextSubmit(String s) {
+ sv.clearFocus();
+ search(s);
+ return true;
+ }
+
+ @Override
+ public boolean onQueryTextChange(String s) {
+ return false;
+ }
+ });
+ MenuItemCompat.setOnActionExpandListener(searchItem, new MenuItemCompat.OnActionExpandListener() {
+ @Override
+ public boolean onMenuItemActionExpand(MenuItem item) {
+ return true;
+ }
+
+ @Override
+ public boolean onMenuItemActionCollapse(MenuItem item) {
+ getActivity().getSupportFragmentManager().popBackStack();
+ return true;
+ }
+ });
+ MenuItemCompat.expandActionView(searchItem);
+ }
+
+ private void search(String query) {
+ if (subscription != null) {
+ subscription.unsubscribe();
+ }
+ showOnlyProgressBar();
+ subscription = client.searchPodcasts(query)
+ .subscribeOn(Schedulers.newThread())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(result -> {
+ progressBar.setVisibility(View.GONE);
+ processSearchResult(result);
+ }, error -> {
+ Log.e(TAG, Log.getStackTraceString(error));
+ progressBar.setVisibility(View.GONE);
+ txtvError.setText(error.toString());
+ txtvError.setVisibility(View.VISIBLE);
+ butRetry.setOnClickListener(v -> search(query));
+ butRetry.setVisibility(View.VISIBLE);
+ });
+ }
+
+ private void showOnlyProgressBar() {
+ gridView.setVisibility(View.GONE);
+ txtvError.setVisibility(View.GONE);
+ butRetry.setVisibility(View.GONE);
+ txtvEmpty.setVisibility(View.GONE);
+ progressBar.setVisibility(View.VISIBLE);
+ }
+
+ void processSearchResult(FyydResponse response) {
+ adapter.clear();
+ if (!response.getData().isEmpty()) {
+ adapter.clear();
+ searchResults = new ArrayList<>();
+ for (SearchHit searchHit : response.getData().values()) {
+ Podcast podcast = Podcast.fromSearch(searchHit);
+ searchResults.add(podcast);
+ }
+ } else {
+ searchResults = emptyList();
+ }
+ for(Podcast podcast : searchResults) {
+ adapter.add(podcast);
+ }
+ adapter.notifyDataSetInvalidated();
+ gridView.setVisibility(!searchResults.isEmpty() ? View.VISIBLE : View.GONE);
+ txtvEmpty.setVisibility(searchResults.isEmpty() ? View.VISIBLE : View.GONE);
+ }
+
+}
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 85eaafcad..818b3a625 100644
--- a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java
+++ b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java
@@ -3,6 +3,7 @@ package de.danoeh.antennapod.preferences;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
+import android.app.ProgressDialog;
import android.app.TimePickerDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
@@ -54,7 +55,10 @@ 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.asynctask.ExportWorker;
+import de.danoeh.antennapod.core.export.ExportWriter;
+import de.danoeh.antennapod.core.export.html.HtmlWriter;
+import de.danoeh.antennapod.core.export.opml.OpmlWriter;
import de.danoeh.antennapod.core.preferences.GpodnetPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.GpodnetSyncService;
@@ -66,6 +70,10 @@ import de.danoeh.antennapod.dialog.AutoFlattrPreferenceDialog;
import de.danoeh.antennapod.dialog.GpodnetSetHostnameDialog;
import de.danoeh.antennapod.dialog.ProxyDialog;
import de.danoeh.antennapod.dialog.VariableSpeedDialog;
+import rx.Observable;
+import rx.Subscription;
+import rx.android.schedulers.AndroidSchedulers;
+import rx.schedulers.Schedulers;
/**
* Sets up a preference UI that lets the user change user preferences.
@@ -80,6 +88,7 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
private static final String PREF_FLATTR_REVOKE = "prefRevokeAccess";
private static final String PREF_AUTO_FLATTR_PREFS = "prefAutoFlattrPrefs";
private static final String PREF_OPML_EXPORT = "prefOpmlExport";
+ private static final String PREF_HTML_EXPORT = "prefHtmlExport";
private static final String STATISTICS = "statistics";
private static final String PREF_ABOUT = "prefAbout";
private static final String PREF_CHOOSE_DATA_DIR = "prefChooseDataDir";
@@ -97,32 +106,11 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
private static final String PREF_KNOWN_ISSUES = "prefKnownIssues";
private static final String PREF_FAQ = "prefFaq";
private static final String PREF_SEND_CRASH_REPORT = "prefSendCrashReport";
-
- private final PreferenceUI ui;
-
- private CheckBoxPreference[] selectedNetworks;
-
private static final String[] EXTERNAL_STORAGE_PERMISSIONS = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE };
private static final int PERMISSION_REQUEST_EXTERNAL_STORAGE = 41;
-
- public PreferenceController(PreferenceUI ui) {
- this.ui = ui;
- PreferenceManager.getDefaultSharedPreferences(ui.getActivity().getApplicationContext())
- .registerOnSharedPreferenceChangeListener(this);
- }
-
- @Override
- public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
- if(key.equals(UserPreferences.PREF_SONIC)) {
- CheckBoxPreference prefSonic = (CheckBoxPreference) ui.findPreference(UserPreferences.PREF_SONIC);
- if(prefSonic != null) {
- prefSonic.setChecked(sharedPreferences.getBoolean(UserPreferences.PREF_SONIC, false));
- }
- }
- }
-
+ private final PreferenceUI ui;
private final SharedPreferences.OnSharedPreferenceChangeListener gpoddernetListener =
(sharedPreferences, key) -> {
if (GpodnetPreferences.PREF_LAST_SYNC_ATTEMPT_TIMESTAMP.equals(key)) {
@@ -130,6 +118,14 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
GpodnetPreferences.getLastSyncAttemptTimestamp());
}
};
+ private CheckBoxPreference[] selectedNetworks;
+ private Subscription subscription;
+
+ public PreferenceController(PreferenceUI ui) {
+ this.ui = ui;
+ PreferenceManager.getDefaultSharedPreferences(ui.getActivity().getApplicationContext())
+ .registerOnSharedPreferenceChangeListener(this);
+ }
/**
* Returns the preference activity that should be used on this device.
@@ -144,6 +140,16 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
}
}
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+ if(key.equals(UserPreferences.PREF_SONIC)) {
+ CheckBoxPreference prefSonic = (CheckBoxPreference) ui.findPreference(UserPreferences.PREF_SONIC);
+ if(prefSonic != null) {
+ prefSonic.setChecked(sharedPreferences.getBoolean(UserPreferences.PREF_SONIC, false));
+ }
+ }
+ }
+
public void onCreate() {
final Activity activity = ui.getActivity();
@@ -179,11 +185,9 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
}
);
ui.findPreference(PreferenceController.PREF_OPML_EXPORT).setOnPreferenceClickListener(
- preference -> {
- new OpmlExportWorker(activity).executeAsync();
- return true;
- }
- );
+ preference -> export(new OpmlWriter()));
+ ui.findPreference(PreferenceController.PREF_HTML_EXPORT).setOnPreferenceClickListener(
+ preference -> export(new HtmlWriter()));
ui.findPreference(PreferenceController.PREF_CHOOSE_DATA_DIR).setOnPreferenceClickListener(
preference -> {
if (Build.VERSION_CODES.KITKAT <= Build.VERSION.SDK_INT &&
@@ -440,6 +444,40 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
setSelectedNetworksEnabled(UserPreferences.isEnableAutodownloadWifiFilter());
}
+ private boolean export(ExportWriter exportWriter) {
+ Context context = ui.getActivity();
+ final ProgressDialog progressDialog = new ProgressDialog(context);
+ progressDialog.setMessage(context.getString(R.string.exporting_label));
+ progressDialog.setIndeterminate(true);
+ progressDialog.show();
+ final AlertDialog.Builder alert = new AlertDialog.Builder(context)
+ .setNeutralButton(android.R.string.ok, (dialog, which) -> dialog.dismiss());
+ Observable<File> observable = new ExportWorker(exportWriter).exportObservable();
+ subscription = observable.subscribeOn(Schedulers.newThread())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(output -> {
+ alert.setTitle(R.string.opml_export_success_title);
+ String message = context.getString(R.string.opml_export_success_sum) + output.toString();
+ alert.setMessage(message);
+ alert.setPositiveButton(R.string.send_label, (dialog, which) -> {
+ Uri outputUri = Uri.fromFile(output);
+ Intent sendIntent = new Intent(Intent.ACTION_SEND);
+ sendIntent.putExtra(Intent.EXTRA_SUBJECT,
+ context.getResources().getText(R.string.opml_export_label));
+ sendIntent.putExtra(Intent.EXTRA_STREAM, outputUri);
+ sendIntent.setType("text/plain");
+ context.startActivity(Intent.createChooser(sendIntent,
+ context.getResources().getText(R.string.send_label)));
+ });
+ alert.create().show();
+ }, error -> {
+ alert.setTitle(R.string.export_error_label);
+ alert.setMessage(error.getMessage());
+ alert.show();
+ }, () -> progressDialog.dismiss());
+ return true;
+ }
+
private void openInBrowser(String url) {
try {
Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
@@ -464,6 +502,12 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
GpodnetPreferences.unregisterOnSharedPreferenceChangeListener(gpoddernetListener);
}
+ public void onStop() {
+ if(subscription != null) {
+ subscription.unsubscribe();
+ }
+ }
+
@SuppressLint("NewApi")
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK &&
diff --git a/app/src/main/res/layout-v14/time_dialog.xml b/app/src/main/res/layout-v14/time_dialog.xml
index 06c2cce14..ba4249268 100644
--- a/app/src/main/res/layout-v14/time_dialog.xml
+++ b/app/src/main/res/layout-v14/time_dialog.xml
@@ -33,26 +33,34 @@
</LinearLayout>
<LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="8dp"
+ android:text="@string/timer_about_to_expire_label"
+ android:textSize="16sp" />
+
+ <CheckBox
+ android:id="@+id/cbShakeToReset"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/shake_to_reset_label" />
+
+ <CheckBox
+ android:id="@+id/cbVibrate"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/timer_vibration_label" />
+
+ <CheckBox
+ android:id="@+id/chAutoEnable"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:orientation="vertical">
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
- android:textSize="16sp"
- android:text="@string/timer_about_to_expire_label"/>
-
- <CheckBox android:id="@+id/cbShakeToReset"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/shake_to_reset_label"/>
-
- <CheckBox android:id="@+id/cbVibrate"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/timer_vibration_label"/>
+ android:text="@string/auto_enable_label" />
</LinearLayout>
diff --git a/app/src/main/res/layout/addfeed.xml b/app/src/main/res/layout/addfeed.xml
index dff24c650..33951e060 100644
--- a/app/src/main/res/layout/addfeed.xml
+++ b/app/src/main/res/layout/addfeed.xml
@@ -7,18 +7,18 @@
<LinearLayout
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingTop="8dp"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingBottom="8dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
- android:paddingBottom="8dp"
- android:orientation="vertical">
+ android:paddingTop="8dp">
<TextView
android:id="@+id/txtvPodcastDirectories"
+ style="@style/AntennaPod.TextView.Heading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- style="@style/AntennaPod.TextView.Heading"
android:text="@string/podcastdirectories_label"/>
<TextView
@@ -26,83 +26,73 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/podcastdirectories_descr"
- android:textSize="@dimen/text_size_medium"
- android:layout_marginTop="4dp"/>
+ android:textSize="@dimen/text_size_medium"/>
<Button
android:id="@+id/butSearchItunes"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
+ android:layout_marginTop="4dp"
android:text="@string/search_itunes_label"/>
<Button
+ android:id="@+id/butSearchFyyd"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/search_fyyd_label"/>
+
+ <Button
android:id="@+id/butBrowseGpoddernet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
android:text="@string/browse_gpoddernet_label"/>
- <View
- android:id="@+id/divider1"
- android:layout_width="match_parent"
- android:layout_height="1dp"
- android:layout_margin="16dp"
- android:background="?android:attr/listDivider"/>
+ <View style="@style/Divider"/>
<TextView
android:id="@+id/txtvFeedurl"
+ style="@style/AntennaPod.TextView.Heading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_below="@id/divider1"
- style="@style/AntennaPod.TextView.Heading"
android:text="@string/txtvfeedurl_label"/>
<EditText
android:id="@+id/etxtFeedurl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginTop="4dp"
- android:hint="@string/etxtFeedurlHint"
- android:inputType="textUri"
+ android:cursorVisible="true"
android:focusable="true"
android:focusableInTouchMode="true"
- android:cursorVisible="true"/>
+ android:hint="@string/etxtFeedurlHint"
+ android:inputType="textUri"/>
<Button
android:id="@+id/butConfirm"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
android:text="@string/confirm_label"/>
- <View
- android:id="@+id/divider2"
- android:layout_width="match_parent"
- android:layout_height="1dp"
- android:layout_margin="16dp"
- android:background="?android:attr/listDivider"/>
+ <View style="@style/Divider"/>
<TextView
android:id="@+id/txtvOpmlImport"
+ style="@style/AntennaPod.TextView.Heading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- style="@style/AntennaPod.TextView.Heading"
android:text="@string/opml_import_label"/>
<TextView
android:id="@+id/txtvOpmlImportExpl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginTop="4dp"
- android:textSize="@dimen/text_size_medium"
- android:text="@string/opml_import_txtv_button_lable"/>
+ android:text="@string/opml_import_txtv_button_lable"
+ android:textSize="@dimen/text_size_medium"/>
<Button
android:id="@+id/butOpmlImport"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
+ android:layout_marginTop="4dp"
android:text="@string/opml_import_label"/>
</LinearLayout>
diff --git a/app/src/main/res/layout/time_dialog.xml b/app/src/main/res/layout/time_dialog.xml
index b270e82f7..0290ce708 100644
--- a/app/src/main/res/layout/time_dialog.xml
+++ b/app/src/main/res/layout/time_dialog.xml
@@ -36,22 +36,30 @@
android:layout_height="wrap_content"
android:orientation="vertical">
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
- android:textSize="16sp"
- android:text="@string/timer_about_to_expire_label"/>
-
- <CheckBox android:id="@+id/cbShakeToReset"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/shake_to_reset_label"/>
-
- <CheckBox android:id="@+id/cbVibrate"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/timer_vibration_label"/>
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="8dp"
+ android:text="@string/timer_about_to_expire_label"
+ android:textSize="16sp" />
+
+ <CheckBox
+ android:id="@+id/cbShakeToReset"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/shake_to_reset_label" />
+
+ <CheckBox
+ android:id="@+id/cbVibrate"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/timer_vibration_label" />
+
+ <CheckBox
+ android:id="@+id/chAutoEnable"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/auto_enable_label" />
</LinearLayout>
diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml
index 5f56b14df..fab96338e 100644
--- a/app/src/main/res/xml/preferences.xml
+++ b/app/src/main/res/xml/preferences.xml
@@ -289,6 +289,9 @@
android:key="prefOpmlExport"
android:title="@string/opml_export_label"/>
<Preference
+ android:key="prefHtmlExport"
+ android:title="@string/html_export_label"/>
+ <Preference
android:key="statistics"
android:title="@string/statistics_label"/>
</PreferenceCategory>
diff --git a/build.gradle b/build.gradle
index 221f5a68c..ad88bb7bf 100644
--- a/build.gradle
+++ b/build.gradle
@@ -6,10 +6,10 @@ buildscript {
mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:2.2.0'
- classpath "me.tatarka:gradle-retrolambda:3.3.0"
+ classpath "com.android.tools.build:gradle:2.2.2"
+ classpath "me.tatarka:gradle-retrolambda:3.3.1"
classpath "me.tatarka.retrolambda.projectlombok:lombok.ast:0.2.3.a2"
- classpath 'com.github.triplet.gradle:play-publisher:1.1.4'
+ classpath "com.github.triplet.gradle:play-publisher:1.1.4"
// Exclude the version that the android plugin depends on.
configurations.classpath.exclude group: "com.android.tools.external.lombok"
}
diff --git a/core/src/free/java/de/danoeh/antennapod/core/ClientConfig.java b/core/src/free/java/de/danoeh/antennapod/core/ClientConfig.java
index eb2e6fc9e..88ae6d6bc 100644
--- a/core/src/free/java/de/danoeh/antennapod/core/ClientConfig.java
+++ b/core/src/free/java/de/danoeh/antennapod/core/ClientConfig.java
@@ -3,6 +3,7 @@ package de.danoeh.antennapod.core;
import android.content.Context;
import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
+import de.danoeh.antennapod.core.preferences.SleepTimerPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
import de.danoeh.antennapod.core.util.NetworkUtils;
@@ -43,7 +44,7 @@ public class ClientConfig {
UpdateManager.init(context);
PlaybackPreferences.init(context);
NetworkUtils.init(context);
-// CastManager.init(context);
+ SleepTimerPreferences.init(context);
initialized = true;
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/asynctask/FeedRemover.java b/core/src/main/java/de/danoeh/antennapod/core/asynctask/FeedRemover.java
index e475e696c..67c460e78 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/asynctask/FeedRemover.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/asynctask/FeedRemover.java
@@ -38,10 +38,11 @@ public class FeedRemover extends AsyncTask<Void, Void, Void> {
@Override
protected void onPostExecute(Void result) {
- dialog.dismiss();
+ if(dialog != null && dialog.isShowing()) {
+ dialog.dismiss();
+ }
if(skipOnCompletion) {
- context.sendBroadcast(new Intent(
- PlaybackService.ACTION_SKIP_CURRENT_EPISODE));
+ context.sendBroadcast(new Intent(PlaybackService.ACTION_SKIP_CURRENT_EPISODE));
}
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/backup/OpmlBackupAgent.java b/core/src/main/java/de/danoeh/antennapod/core/backup/OpmlBackupAgent.java
index 982015314..80ce6cf56 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/backup/OpmlBackupAgent.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/backup/OpmlBackupAgent.java
@@ -8,6 +8,7 @@ import android.content.Context;
import android.os.ParcelFileDescriptor;
import android.util.Log;
+import org.apache.commons.io.IOUtils;
import org.xmlpull.v1.XmlPullParserException;
import java.io.ByteArrayOutputStream;
@@ -27,10 +28,10 @@ import java.util.ArrayList;
import java.util.Arrays;
import de.danoeh.antennapod.core.BuildConfig;
+import de.danoeh.antennapod.core.export.opml.OpmlElement;
+import de.danoeh.antennapod.core.export.opml.OpmlReader;
+import de.danoeh.antennapod.core.export.opml.OpmlWriter;
import de.danoeh.antennapod.core.feed.Feed;
-import de.danoeh.antennapod.core.opml.OpmlElement;
-import de.danoeh.antennapod.core.opml.OpmlReader;
-import de.danoeh.antennapod.core.opml.OpmlWriter;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DownloadRequestException;
import de.danoeh.antennapod.core.storage.DownloadRequester;
@@ -56,7 +57,9 @@ public class OpmlBackupAgent extends BackupAgentHelper {
}
}
- /** Class for backing up and restoring the OPML file. */
+ /**
+ * Class for backing up and restoring the OPML file.
+ */
private static class OpmlBackupHelper implements BackupHelper {
private static final String TAG = "OpmlBackupHelper";
@@ -64,7 +67,9 @@ public class OpmlBackupAgent extends BackupAgentHelper {
private final Context mContext;
- /** Checksum of restored OPML file */
+ /**
+ * Checksum of restored OPML file
+ */
private byte[] mChecksum;
public OpmlBackupHelper(Context context) {
@@ -170,12 +175,7 @@ public class OpmlBackupAgent extends BackupAgentHelper {
} catch (IOException e) {
Log.e(TAG, "Failed to restore OPML backup", e);
} finally {
- if (reader != null) {
- try {
- reader.close();
- } catch (IOException e) {
- }
- }
+ IOUtils.closeQuietly(reader);
}
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/event/MessageEvent.java b/core/src/main/java/de/danoeh/antennapod/core/event/MessageEvent.java
new file mode 100644
index 000000000..9fc488fbc
--- /dev/null
+++ b/core/src/main/java/de/danoeh/antennapod/core/event/MessageEvent.java
@@ -0,0 +1,21 @@
+package de.danoeh.antennapod.core.event;
+
+import android.support.annotation.Nullable;
+
+public class MessageEvent {
+
+ public final String message;
+
+ @Nullable
+ public final Runnable action;
+
+ public MessageEvent(String message) {
+ this(message, null);
+ }
+
+ public MessageEvent(String message, Runnable action) {
+ this.message = message;
+ this.action = action;
+ }
+
+}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/export/CommonSymbols.java b/core/src/main/java/de/danoeh/antennapod/core/export/CommonSymbols.java
new file mode 100644
index 000000000..3ed251047
--- /dev/null
+++ b/core/src/main/java/de/danoeh/antennapod/core/export/CommonSymbols.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package de.danoeh.antennapod.core.export;
+
+public class CommonSymbols {
+
+ public static final String HEAD = "head";
+ public static final String BODY = "body";
+ public static final String TITLE = "title";
+
+ public static final String XML_FEATURE_INDENT_OUTPUT = "http://xmlpull.org/v1/doc/features.html#indent-output";
+
+}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/export/ExportWriter.java b/core/src/main/java/de/danoeh/antennapod/core/export/ExportWriter.java
new file mode 100644
index 000000000..d6a187b21
--- /dev/null
+++ b/core/src/main/java/de/danoeh/antennapod/core/export/ExportWriter.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package de.danoeh.antennapod.core.export;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.List;
+
+import de.danoeh.antennapod.core.feed.Feed;
+
+public interface ExportWriter {
+
+ void writeDocument(List<Feed> feeds, Writer writer)
+ throws IllegalArgumentException, IllegalStateException, IOException;
+
+ String fileExtension();
+
+}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/export/html/HtmlSymbols.java b/core/src/main/java/de/danoeh/antennapod/core/export/html/HtmlSymbols.java
new file mode 100644
index 000000000..b8807a686
--- /dev/null
+++ b/core/src/main/java/de/danoeh/antennapod/core/export/html/HtmlSymbols.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package de.danoeh.antennapod.core.export.html;
+
+import de.danoeh.antennapod.core.export.CommonSymbols;
+
+class HtmlSymbols extends CommonSymbols {
+
+ static final String HTML = "html";
+
+ static final String ORDERED_LIST = "ol";
+ static final String LIST_ITEM = "li";
+
+ static String HEADING = "h1";
+
+ static final String LINK = "a";
+ static final String LINK_DESTINATION = "href";
+
+}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/export/html/HtmlWriter.java b/core/src/main/java/de/danoeh/antennapod/core/export/html/HtmlWriter.java
new file mode 100644
index 000000000..c24b39812
--- /dev/null
+++ b/core/src/main/java/de/danoeh/antennapod/core/export/html/HtmlWriter.java
@@ -0,0 +1,82 @@
+package de.danoeh.antennapod.core.export.html;
+
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.Xml;
+
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.List;
+
+import de.danoeh.antennapod.core.export.ExportWriter;
+import de.danoeh.antennapod.core.feed.Feed;
+
+/** Writes HTML documents. */
+public class HtmlWriter implements ExportWriter {
+
+ private static final String TAG = "HtmlWriter";
+ private static final String ENCODING = "UTF-8";
+ private static final String HTML_TITLE = "AntennaPod Subscriptions";
+
+ /**
+ * Takes a list of feeds and a writer and writes those into an HTML
+ * document.
+ *
+ * @throws IOException
+ * @throws IllegalStateException
+ * @throws IllegalArgumentException
+ */
+ @Override
+ public void writeDocument(List<Feed> feeds, Writer writer)
+ throws IllegalArgumentException, IllegalStateException, IOException {
+ Log.d(TAG, "Starting to write document");
+ XmlSerializer xs = Xml.newSerializer();
+ xs.setFeature(HtmlSymbols.XML_FEATURE_INDENT_OUTPUT, true);
+ xs.setOutput(writer);
+
+ xs.startDocument(ENCODING, false);
+ xs.startTag(null, HtmlSymbols.HTML);
+ xs.startTag(null, HtmlSymbols.HEAD);
+ xs.startTag(null, HtmlSymbols.TITLE);
+ xs.text(HTML_TITLE);
+ xs.endTag(null, HtmlSymbols.TITLE);
+ xs.endTag(null, HtmlSymbols.HEAD);
+
+ xs.startTag(null, HtmlSymbols.BODY);
+ xs.startTag(null, HtmlSymbols.HEADING);
+ xs.text(HTML_TITLE);
+ xs.endTag(null, HtmlSymbols.HEADING);
+ xs.startTag(null, HtmlSymbols.ORDERED_LIST);
+ for (Feed feed : feeds) {
+ xs.startTag(null, HtmlSymbols.LIST_ITEM);
+ xs.text(feed.getTitle());
+ if (!TextUtils.isEmpty(feed.getLink())) {
+ xs.text(" [");
+ xs.startTag(null, HtmlSymbols.LINK);
+ xs.attribute(null, HtmlSymbols.LINK_DESTINATION, feed.getLink());
+ xs.text("Website");
+ xs.endTag(null, HtmlSymbols.LINK);
+ xs.text("]");
+ }
+ xs.text(" [");
+ xs.startTag(null, HtmlSymbols.LINK);
+ xs.attribute(null, HtmlSymbols.LINK_DESTINATION, feed.getDownload_url());
+ xs.text("Feed");
+ xs.endTag(null, HtmlSymbols.LINK);
+ xs.text("]");
+ xs.endTag(null, HtmlSymbols.LIST_ITEM);
+ }
+ xs.endTag(null, HtmlSymbols.ORDERED_LIST);
+ xs.endTag(null, HtmlSymbols.BODY);
+ xs.endTag(null, HtmlSymbols.HTML);
+ xs.endDocument();
+ Log.d(TAG, "Finished writing document");
+ }
+
+ public String fileExtension() {
+ return "html";
+ }
+
+}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/opml/OpmlElement.java b/core/src/main/java/de/danoeh/antennapod/core/export/opml/OpmlElement.java
index 8d0a4a842..61eb4d0c9 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/opml/OpmlElement.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/export/opml/OpmlElement.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.core.opml;
+package de.danoeh.antennapod.core.export.opml;
/** Represents a single feed in an OPML file. */
public class OpmlElement {
diff --git a/core/src/main/java/de/danoeh/antennapod/core/opml/OpmlReader.java b/core/src/main/java/de/danoeh/antennapod/core/export/opml/OpmlReader.java
index 17afc7904..a17fedd7d 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/opml/OpmlReader.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/export/opml/OpmlReader.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.core.opml;
+package de.danoeh.antennapod.core.export.opml;
import android.util.Log;
diff --git a/core/src/main/java/de/danoeh/antennapod/core/export/opml/OpmlSymbols.java b/core/src/main/java/de/danoeh/antennapod/core/export/opml/OpmlSymbols.java
new file mode 100644
index 000000000..40b0e23b8
--- /dev/null
+++ b/core/src/main/java/de/danoeh/antennapod/core/export/opml/OpmlSymbols.java
@@ -0,0 +1,21 @@
+package de.danoeh.antennapod.core.export.opml;
+
+import de.danoeh.antennapod.core.export.CommonSymbols;
+
+/** Contains symbols for reading and writing OPML documents. */
+public final class OpmlSymbols extends CommonSymbols {
+
+ public static final String OPML = "opml";
+ static final String OUTLINE = "outline";
+ static final String TEXT = "text";
+ static final String XMLURL = "xmlUrl";
+ static final String HTMLURL = "htmlUrl";
+ static final String TYPE = "type";
+ static final String VERSION = "version";
+ static final String DATE_CREATED = "dateCreated";
+
+ private OpmlSymbols() {
+
+ }
+
+}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/opml/OpmlWriter.java b/core/src/main/java/de/danoeh/antennapod/core/export/opml/OpmlWriter.java
index 673c602df..fd0922f72 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/opml/OpmlWriter.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/export/opml/OpmlWriter.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.core.opml;
+package de.danoeh.antennapod.core.export.opml;
import android.util.Log;
import android.util.Xml;
@@ -10,11 +10,13 @@ import java.io.Writer;
import java.util.Date;
import java.util.List;
+import de.danoeh.antennapod.core.export.ExportWriter;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.util.DateUtils;
/** Writes OPML documents. */
-public class OpmlWriter {
+public class OpmlWriter implements ExportWriter {
+
private static final String TAG = "OpmlWriter";
private static final String ENCODING = "UTF-8";
private static final String OPML_VERSION = "2.0";
@@ -28,40 +30,29 @@ public class OpmlWriter {
* @throws IllegalStateException
* @throws IllegalArgumentException
*/
+ @Override
public void writeDocument(List<Feed> feeds, Writer writer)
throws IllegalArgumentException, IllegalStateException, IOException {
Log.d(TAG, "Starting to write document");
XmlSerializer xs = Xml.newSerializer();
+ xs.setFeature(OpmlSymbols.XML_FEATURE_INDENT_OUTPUT, true);
xs.setOutput(writer);
xs.startDocument(ENCODING, false);
- xs.text("\n");
xs.startTag(null, OpmlSymbols.OPML);
xs.attribute(null, OpmlSymbols.VERSION, OPML_VERSION);
- xs.text("\n");
- xs.text(" ");
xs.startTag(null, OpmlSymbols.HEAD);
- xs.text("\n");
- xs.text(" ");
xs.startTag(null, OpmlSymbols.TITLE);
xs.text(OPML_TITLE);
xs.endTag(null, OpmlSymbols.TITLE);
- xs.text("\n");
- xs.text(" ");
xs.startTag(null, OpmlSymbols.DATE_CREATED);
xs.text(DateUtils.formatRFC822Date(new Date()));
xs.endTag(null, OpmlSymbols.DATE_CREATED);
- xs.text("\n");
- xs.text(" ");
xs.endTag(null, OpmlSymbols.HEAD);
- xs.text("\n");
- xs.text(" ");
xs.startTag(null, OpmlSymbols.BODY);
- xs.text("\n");
for (Feed feed : feeds) {
- xs.text(" ");
xs.startTag(null, OpmlSymbols.OUTLINE);
xs.attribute(null, OpmlSymbols.TEXT, feed.getTitle());
xs.attribute(null, OpmlSymbols.TITLE, feed.getTitle());
@@ -73,14 +64,15 @@ public class OpmlWriter {
xs.attribute(null, OpmlSymbols.HTMLURL, feed.getLink());
}
xs.endTag(null, OpmlSymbols.OUTLINE);
- xs.text("\n");
}
- xs.text(" ");
xs.endTag(null, OpmlSymbols.BODY);
- xs.text("\n");
xs.endTag(null, OpmlSymbols.OPML);
- xs.text("\n");
xs.endDocument();
Log.d(TAG, "Finished writing document");
}
+
+ public String fileExtension() {
+ return "opml";
+ }
+
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/opml/OpmlSymbols.java b/core/src/main/java/de/danoeh/antennapod/core/opml/OpmlSymbols.java
deleted file mode 100644
index c973713cb..000000000
--- a/core/src/main/java/de/danoeh/antennapod/core/opml/OpmlSymbols.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package de.danoeh.antennapod.core.opml;
-
-/** Contains symbols for reading and writing OPML documents. */
-public final class OpmlSymbols {
-
- public static final String OPML = "opml";
- public static final String BODY = "body";
- public static final String OUTLINE = "outline";
- public static final String TEXT = "text";
- public static final String XMLURL = "xmlUrl";
- public static final String HTMLURL = "htmlUrl";
- public static final String TYPE = "type";
- public static final String VERSION = "version";
- public static final String HEAD = "head";
- public static final String TITLE = "title";
- public static final String DATE_CREATED = "dateCreated";
-
- private OpmlSymbols() {
-
- }
-
-}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/preferences/SleepTimerPreferences.java b/core/src/main/java/de/danoeh/antennapod/core/preferences/SleepTimerPreferences.java
new file mode 100644
index 000000000..b7ed890f5
--- /dev/null
+++ b/core/src/main/java/de/danoeh/antennapod/core/preferences/SleepTimerPreferences.java
@@ -0,0 +1,80 @@
+package de.danoeh.antennapod.core.preferences;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.support.annotation.NonNull;
+import android.util.Log;
+
+import java.util.concurrent.TimeUnit;
+
+public class SleepTimerPreferences {
+
+ private static final String TAG = "SleepTimerPreferences";
+
+ private static final String PREF_NAME = "SleepTimerDialog";
+ private static final String PREF_VALUE = "LastValue";
+ private static final String PREF_TIME_UNIT = "LastTimeUnit";
+ private static final String PREF_VIBRATE = "Vibrate";
+ private static final String PREF_SHAKE_TO_RESET = "ShakeToReset";
+ private static final String PREF_AUTO_ENABLE = "AutoEnable";
+
+ private static final TimeUnit[] UNITS = { TimeUnit.SECONDS, TimeUnit.MINUTES, TimeUnit.HOURS };
+
+ private static final String DEFAULT_VALUE = "15";
+ private static final int DEFAULT_TIME_UNIT = 1;
+
+ private static Context context;
+ private static SharedPreferences prefs;
+
+ /**
+ * Sets up the UserPreferences class.
+ *
+ * @throws IllegalArgumentException if context is null
+ */
+ public static void init(@NonNull Context context) {
+ Log.d(TAG, "Creating new instance of SleepTimerPreferences");
+ SleepTimerPreferences.prefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
+ }
+
+ public static void setLastTimer(String value, int timeUnit) {
+ prefs.edit().putString(PREF_VALUE, value).putInt(PREF_TIME_UNIT, timeUnit).apply();
+ }
+
+ public static String lastTimerValue() {
+ return prefs.getString(PREF_VALUE, DEFAULT_VALUE);
+ }
+
+ public static int lastTimerTimeUnit() {
+ return prefs.getInt(PREF_TIME_UNIT, DEFAULT_TIME_UNIT);
+ }
+
+ public static long timerMillis() {
+ long value = Long.parseLong(lastTimerValue());
+ return UNITS[lastTimerTimeUnit()].toMillis(value);
+ }
+
+ public static void setVibrate(boolean vibrate) {
+ prefs.edit().putBoolean(PREF_VIBRATE, vibrate).apply();
+ }
+
+ public static boolean vibrate() {
+ return prefs.getBoolean(PREF_VIBRATE, true);
+ }
+
+ public static void setShakeToReset(boolean shakeToReset) {
+ prefs.edit().putBoolean(PREF_SHAKE_TO_RESET, shakeToReset).apply();
+ }
+
+ public static boolean shakeToReset() {
+ return prefs.getBoolean(PREF_SHAKE_TO_RESET, true);
+ }
+
+ public static void setAutoEnable(boolean autoEnable) {
+ prefs.edit().putBoolean(PREF_AUTO_ENABLE, autoEnable).apply();
+ }
+
+ public static boolean autoEnable() {
+ return prefs.getBoolean(PREF_AUTO_ENABLE, false);
+ }
+
+}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java b/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java
index d5a1007af..aa3bbaeab 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java
@@ -56,7 +56,6 @@ public class UserPreferences {
public static final String PREF_LOCKSCREEN_BACKGROUND = "prefLockscreenBackground";
public static final String PREF_SHOW_DOWNLOAD_REPORT = "prefShowDownloadReport";
-
// Queue
public static final String PREF_QUEUE_ADD_TO_FRONT = "prefQueueAddToFront";
@@ -123,13 +122,14 @@ public class UserPreferences {
private static final int NOTIFICATION_BUTTON_FAST_FORWARD = 1;
private static final int NOTIFICATION_BUTTON_SKIP = 2;
private static int EPISODE_CACHE_SIZE_UNLIMITED = -1;
- public static int FEED_ORDER_COUNTER = 0;
- public static int FEED_ORDER_ALPHABETICAL = 1;
- public static int FEED_ORDER_LAST_UPDATE = 2;
- public static int FEED_COUNTER_SHOW_NEW_UNPLAYED_SUM = 0;
- public static int FEED_COUNTER_SHOW_NEW = 1;
- public static int FEED_COUNTER_SHOW_UNPLAYED = 2;
- public static int FEED_COUNTER_SHOW_NONE = 3;
+ public static final int FEED_ORDER_COUNTER = 0;
+ public static final int FEED_ORDER_ALPHABETICAL = 1;
+ public static final int FEED_ORDER_LAST_UPDATE = 2;
+ public static final int FEED_COUNTER_SHOW_NEW_UNPLAYED_SUM = 0;
+ public static final int FEED_COUNTER_SHOW_NEW = 1;
+ public static final int FEED_COUNTER_SHOW_UNPLAYED = 2;
+ public static final int FEED_COUNTER_SHOW_NONE = 3;
+ public static final int FEED_COUNTER_SHOW_DOWNLOADED = 4;
private static Context context;
private static SharedPreferences prefs;
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java
index 0871758d0..cad67539b 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java
@@ -383,6 +383,9 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
statusBeforeSeeking = playerStatus;
setPlayerStatus(PlayerStatus.SEEKING, media, getPosition());
mediaPlayer.seekTo(t);
+ if (statusBeforeSeeking == PlayerStatus.PREPARED) {
+ media.setPosition(t);
+ }
try {
seekLatch.await(3, TimeUnit.SECONDS);
} catch (InterruptedException e) {
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java
index e67dc9d0a..33aec0ee0 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java
@@ -47,12 +47,14 @@ import java.util.List;
import de.danoeh.antennapod.core.ClientConfig;
import de.danoeh.antennapod.core.R;
+import de.danoeh.antennapod.core.event.MessageEvent;
import de.danoeh.antennapod.core.feed.Chapter;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.feed.MediaType;
import de.danoeh.antennapod.core.glide.ApGlideSettings;
import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
+import de.danoeh.antennapod.core.preferences.SleepTimerPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.receiver.MediaButtonReceiver;
import de.danoeh.antennapod.core.storage.DBReader;
@@ -62,6 +64,7 @@ import de.danoeh.antennapod.core.util.IntList;
import de.danoeh.antennapod.core.util.QueueAccess;
import de.danoeh.antennapod.core.util.playback.ExternalMedia;
import de.danoeh.antennapod.core.util.playback.Playable;
+import de.greenrobot.event.EventBus;
/**
* Controls the MediaPlayer that plays a FeedMedia-file
@@ -605,6 +608,11 @@ public class PlaybackService extends MediaBrowserServiceCompat {
writePlayerStatusPlaybackPreferences();
setupNotification(newInfo);
started = true;
+ // set sleep timer if auto-enabled
+ if(SleepTimerPreferences.autoEnable() && !sleepTimerActive()) {
+ setSleepTimer(SleepTimerPreferences.timerMillis(), SleepTimerPreferences.shakeToReset(),
+ SleepTimerPreferences.vibrate());
+ }
break;
case ERROR:
@@ -846,11 +854,14 @@ public class PlaybackService extends MediaBrowserServiceCompat {
Log.d(TAG, "Setting sleep timer to " + Long.toString(waitingTime) + " milliseconds");
taskManager.setSleepTimer(waitingTime, shakeToReset, vibrate);
sendNotificationBroadcast(NOTIFICATION_TYPE_SLEEPTIMER_UPDATE, 0);
+ EventBus.getDefault().post(new MessageEvent(getString(R.string.sleep_timer_enabled_label),
+ () -> disableSleepTimer()));
}
public void disableSleepTimer() {
taskManager.disableSleepTimer();
sendNotificationBroadcast(NOTIFICATION_TYPE_SLEEPTIMER_UPDATE, 0);
+ EventBus.getDefault().post(new MessageEvent(getString(R.string.sleep_timer_disabled_label)));
}
private void writePlaybackPreferencesNoMediaPlaying() {
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 7631d26d5..b0d053f5a 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
@@ -42,12 +42,12 @@ import de.greenrobot.event.EventBus;
public class PodDBAdapter {
private static final String TAG = "PodDBAdapter";
- public static final String DATABASE_NAME = "Antennapod.db";
+ private static final String DATABASE_NAME = "Antennapod.db";
/**
* Maximum number of arguments for IN-operator.
*/
- public static final int IN_OPERATOR_MAXIMUM = 800;
+ private static final int IN_OPERATOR_MAXIMUM = 800;
/**
* Maximum number of entries per search request.
@@ -109,14 +109,14 @@ public class PodDBAdapter {
public static final String KEY_EXCLUDE_FILTER = "exclude_filter";
// Table names
- public static final String TABLE_NAME_FEEDS = "Feeds";
- public static final String TABLE_NAME_FEED_ITEMS = "FeedItems";
- public static final String TABLE_NAME_FEED_IMAGES = "FeedImages";
- public static final String TABLE_NAME_FEED_MEDIA = "FeedMedia";
- public static final String TABLE_NAME_DOWNLOAD_LOG = "DownloadLog";
- public static final String TABLE_NAME_QUEUE = "Queue";
- public static final String TABLE_NAME_SIMPLECHAPTERS = "SimpleChapters";
- public static final String TABLE_NAME_FAVORITES = "Favorites";
+ private static final String TABLE_NAME_FEEDS = "Feeds";
+ private static final String TABLE_NAME_FEED_ITEMS = "FeedItems";
+ private static final String TABLE_NAME_FEED_IMAGES = "FeedImages";
+ private static final String TABLE_NAME_FEED_MEDIA = "FeedMedia";
+ private static final String TABLE_NAME_DOWNLOAD_LOG = "DownloadLog";
+ private static final String TABLE_NAME_QUEUE = "Queue";
+ private static final String TABLE_NAME_SIMPLECHAPTERS = "SimpleChapters";
+ private static final String TABLE_NAME_FAVORITES = "Favorites";
// SQL Statements for creating new tables
private static final String TABLE_PRIMARY_KEY = KEY_ID
@@ -1436,15 +1436,24 @@ public class PodDBAdapter {
public final LongIntMap getFeedCounters(long... feedIds) {
int setting = UserPreferences.getFeedCounterSetting();
String whereRead;
- if(setting == UserPreferences.FEED_COUNTER_SHOW_NEW_UNPLAYED_SUM) {
- whereRead = "(" + KEY_READ + "=" + FeedItem.NEW
- + " OR " + KEY_READ + "=" + FeedItem.UNPLAYED + ")";
- } else if(setting == UserPreferences.FEED_COUNTER_SHOW_NEW) {
- whereRead = KEY_READ + "=" + FeedItem.NEW;
- } else if(setting == UserPreferences.FEED_COUNTER_SHOW_UNPLAYED) {
- whereRead = KEY_READ + "=" + FeedItem.UNPLAYED;
- } else { // NONE
- return new LongIntMap(0);
+ switch(setting) {
+ case UserPreferences.FEED_COUNTER_SHOW_NEW_UNPLAYED_SUM:
+ whereRead = "(" + KEY_READ + "=" + FeedItem.NEW +
+ " OR " + KEY_READ + "=" + FeedItem.UNPLAYED + ")";
+ break;
+ case UserPreferences.FEED_COUNTER_SHOW_NEW:
+ whereRead = KEY_READ + "=" + FeedItem.NEW;
+ break;
+ case UserPreferences.FEED_COUNTER_SHOW_UNPLAYED:
+ whereRead = KEY_READ + "=" + FeedItem.UNPLAYED;
+ break;
+ case UserPreferences.FEED_COUNTER_SHOW_DOWNLOADED:
+ whereRead = KEY_DOWNLOADED + "=1";
+ break;
+ case UserPreferences.FEED_COUNTER_SHOW_NONE:
+ // deliberate fall-through
+ default: // NONE
+ return new LongIntMap(0);
}
// work around TextUtils.join wanting only boxed items
@@ -1459,8 +1468,10 @@ public class PodDBAdapter {
builder.deleteCharAt(builder.length() - 1);
}
- final String query = "SELECT " + KEY_FEED + ", COUNT(" + KEY_ID + ") AS count "
+ final String query = "SELECT " + KEY_FEED + ", COUNT(" + TABLE_NAME_FEED_ITEMS + "." + KEY_ID + ") AS count "
+ " FROM " + TABLE_NAME_FEED_ITEMS
+ + " LEFT JOIN " + TABLE_NAME_FEED_MEDIA + " ON "
+ + TABLE_NAME_FEED_ITEMS + "." + KEY_ID + "=" + TABLE_NAME_FEED_MEDIA + "." + KEY_FEEDITEM
+ " WHERE " + KEY_FEED + " IN (" + builder.toString() + ") "
+ " AND " + whereRead + " GROUP BY " + KEY_FEED;
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java
index 13aadf027..6251cc4a0 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java
@@ -216,7 +216,7 @@ public abstract class PlaybackController {
Intent serviceIntent = new Intent(activity, PlaybackService.class);
serviceIntent.putExtra(PlaybackService.EXTRA_PLAYABLE, media);
serviceIntent.putExtra(PlaybackService.EXTRA_START_WHEN_PREPARED, false);
- serviceIntent.putExtra(PlaybackService.EXTRA_PREPARE_IMMEDIATELY, false);
+ serviceIntent.putExtra(PlaybackService.EXTRA_PREPARE_IMMEDIATELY, true);
boolean fileExists = media.localFileAvailable();
boolean lastIsStream = PlaybackPreferences.getCurrentEpisodeIsStream();
if (!fileExists && !lastIsStream && media instanceof FeedMedia) {
diff --git a/core/src/main/res/values/arrays.xml b/core/src/main/res/values/arrays.xml
index c8c5162ef..133a3ed6e 100644
--- a/core/src/main/res/values/arrays.xml
+++ b/core/src/main/res/values/arrays.xml
@@ -168,12 +168,14 @@
<item>@string/drawer_feed_counter_new_unplayed</item>
<item>@string/drawer_feed_counter_new</item>
<item>@string/drawer_feed_counter_unplayed</item>
+ <item>@string/drawer_feed_counter_downloaded</item>
<item>@string/drawer_feed_counter_none</item>
</string-array>
<string-array name="nav_drawer_feed_counter_values">
<item>0</item>
<item>1</item>
<item>2</item>
+ <item>4</item>
<item>3</item>
</string-array>
diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml
index c7042708d..48bd15b13 100644
--- a/core/src/main/res/values/strings.xml
+++ b/core/src/main/res/values/strings.xml
@@ -42,6 +42,7 @@
<string name="drawer_feed_counter_new_unplayed">Number of new and unplayed episodes</string>
<string name="drawer_feed_counter_new">Number of new episodes</string>
<string name="drawer_feed_counter_unplayed">Number of unplayed episodes</string>
+ <string name="drawer_feed_counter_downloaded">Number of downloaded episodes</string>
<string name="drawer_feed_counter_none">None</string>
<!-- Webview actions -->
@@ -102,7 +103,7 @@
<string name="etxtFeedurlHint">www.example.com/feed</string>
<string name="txtvfeedurl_label">Add Podcast by URL</string>
<string name="podcastdirectories_label">Find Podcast in Directory</string>
- <string name="podcastdirectories_descr">You can search for new podcasts by name, category or popularity in the gpodder.net directory, or search the iTunes store.</string>
+ <string name="podcastdirectories_descr">For new podcasts, you can search iTunes or fyyd, or browse gpodder.net by name, category or popularity.</string>
<string name="browse_gpoddernet_label">Browse gpodder.net</string>
<!-- Actions on feeds -->
@@ -451,6 +452,7 @@
<string name="choose_file_from_filesystem">From local filesystem</string>
<string name="choose_file_from_external_application">Use external application</string>
<string name="opml_export_label">OPML export</string>
+ <string name="html_export_label">HTML export</string>
<string name="exporting_label">Exporting&#8230;</string>
<string name="export_error_label">Export error</string>
<string name="opml_export_success_title">OPML Export successful.</string>
@@ -482,6 +484,9 @@
<item quantity="one">1 hour</item>
<item quantity="other">%d hours</item>
</plurals>
+ <string name="auto_enable_label">Auto-enable</string>
+ <string name="sleep_timer_enabled_label">Sleep timer enabled</string>
+ <string name="sleep_timer_disabled_label">Sleep timer disabled</string>
<!-- gpodder.net -->
<string name="gpodnet_taglist_header">CATEGORIES</string>
@@ -575,6 +580,8 @@
<string name="search_itunes_label">Search iTunes</string>
<string name="filter">Filter</string>
+
+ <string name="search_fyyd_label">Search fyyd</string>
<!-- Episodes apply actions -->
<string name="all_label">All</string>
diff --git a/core/src/main/res/values/styles.xml b/core/src/main/res/values/styles.xml
index 6a4dc4781..9b20fdd02 100644
--- a/core/src/main/res/values/styles.xml
+++ b/core/src/main/res/values/styles.xml
@@ -285,6 +285,16 @@
<item name="textAllCaps">false</item>
</style>
+ <style name="Divider">
+ <item name="android:layout_width">match_parent</item>
+ <item name="android:layout_height">1dp</item>
+ <item name="android:layout_marginTop">8dp</item>
+ <item name="android:layout_marginLeft">16dp</item>
+ <item name="android:layout_marginRight">16dp</item>
+ <item name="android:layout_marginBottom">8dp</item>
+ <item name="android:background">?android:attr/listDivider</item>
+ </style>
+
<style name="AntennaPod.Dialog.Light" parent="Theme.AppCompat.Light.Dialog">
<item name="colorAccent">@color/holo_blue_light</item>
</style>
diff --git a/core/src/play/java/de/danoeh/antennapod/core/ClientConfig.java b/core/src/play/java/de/danoeh/antennapod/core/ClientConfig.java
index 3dfd6ea65..f12f1d806 100644
--- a/core/src/play/java/de/danoeh/antennapod/core/ClientConfig.java
+++ b/core/src/play/java/de/danoeh/antennapod/core/ClientConfig.java
@@ -4,6 +4,7 @@ import android.content.Context;
import de.danoeh.antennapod.core.cast.CastManager;
import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
+import de.danoeh.antennapod.core.preferences.SleepTimerPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
import de.danoeh.antennapod.core.util.NetworkUtils;
@@ -45,6 +46,7 @@ public class ClientConfig {
PlaybackPreferences.init(context);
NetworkUtils.init(context);
CastManager.init(context);
+ SleepTimerPreferences.init(context);
initialized = true;
}