summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/build.gradle13
-rw-r--r--app/proguard.cfg19
-rw-r--r--app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java2
-rw-r--r--app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java2
-rw-r--r--app/src/main/AndroidManifest.xml21
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java133
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java20
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/MediaplayerInfoActivity.java28
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java41
-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.java9
-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/activity/SplashActivity.java23
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/AdapterUtils.java5
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java1
-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/EpisodesApplyActionFragment.java15
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/ProxyDialog.java17
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/RenameFeedDialog.java44
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java57
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java5
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java20
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java16
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java19
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/FyydSearchFragment.java192
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java12
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java15
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java6
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java6
-rw-r--r--app/src/main/java/de/danoeh/antennapod/menuhandler/MenuItemUtils.java1
-rw-r--r--app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java178
-rw-r--r--app/src/main/play/ast_ES/listing/fulldescription43
-rw-r--r--app/src/main/play/lt/listing/fulldescription43
-rw-r--r--app/src/main/play/te/listing/fulldescription43
-rw-r--r--app/src/main/play/zh_TW/listing/fulldescription43
-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/nav_list.xml23
-rw-r--r--app/src/main/res/layout/subscription_item.xml19
-rw-r--r--app/src/main/res/layout/time_dialog.xml40
-rw-r--r--app/src/main/res/menu/episodes_apply_action_options.xml2
-rw-r--r--app/src/main/res/menu/feedlist.xml6
-rw-r--r--app/src/main/res/menu/nav_feed_context.xml5
-rw-r--r--app/src/main/res/xml/automotive_app_desc.xml4
-rw-r--r--app/src/main/res/xml/preferences.xml23
-rw-r--r--app/src/main/templates/about.html2
53 files changed, 1108 insertions, 505 deletions
diff --git a/app/build.gradle b/app/build.gradle
index a3b09ff6e..c7b95421b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -107,6 +107,10 @@ android {
play {
}
}
+
+ dexOptions {
+ jumboMode true
+ }
}
configurations {
@@ -139,8 +143,8 @@ dependencies {
compile "commons-io:commons-io:$commonsioVersion"
compile "org.jsoup:jsoup:$jsoupVersion"
compile "com.github.bumptech.glide:glide:$glideVersion"
- compile "com.squareup.okhttp:okhttp:$okhttpVersion"
- compile "com.squareup.okhttp:okhttp-urlconnection:$okhttpVersion"
+ compile "com.squareup.okhttp3:okhttp:$okhttpVersion"
+ compile "com.squareup.okhttp3:okhttp-urlconnection:$okhttpVersion"
compile "com.squareup.okio:okio:$okioVersion"
compile "de.greenrobot:eventbus:$eventbusVersion"
compile "io.reactivex:rxandroid:$rxAndroidVersion"
@@ -160,6 +164,8 @@ dependencies {
compile "com.github.shts:TriangleLabelView:$triangleLabelViewVersion"
compile "com.github.AntennaPod:AntennaPod-AudioPlayer:$audioPlayerVersion"
+
+ compile 'com.github.mfietz:fyydlin:v0.1'
}
play {
@@ -178,7 +184,8 @@ task filterAbout {
from "src/main/templates/about.html"
into "src/main/assets"
filter(ReplaceTokens, tokens: [versionname: android.defaultConfig.versionName,
- commit : "git rev-parse --short HEAD".execute().text])
+ commit : "git rev-parse --short HEAD".execute().text,
+ year : new Date().format('yyyy')])
}
}
diff --git a/app/proguard.cfg b/app/proguard.cfg
index a25664490..815a89452 100644
--- a/app/proguard.cfg
+++ b/app/proguard.cfg
@@ -53,7 +53,7 @@
public *;
}
--dontwarn com.squareup.okhttp.**
+-dontwarn okhttp3.**
-dontwarn okio.**
# for RxJava:
@@ -107,4 +107,19 @@
-dontwarn com.viewpagerindicator.LinePageIndicator
# for some reason ProGuard removes this file. Why? Unsure.
--keep class de.danoeh.antennapod.core.cast.SwitchableMediaRouteActionProvider { *; } \ No newline at end of file
+-keep class de.danoeh.antennapod.core.cast.SwitchableMediaRouteActionProvider { *; }
+
+# Retrofit 2.0
+-dontwarn retrofit2.**
+-keep class retrofit2.** { *; }
+-keepattributes Signature
+-keepattributes Exceptions
+
+-keepclasseswithmembers class * {
+ @retrofit2.http.* <methods>;
+}
+
+# Moshi
+-keep class com.squareup.moshi.** { *; }
+-keep interface com.squareup.moshi.** { *; }
+-keep public class retrofit2.adapter.rxjava.RxJavaCallAdapterFactory { *; }
diff --git a/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java b/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java
index 30ab365bf..9ac92c2f9 100644
--- a/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java
@@ -789,7 +789,7 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
}
@Override
- public void onPostPlayback(@NonNull Playable media, boolean ended, boolean playingNext) {
+ public void onPostPlayback(@NonNull Playable media, boolean ended, boolean skipped, boolean playingNext) {
}
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java b/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java
index 78b807710..d02efa521 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java
@@ -44,7 +44,7 @@ public class DBTestUtils {
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
for (int i = 0; i < numFeeds; i++) {
- Feed f = new Feed(0, null, "feed " + i, "link" + i, "descr", null, null,
+ Feed f = new Feed(0, null, "feed " + i, null, "link" + i, "descr", null, null,
null, null, "id" + i, null, null, "url" + i, false, new FlattrStatus(), false, null, null, false);
f.setItems(new ArrayList<>());
for (int j = 0; j < numItems; j++) {
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 14a38e017..2049b6bae 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="de.danoeh.antennapod"
- android:versionCode="1060102"
- android:versionName="1.6.1.2">
+ android:versionCode="1060203"
+ android:versionName="1.6.2.3">
<!--
Version code schema:
"1.2.3-SNAPSHOT" -> 1020300
@@ -37,23 +37,28 @@
android:backupAgent=".core.backup.OpmlBackupAgent"
android:restoreAnyVersion="true"
android:logo="@drawable/ic_launcher">
- <meta-data android:name="com.google.android.gms.car.notification.SmallIcon"
- android:resource="@drawable/ic_notification" />
<meta-data
android:name="com.google.android.backup.api_key"
android:value="AEdPqrEAAAAI3a05VToCTlqBymJrbFGaKQMvF-bBAuLsOdavBA"/>
<activity
- android:name=".activity.MainActivity"
+ android:name=".activity.SplashActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:launchMode="singleTask"
- android:label="@string/app_name">
+ android:label="@string/app_name"
+ android:theme="@style/Theme.AntennaPod.Dark.Splash">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
+ android:name=".activity.MainActivity"
+ android:configChanges="keyboardHidden|orientation|screenSize"
+ android:launchMode="singleTask"
+ android:label="@string/app_name">
+ </activity>
+ <activity
android:name=".activity.AudioplayerActivity"
android:launchMode="singleTop">
<meta-data
@@ -344,10 +349,6 @@
<meta-data
android:name="de.danoeh.antennapod.core.glide.ApGlideModule"
android:value="GlideModule" />
-
- <meta-data
- android:name="com.google.android.gms.car.application"
- android:resource="@xml/automotive_app_desc"/>
</application>
</manifest>
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java
index cfd633fae..19aabfc88 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java
@@ -8,6 +8,7 @@ import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
+import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Menu;
@@ -27,6 +28,10 @@ import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.joanzapata.iconify.Iconify;
+import org.apache.commons.lang3.StringUtils;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
@@ -40,6 +45,7 @@ import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.storage.DownloadRequestException;
import de.danoeh.antennapod.core.util.IntentUtils;
import de.danoeh.antennapod.core.util.LangUtils;
+import de.danoeh.antennapod.core.util.syndication.HtmlToPlainText;
import de.danoeh.antennapod.menuhandler.FeedMenuHandler;
import rx.Observable;
import rx.Subscription;
@@ -50,17 +56,18 @@ import rx.schedulers.Schedulers;
* Displays information about a feed.
*/
public class FeedInfoActivity extends AppCompatActivity {
- private static final String TAG = "FeedInfoActivity";
- private boolean autoDeleteChanged = false;
public static final String EXTRA_FEED_ID = "de.danoeh.antennapod.extra.feedId";
-
+ private static final String TAG = "FeedInfoActivity";
+ private boolean autoDeleteChanged = false;
private Feed feed;
private ImageView imgvCover;
private TextView txtvTitle;
private TextView txtvDescription;
+ private TextView lblLanguage;
private TextView txtvLanguage;
+ private TextView lblAuthor;
private TextView txtvAuthor;
private TextView txtvUrl;
private EditText etxtUsername;
@@ -75,6 +82,7 @@ public class FeedInfoActivity extends AppCompatActivity {
private Subscription subscription;
+
private final View.OnClickListener copyUrlToClipboard = new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -96,6 +104,40 @@ public class FeedInfoActivity extends AppCompatActivity {
}
};
+ private boolean authInfoChanged = false;
+
+ private TextWatcher authTextWatcher = new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ authInfoChanged = true;
+ }
+ };
+
+ private boolean filterTextChanged = false;
+
+ private TextWatcher filterTextWatcher = new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ filterTextChanged = true;
+ }
+ };
+
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(UserPreferences.getTheme());
@@ -107,7 +149,9 @@ public class FeedInfoActivity extends AppCompatActivity {
imgvCover = (ImageView) findViewById(R.id.imgvCover);
txtvTitle = (TextView) findViewById(R.id.txtvTitle);
txtvDescription = (TextView) findViewById(R.id.txtvDescription);
+ lblLanguage = (TextView) findViewById(R.id.lblLanguage);
txtvLanguage = (TextView) findViewById(R.id.txtvLanguage);
+ lblAuthor = (TextView) findViewById(R.id.lblAuthor);
txtvAuthor = (TextView) findViewById(R.id.txtvAuthor);
txtvUrl = (TextView) findViewById(R.id.txtvUrl);
cbxAutoDownload = (CheckBox) findViewById(R.id.cbxAutoDownload);
@@ -152,14 +196,30 @@ public class FeedInfoActivity extends AppCompatActivity {
.into(imgvCover);
txtvTitle.setText(feed.getTitle());
+
String description = feed.getDescription();
- txtvDescription.setText((description != null) ? description.trim() : "");
- if (feed.getAuthor() != null) {
+ if(description != null) {
+ if(Feed.TYPE_ATOM1.equals(feed.getType())) {
+ HtmlToPlainText formatter = new HtmlToPlainText();
+ Document feedDescription = Jsoup.parse(feed.getDescription());
+ description = StringUtils.trim(formatter.getPlainText(feedDescription));
+ }
+ } else {
+ description = "";
+ }
+ txtvDescription.setText(description);
+
+ if (!TextUtils.isEmpty(feed.getAuthor())) {
txtvAuthor.setText(feed.getAuthor());
+ } else {
+ lblAuthor.setVisibility(View.GONE);
+ txtvAuthor.setVisibility(View.GONE);
}
- if (feed.getLanguage() != null) {
- txtvLanguage.setText(LangUtils
- .getLanguageString(feed.getLanguage()));
+ if (!TextUtils.isEmpty(feed.getLanguage())) {
+ txtvLanguage.setText(LangUtils.getLanguageString(feed.getLanguage()));
+ } else {
+ lblLanguage.setVisibility(View.GONE);
+ txtvLanguage.setVisibility(View.GONE);
}
txtvUrl.setText(feed.getDownload_url() + " {fa-paperclip}");
Iconify.addIcons(txtvUrl);
@@ -241,53 +301,6 @@ public class FeedInfoActivity extends AppCompatActivity {
}
@Override
- public void onDestroy() {
- super.onDestroy();
- if(subscription != null) {
- subscription.unsubscribe();
- }
- }
-
-
- private boolean authInfoChanged = false;
-
- private TextWatcher authTextWatcher = new TextWatcher() {
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-
- }
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
-
- }
-
- @Override
- public void afterTextChanged(Editable s) {
- authInfoChanged = true;
- }
- };
-
- private boolean filterTextChanged = false;
-
- private TextWatcher filterTextWatcher = new TextWatcher() {
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-
- }
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
-
- }
-
- @Override
- public void afterTextChanged(Editable s) {
- filterTextChanged = true;
- }
- };
-
- @Override
protected void onPause() {
super.onPause();
if (feed != null) {
@@ -319,6 +332,14 @@ public class FeedInfoActivity extends AppCompatActivity {
}
@Override
+ public void onDestroy() {
+ super.onDestroy();
+ if(subscription != null) {
+ subscription.unsubscribe();
+ }
+ }
+
+ @Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
MenuInflater inflater = getMenuInflater();
@@ -369,7 +390,7 @@ public class FeedInfoActivity extends AppCompatActivity {
private final Feed feed;
private final boolean autoDownload;
- public ApplyToEpisodesDialog(Context context, Feed feed, boolean autoDownload) {
+ ApplyToEpisodesDialog(Context context, Feed feed, boolean autoDownload) {
super(context, R.string.auto_download_apply_to_items_title,
R.string.auto_download_apply_to_items_message);
this.feed = feed;
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 97732786e..41ed963c2 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;
@@ -46,11 +48,13 @@ import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.storage.DBReader;
+import de.danoeh.antennapod.core.storage.DBTasks;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.util.FeedItemUtil;
import de.danoeh.antennapod.core.util.Flavors;
import de.danoeh.antennapod.core.util.StorageUtils;
import de.danoeh.antennapod.dialog.RatingDialog;
+import de.danoeh.antennapod.dialog.RenameFeedDialog;
import de.danoeh.antennapod.fragment.AddFeedFragment;
import de.danoeh.antennapod.fragment.DownloadsFragment;
import de.danoeh.antennapod.fragment.EpisodesFragment;
@@ -463,6 +467,7 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi
protected void onResume() {
super.onResume();
StorageUtils.checkStorageAvailability(this);
+ DBTasks.checkShouldRefreshFeeds(getApplicationContext());
Intent intent = getIntent();
if (intent.hasExtra(EXTRA_FEED_ID) ||
@@ -573,6 +578,9 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi
case R.id.mark_all_read_item:
DBWriter.markFeedRead(feed.getId());
return true;
+ case R.id.rename_item:
+ new RenameFeedDialog(this, feed).show();
+ return true;
case R.id.remove_item:
final FeedRemover remover = new FeedRemover(this, feed) {
@Override
@@ -731,6 +739,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/MediaplayerInfoActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerInfoActivity.java
index 2880b26e8..9d2f35e3d 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;
@@ -43,9 +45,11 @@ import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.service.playback.PlayerStatus;
import de.danoeh.antennapod.core.storage.DBReader;
+import de.danoeh.antennapod.core.storage.DBTasks;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.util.playback.Playable;
import de.danoeh.antennapod.core.util.playback.PlaybackController;
+import de.danoeh.antennapod.dialog.RenameFeedDialog;
import de.danoeh.antennapod.fragment.AddFeedFragment;
import de.danoeh.antennapod.fragment.ChaptersFragment;
import de.danoeh.antennapod.fragment.CoverFragment;
@@ -57,6 +61,7 @@ import de.danoeh.antennapod.fragment.QueueFragment;
import de.danoeh.antennapod.fragment.SubscriptionFragment;
import de.danoeh.antennapod.menuhandler.NavDrawerActivity;
import de.danoeh.antennapod.preferences.PreferenceController;
+import de.greenrobot.event.EventBus;
import rx.Observable;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
@@ -102,6 +107,12 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem
private Subscription subscription;
@Override
+ protected void onPause() {
+ super.onPause();
+ EventBus.getDefault().unregister(this);
+ }
+
+ @Override
protected void onStop() {
super.onStop();
Log.d(TAG, "onStop()");
@@ -168,8 +179,10 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem
pagerAdapter.onMediaChanged(media);
pagerAdapter.setController(controller);
}
+ DBTasks.checkShouldRefreshFeeds(getApplicationContext());
EventDistributor.getInstance().register(contentUpdate);
+ EventBus.getDefault().register(this);
loadData();
}
@@ -370,6 +383,9 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity implem
case R.id.mark_all_read_item:
DBWriter.markFeedRead(feed.getId());
return true;
+ case R.id.rename_item:
+ new RenameFeedDialog(this, feed).show();
+ return true;
case R.id.remove_item:
final FeedRemover remover = new FeedRemover(this, feed) {
@Override
@@ -462,7 +478,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/OnlineFeedViewActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java
index a40877832..a4e661f62 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java
@@ -29,7 +29,6 @@ import com.bumptech.glide.Glide;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
-import org.jsoup.examples.HtmlToPlainText;
import org.jsoup.nodes.Document;
import java.io.File;
@@ -63,6 +62,7 @@ import de.danoeh.antennapod.core.util.FileNameGenerator;
import de.danoeh.antennapod.core.util.StorageUtils;
import de.danoeh.antennapod.core.util.URLChecker;
import de.danoeh.antennapod.core.util.syndication.FeedDiscoverer;
+import de.danoeh.antennapod.core.util.syndication.HtmlToPlainText;
import de.danoeh.antennapod.dialog.AuthenticationDialog;
import de.greenrobot.event.EventBus;
import rx.Observable;
@@ -81,17 +81,12 @@ import rx.schedulers.Schedulers;
*/
public class OnlineFeedViewActivity extends AppCompatActivity {
- private static final String TAG = "OnlineFeedViewActivity";
-
public static final String ARG_FEEDURL = "arg.feedurl";
-
// Optional argument: specify a title for the actionbar.
public static final String ARG_TITLE = "title";
-
- private static final int EVENTS = EventDistributor.FEED_LIST_UPDATE;
-
public static final int RESULT_ERROR = 2;
-
+ private static final String TAG = "OnlineFeedViewActivity";
+ private static final int EVENTS = EventDistributor.FEED_LIST_UPDATE;
private volatile List<Feed> feeds;
private Feed feed;
private String selectedDownloadUrl;
@@ -106,17 +101,11 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
private Subscription download;
private Subscription parser;
private Subscription updater;
-
- public void onEventMainThread(DownloadEvent event) {
- Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]");
- setSubscribeButtonState(feed);
- }
-
private EventDistributor.EventListener listener = new EventDistributor.EventListener() {
@Override
public void update(EventDistributor eventDistributor, Integer arg) {
if ((arg & EventDistributor.FEED_LIST_UPDATE) != 0) {
- updater = Observable.fromCallable(() -> DBReader.getFeedList())
+ updater = Observable.fromCallable(DBReader::getFeedList)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
@@ -133,6 +122,11 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
}
};
+ public void onEventMainThread(DownloadEvent event) {
+ Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]");
+ setSubscribeButtonState(feed);
+ }
+
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(UserPreferences.getTheme());
@@ -284,7 +278,7 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
})
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
- .subscribe(status -> checkDownloadResult(status),
+ .subscribe(this::checkDownloadResult,
error -> Log.e(TAG, Log.getStackTraceString(error)));
}
@@ -360,14 +354,19 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
* This method is executed on a background thread
*/
private void beforeShowFeedInformation(Feed feed) {
- // remove HTML tags from descriptions
+ final HtmlToPlainText formatter = new HtmlToPlainText();
+ if(Feed.TYPE_ATOM1.equals(feed.getType()) && feed.getDescription() != null) {
+ // remove HTML tags from descriptions
+ Log.d(TAG, "Removing HTML from feed description");
+ Document feedDescription = Jsoup.parse(feed.getDescription());
+ feed.setDescription(StringUtils.trim(formatter.getPlainText(feedDescription)));
+ }
Log.d(TAG, "Removing HTML from shownotes");
if (feed.getItems() != null) {
- HtmlToPlainText formatter = new HtmlToPlainText();
for (FeedItem item : feed.getItems()) {
if (item.getDescription() != null) {
- Document description = Jsoup.parse(item.getDescription());
- item.setDescription(StringUtils.trim(formatter.getPlainText(description)));
+ Document itemDescription = Jsoup.parse(item.getDescription());
+ item.setDescription(StringUtils.trim(formatter.getPlainText(itemDescription)));
}
}
}
@@ -589,7 +588,7 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
private String feedUrl;
- public FeedViewAuthenticationDialog(Context context, int titleRes, String feedUrl) {
+ FeedViewAuthenticationDialog(Context context, int titleRes, String feedUrl) {
super(context, titleRes, true, false, null, null);
this.feedUrl = feedUrl;
}
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..07b0b3cdb 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportBaseActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportBaseActivity.java
@@ -3,6 +3,7 @@ package de.danoeh.antennapod.activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
+import android.os.Build;
import android.os.Environment;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
@@ -20,7 +21,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 +30,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;
/**
@@ -77,7 +77,8 @@ public class OpmlImportBaseActivity extends AppCompatActivity {
return;
}
this.uri = uri;
- if(uri.toString().contains(Environment.getExternalStorageDirectory().toString())) {
+ if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
+ uri.toString().contains(Environment.getExternalStorageDirectory().toString())) {
int permission = ActivityCompat.checkSelfPermission(this, android.Manifest.permission.READ_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
requestPermission();
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/activity/SplashActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/SplashActivity.java
new file mode 100644
index 000000000..b92ac8577
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/activity/SplashActivity.java
@@ -0,0 +1,23 @@
+package de.danoeh.antennapod.activity;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v7.app.AppCompatActivity;
+
+/**
+ * Creator: vbarad
+ * Date: 2016-12-03
+ * Project: AntennaPod
+ */
+
+public class SplashActivity extends AppCompatActivity {
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ Intent intent = new Intent(this, MainActivity.class);
+ startActivity(intent);
+ finish();
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java b/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java
index 1a8f0a67a..f0210f983 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java
@@ -47,6 +47,7 @@ public class ActionButtonUtils {
* Sets the displayed bitmap and content description of the given
* action button so that it matches the state of the FeedItem.
*/
+ @SuppressWarnings("ResourceType")
public void configureActionButton(ImageButton butSecondary, FeedItem item, boolean isInQueue) {
Validate.isTrue(butSecondary != null && item != null, "butSecondary or item was null");
@@ -57,8 +58,7 @@ public class ActionButtonUtils {
if (isDownloadingMedia) {
// item is being downloaded
butSecondary.setVisibility(View.VISIBLE);
- butSecondary.setImageDrawable(drawables
- .getDrawable(1));
+ butSecondary.setImageDrawable(drawables.getDrawable(1));
butSecondary.setContentDescription(context.getString(labels[1]));
} else {
// item is not downloaded and not being downloaded
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/AdapterUtils.java b/app/src/main/java/de/danoeh/antennapod/adapter/AdapterUtils.java
index 8aaf0055a..5c58d00f2 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/AdapterUtils.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/AdapterUtils.java
@@ -15,7 +15,7 @@ import de.danoeh.antennapod.core.util.NetworkUtils;
/**
* Utility methods for adapters
*/
-public class AdapterUtils {
+class AdapterUtils {
private static final String TAG = AdapterUtils.class.getSimpleName();
@@ -26,7 +26,7 @@ public class AdapterUtils {
/**
* Updates the contents of the TextView that shows the current playback position and the ProgressBar.
*/
- public static void updateEpisodePlaybackProgress(FeedItem item, TextView txtvPos, ProgressBar episodeProgress) {
+ static void updateEpisodePlaybackProgress(FeedItem item, TextView txtvPos, ProgressBar episodeProgress) {
FeedMedia media = item.getMedia();
episodeProgress.setVisibility(View.GONE);
if (media == null) {
@@ -47,7 +47,6 @@ public class AdapterUtils {
- media.getPosition()));
}
} else if (!media.isDownloaded()) {
- Log.d(TAG, "size: " + media.getSize());
if (media.getSize() > 0) {
txtvPos.setText(Converter.byteToString(media.getSize()));
} else if(NetworkUtils.isDownloadAllowed() && !media.checkedOnSizeButUnknown()) {
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java
index 07847d0d1..35c42725c 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java
@@ -87,6 +87,7 @@ public class FeedItemlistAdapter extends BaseAdapter {
}
@Override
+ @SuppressWarnings("ResourceType")
public View getView(final int position, View convertView, ViewGroup parent) {
Holder holder;
final FeedItem item = getItem(position);
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/EpisodesApplyActionFragment.java b/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java
index 577a3ecbe..ac073141d 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java
@@ -225,6 +225,10 @@ public class EpisodesApplyActionFragment extends Fragment {
checkQueued(false);
resId = R.string.selected_not_queued_label;
break;
+ case R.id.check_has_media:
+ checkWithMedia();
+ resId = R.string.selected_has_media_label;
+ break;
case R.id.sort_title_a_z:
sortByTitle(false);
return true;
@@ -357,6 +361,17 @@ public class EpisodesApplyActionFragment extends Fragment {
refreshCheckboxes();
}
+ private void checkWithMedia() {
+ for (FeedItem episode : episodes) {
+ if(episode.hasMedia()) {
+ checkedIds.add(episode.getId());
+ } else {
+ checkedIds.remove(episode.getId());
+ }
+ }
+ refreshCheckboxes();
+ }
+
private void refreshTitles() {
titles.clear();
for(FeedItem episode : episodes) {
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/ProxyDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/ProxyDialog.java
index 98a4b5356..0bd75b5b0 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/ProxyDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/ProxyDialog.java
@@ -18,10 +18,6 @@ import android.widget.TextView;
import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.afollestad.materialdialogs.internal.MDButton;
-import com.squareup.okhttp.Credentials;
-import com.squareup.okhttp.OkHttpClient;
-import com.squareup.okhttp.Request;
-import com.squareup.okhttp.Response;
import java.io.IOException;
import java.net.InetSocketAddress;
@@ -33,6 +29,10 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.download.AntennapodHttpClient;
import de.danoeh.antennapod.core.service.download.ProxyConfig;
+import okhttp3.Credentials;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
import rx.Observable;
import rx.Subscriber;
import rx.Subscription;
@@ -258,10 +258,11 @@ public class ProxyDialog {
SocketAddress address = InetSocketAddress.createUnresolved(host, portValue);
Proxy.Type proxyType = Proxy.Type.valueOf(type.toUpperCase());
Proxy proxy = new Proxy(proxyType, address);
- OkHttpClient client = AntennapodHttpClient.newHttpClient();
- client.setConnectTimeout(10, TimeUnit.SECONDS);
- client.setProxy(proxy);
- client.interceptors().clear();
+ OkHttpClient.Builder builder = AntennapodHttpClient.newBuilder()
+ .connectTimeout(10, TimeUnit.SECONDS)
+ .proxy(proxy);
+ builder.interceptors().clear();
+ OkHttpClient client = builder.build();
if(!TextUtils.isEmpty(username)) {
String credentials = Credentials.basic(username, password);
client.interceptors().add(chain -> {
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/RenameFeedDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/RenameFeedDialog.java
new file mode 100644
index 000000000..31a544582
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/RenameFeedDialog.java
@@ -0,0 +1,44 @@
+package de.danoeh.antennapod.dialog;
+
+import android.app.Activity;
+import android.text.InputType;
+
+import com.afollestad.materialdialogs.MaterialDialog;
+
+import java.lang.ref.WeakReference;
+
+import de.danoeh.antennapod.core.feed.Feed;
+import de.danoeh.antennapod.core.storage.DBWriter;
+
+public class RenameFeedDialog {
+
+ private final WeakReference<Activity> activityRef;
+ private final Feed feed;
+
+ public RenameFeedDialog(Activity activity, Feed feed) {
+ this.activityRef = new WeakReference<>(activity);
+ this.feed = feed;
+ }
+
+ public void show() {
+ Activity activity = activityRef.get();
+ if(activity == null) {
+ return;
+ }
+ new MaterialDialog.Builder(activity)
+ .title(de.danoeh.antennapod.core.R.string.rename_feed_label)
+ .inputType(InputType.TYPE_CLASS_TEXT)
+ .input(feed.getTitle(), feed.getTitle(), true, (dialog, input) -> {
+ feed.setCustomTitle(input.toString());
+ DBWriter.setFeedCustomTitle(feed);
+ dialog.dismiss();
+ })
+ .neutralText(de.danoeh.antennapod.core.R.string.reset)
+ .onNeutral((dialog, which) -> dialog.getInputEditText().setText(feed.getFeedTitle()))
+ .negativeText(de.danoeh.antennapod.core.R.string.cancel_label)
+ .onNegative((dialog, which) -> dialog.dismiss())
+ .autoDismiss(false)
+ .show();
+ }
+
+}
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..7d6a66a54 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,7 @@
package de.danoeh.antennapod.dialog;
import android.content.Context;
-import android.content.SharedPreferences;
+import android.support.design.widget.Snackbar;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
@@ -9,6 +9,7 @@ import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
+import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;
@@ -16,36 +17,27 @@ 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.event.MessageEvent;
+import de.danoeh.antennapod.core.preferences.SleepTimerPreferences;
+import de.greenrobot.event.EventBus;
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) {
+ protected SleepTimerDialog(Context context) {
this.context = context;
- prefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
}
public MaterialDialog createNewDialog() {
@@ -58,7 +50,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 +67,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,12 +97,17 @@ 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());
+ chAutoEnable.setOnCheckedChangeListener((compoundButton, isChecked) -> {
+ SleepTimerPreferences.setAutoEnable(isChecked);
+ int messageString = isChecked ? R.string.sleep_timer_enabled_label : R.string.sleep_timer_disabled_label;
+ EventBus.getDefault().post(new MessageEvent(context.getString(messageString)));
+ });
return dialog;
}
@@ -125,19 +123,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/AllEpisodesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
index 29df6617d..ab8808093 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
@@ -227,22 +227,32 @@ public class AllEpisodesFragment extends Fragment {
}
return true;
case R.id.mark_all_read_item:
- ConfirmationDialog conDialog = new ConfirmationDialog(getActivity(),
+ ConfirmationDialog markAllReadConfirmationDialog = new ConfirmationDialog(getActivity(),
R.string.mark_all_read_label,
R.string.mark_all_read_confirmation_msg) {
@Override
- public void onConfirmButtonPressed(
- DialogInterface dialog) {
+ public void onConfirmButtonPressed(DialogInterface dialog) {
dialog.dismiss();
DBWriter.markAllItemsRead();
Toast.makeText(getActivity(), R.string.mark_all_read_msg, Toast.LENGTH_SHORT).show();
}
};
- conDialog.createNewDialog().show();
+ markAllReadConfirmationDialog.createNewDialog().show();
return true;
case R.id.mark_all_seen_item:
- DBWriter.markNewItemsSeen();
+ ConfirmationDialog markAllSeenConfirmationDialog = new ConfirmationDialog(getActivity(),
+ R.string.mark_all_seen_label,
+ R.string.mark_all_seen_confirmation_msg) {
+
+ @Override
+ public void onConfirmButtonPressed(DialogInterface dialog) {
+ dialog.dismiss();
+ DBWriter.markNewItemsSeen();
+ Toast.makeText(getActivity(), R.string.mark_all_seen_msg, Toast.LENGTH_SHORT).show();
+ }
+ };
+ markAllSeenConfirmationDialog.createNewDialog().show();
return true;
default:
return false;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java
index 77e66f3b0..4d34d076d 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java
@@ -69,16 +69,18 @@ public class ChaptersFragment extends ListFragment implements MediaplayerInfoCon
@Override
public void onMediaChanged(Playable media) {
- if(this.media == media || adapter == null) {
+ if(this.media == media) {
return;
}
this.media = media;
- adapter.setMedia(media);
- adapter.notifyDataSetChanged();
- if(media == null || media.getChapters() == null || media.getChapters().size() == 0) {
- setEmptyText(getString(R.string.no_items_label));
- } else {
- setEmptyText(null);
+ if (adapter != null) {
+ adapter.setMedia(media);
+ adapter.notifyDataSetChanged();
+ if(media == null || media.getChapters() == null || media.getChapters().size() == 0) {
+ setEmptyText(getString(R.string.no_items_label));
+ } else {
+ setEmptyText(null);
+ }
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java
index 856888ee0..1d3fcefba 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java
@@ -33,22 +33,15 @@ public class CoverFragment extends Fragment implements MediaplayerInfoContentFra
public static CoverFragment newInstance(Playable item) {
CoverFragment f = new CoverFragment();
- if (item != null) {
- Bundle args = new Bundle();
- args.putParcelable(ARG_PLAYABLE, item);
- f.setArguments(args);
- }
+ f.media = item;
return f;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- Bundle args = getArguments();
- if (args != null) {
- media = args.getParcelable(ARG_PLAYABLE);
- } else {
- Log.e(TAG, TAG + " was called with invalid arguments");
+ if (media == null) {
+ Log.e(TAG, TAG + " was called without media");
}
}
@@ -98,11 +91,13 @@ public class CoverFragment extends Fragment implements MediaplayerInfoContentFra
@Override
public void onMediaChanged(Playable media) {
- if(!isAdded() || this.media == media) {
+ if(this.media == media) {
return;
}
this.media = media;
- loadMediaInfo();
+ if (isAdded()) {
+ loadMediaInfo();
+ }
}
}
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..7c1ec5ec1
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/FyydSearchFragment.java
@@ -0,0 +1,192 @@
+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.core.service.download.AntennapodHttpClient;
+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(AntennapodHttpClient.getHttpClient());
+
+ /**
+ * 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/fragment/ItemDescriptionFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java
index 89a1a8d50..a0586fe16 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java
@@ -185,8 +185,10 @@ public class ItemDescriptionFragment extends Fragment implements MediaplayerInfo
super.onViewCreated(view, savedInstanceState);
Bundle args = getArguments();
if (args.containsKey(ARG_PLAYABLE)) {
- media = args.getParcelable(ARG_PLAYABLE);
- shownotesProvider = media;
+ if (media == null) {
+ media = args.getParcelable(ARG_PLAYABLE);
+ shownotesProvider = media;
+ }
load();
} else if (args.containsKey(ARG_FEEDITEM_ID)) {
long id = getArguments().getLong(ARG_FEEDITEM_ID);
@@ -377,12 +379,14 @@ public class ItemDescriptionFragment extends Fragment implements MediaplayerInfo
@Override
public void onMediaChanged(Playable media) {
- if(this.media == media || webvDescription == null) {
+ if(this.media == media) {
return;
}
this.media = media;
this.shownotesProvider = media;
- load();
+ if (webvDescription != null) {
+ load();
+ }
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java
index 13f5481e9..75f9c0d35 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java
@@ -67,6 +67,7 @@ import de.danoeh.antennapod.core.util.FeedItemUtil;
import de.danoeh.antennapod.core.util.LongList;
import de.danoeh.antennapod.core.util.gui.MoreContentListFooterUtil;
import de.danoeh.antennapod.dialog.EpisodesApplyActionFragment;
+import de.danoeh.antennapod.dialog.RenameFeedDialog;
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
import de.danoeh.antennapod.menuhandler.FeedMenuHandler;
import de.danoeh.antennapod.menuhandler.MenuItemUtils;
@@ -99,6 +100,7 @@ public class ItemlistFragment extends ListFragment {
private boolean itemsLoaded = false;
private boolean viewsCreated = false;
+ private boolean headerCreated = false;
private List<Downloader> downloaderList;
@@ -106,6 +108,7 @@ public class ItemlistFragment extends ListFragment {
private boolean isUpdatingFeed;
+ private TextView txtvTitle;
private IconTextView txtvFailure;
private TextView txtvInformation;
@@ -248,6 +251,9 @@ public class ItemlistFragment extends ListFragment {
.newInstance(feed.getItems());
((MainActivity)getActivity()).loadChildFragment(fragment);
return true;
+ case R.id.rename_item:
+ new RenameFeedDialog(getActivity(), feed).show();
+ return true;
case R.id.remove_item:
final FeedRemover remover = new FeedRemover(
getActivity(), feed) {
@@ -415,6 +421,7 @@ public class ItemlistFragment extends ListFragment {
public void update(EventDistributor eventDistributor, Integer arg) {
if ((EVENTS & arg) != 0) {
Log.d(TAG, "Received contentUpdate Intent. arg " + arg);
+ refreshHeaderView();
loadItems();
updateProgressBarVisibility();
}
@@ -460,8 +467,8 @@ public class ItemlistFragment extends ListFragment {
}
private void refreshHeaderView() {
- if (getListView() == null || feed == null) {
- Log.e(TAG, "Unable to setup listview: recyclerView = null or feed = null");
+ if (getListView() == null || feed == null || !headerCreated) {
+ Log.e(TAG, "Unable to refresh header view");
return;
}
if(feed.hasLastUpdateFailed()) {
@@ -469,6 +476,7 @@ public class ItemlistFragment extends ListFragment {
} else {
txtvFailure.setVisibility(View.GONE);
}
+ txtvTitle.setText(feed.getTitle());
if(feed.getItemFilter() != null) {
FeedItemFilter filter = feed.getItemFilter();
if(filter.getValues().length > 0) {
@@ -498,7 +506,7 @@ public class ItemlistFragment extends ListFragment {
View header = inflater.inflate(R.layout.feeditemlist_header, lv, false);
lv.addHeaderView(header);
- TextView txtvTitle = (TextView) header.findViewById(R.id.txtvTitle);
+ txtvTitle = (TextView) header.findViewById(R.id.txtvTitle);
TextView txtvAuthor = (TextView) header.findViewById(R.id.txtvAuthor);
ImageView imgvBackground = (ImageView) header.findViewById(R.id.imgvBackground);
ImageView imgvCover = (ImageView) header.findViewById(R.id.imgvCover);
@@ -539,6 +547,7 @@ public class ItemlistFragment extends ListFragment {
startActivity(startIntent);
}
});
+ headerCreated = true;
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java
index b736688b9..db88c070d 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java
@@ -18,9 +18,6 @@ import android.widget.ProgressBar;
import android.widget.TextView;
import com.afollestad.materialdialogs.MaterialDialog;
-import com.squareup.okhttp.OkHttpClient;
-import com.squareup.okhttp.Request;
-import com.squareup.okhttp.Response;
import org.json.JSONArray;
import org.json.JSONException;
@@ -39,6 +36,9 @@ import de.danoeh.antennapod.adapter.itunes.ItunesAdapter;
import de.danoeh.antennapod.core.ClientConfig;
import de.danoeh.antennapod.core.service.download.AntennapodHttpClient;
import de.danoeh.antennapod.menuhandler.MenuItemUtils;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
import rx.Observable;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java
index 3ddd5245a..01119bcff 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java
@@ -26,6 +26,7 @@ import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.util.FeedItemUtil;
+import de.danoeh.antennapod.dialog.RenameFeedDialog;
import rx.Observable;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
@@ -102,7 +103,7 @@ public class SubscriptionFragment extends Fragment {
if(subscription != null) {
subscription.unsubscribe();
}
- subscription = Observable.fromCallable(() -> DBReader.getNavDrawerData())
+ subscription = Observable.fromCallable(DBReader::getNavDrawerData)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> {
@@ -164,6 +165,9 @@ public class SubscriptionFragment extends Fragment {
.subscribe(result -> loadSubscriptions(),
error -> Log.e(TAG, Log.getStackTraceString(error)));
return true;
+ case R.id.rename_item:
+ new RenameFeedDialog(getActivity(), feed).show();
+ return true;
case R.id.remove_item:
final FeedRemover remover = new FeedRemover(getContext(), feed) {
@Override
diff --git a/app/src/main/java/de/danoeh/antennapod/menuhandler/MenuItemUtils.java b/app/src/main/java/de/danoeh/antennapod/menuhandler/MenuItemUtils.java
index 4c28b197d..ac703e13e 100644
--- a/app/src/main/java/de/danoeh/antennapod/menuhandler/MenuItemUtils.java
+++ b/app/src/main/java/de/danoeh/antennapod/menuhandler/MenuItemUtils.java
@@ -28,6 +28,7 @@ public class MenuItemUtils extends de.danoeh.antennapod.core.menuhandler.MenuIte
}
}
+ @SuppressWarnings("ResourceType")
public static void refreshLockItem(Context context, Menu menu) {
final MenuItem queueLock = menu.findItem(de.danoeh.antennapod.R.id.queue_lock);
int[] lockIcons = new int[] { de.danoeh.antennapod.R.attr.ic_lock_open, de.danoeh.antennapod.R.attr.ic_lock_closed };
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 77764247d..7777af450 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;
@@ -42,6 +43,8 @@ import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.concurrent.TimeUnit;
@@ -55,7 +58,10 @@ import de.danoeh.antennapod.activity.MediaplayerActivity;
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;
@@ -67,6 +73,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.
@@ -76,55 +86,36 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
private static final String TAG = "PreferenceController";
- public static final String PREF_FLATTR_SETTINGS = "prefFlattrSettings";
- public static final String PREF_FLATTR_AUTH = "pref_flattr_authenticate";
- public static final String PREF_FLATTR_REVOKE = "prefRevokeAccess";
- public static final String PREF_AUTO_FLATTR_PREFS = "prefAutoFlattrPrefs";
- public static final String PREF_OPML_EXPORT = "prefOpmlExport";
- public static final String STATISTICS = "statistics";
- public static final String PREF_ABOUT = "prefAbout";
- public static final String PREF_CHOOSE_DATA_DIR = "prefChooseDataDir";
- public static final String AUTO_DL_PREF_SCREEN = "prefAutoDownloadSettings";
- public static final String PREF_PLAYBACK_SPEED_LAUNCHER = "prefPlaybackSpeedLauncher";
+ private static final String PREF_FLATTR_SETTINGS = "prefFlattrSettings";
+ private static final String PREF_FLATTR_AUTH = "pref_flattr_authenticate";
+ 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";
+ private static final String AUTO_DL_PREF_SCREEN = "prefAutoDownloadSettings";
+ private static final String PREF_PLAYBACK_SPEED_LAUNCHER = "prefPlaybackSpeedLauncher";
public static final String PREF_PLAYBACK_REWIND_DELTA_LAUNCHER = "prefPlaybackRewindDeltaLauncher";
public static final String PREF_PLAYBACK_FAST_FORWARD_DELTA_LAUNCHER = "prefPlaybackFastForwardDeltaLauncher";
- public static final String PREF_GPODNET_LOGIN = "pref_gpodnet_authenticate";
- public static final String PREF_GPODNET_SETLOGIN_INFORMATION = "pref_gpodnet_setlogin_information";
- public static final String PREF_GPODNET_SYNC = "pref_gpodnet_sync";
- public static final String PREF_GPODNET_LOGOUT = "pref_gpodnet_logout";
- public static final String PREF_GPODNET_HOSTNAME = "pref_gpodnet_hostname";
- public static final String PREF_GPODNET_NOTIFICATIONS = "pref_gpodnet_notifications";
- public static final String PREF_EXPANDED_NOTIFICATION = "prefExpandNotify";
- public static final String PREF_PROXY = "prefProxy";
- public static final String PREF_KNOWN_ISSUES = "prefKnownIssues";
- public static final String PREF_FAQ = "prefFaq";
- public static final String PREF_SEND_CRASH_REPORT = "prefSendCrashReport";
-
- private final PreferenceUI ui;
-
- private CheckBoxPreference[] selectedNetworks;
-
+ private static final String PREF_GPODNET_LOGIN = "pref_gpodnet_authenticate";
+ private static final String PREF_GPODNET_SETLOGIN_INFORMATION = "pref_gpodnet_setlogin_information";
+ private static final String PREF_GPODNET_SYNC = "pref_gpodnet_sync";
+ private static final String PREF_GPODNET_FORCE_FULL_SYNC = "pref_gpodnet_force_full_sync";
+ private static final String PREF_GPODNET_LOGOUT = "pref_gpodnet_logout";
+ private static final String PREF_GPODNET_HOSTNAME = "pref_gpodnet_hostname";
+ private static final String PREF_GPODNET_NOTIFICATIONS = "pref_gpodnet_notifications";
+ private static final String PREF_EXPANDED_NOTIFICATION = "prefExpandNotify";
+ private static final String PREF_PROXY = "prefProxy";
+ 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 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)) {
@@ -132,6 +123,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.
@@ -146,6 +145,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();
@@ -181,11 +190,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 &&
@@ -361,6 +368,18 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
toast.show();
return true;
});
+ ui.findPreference(PreferenceController.PREF_GPODNET_FORCE_FULL_SYNC).
+ setOnPreferenceClickListener(preference -> {
+ GpodnetPreferences.setLastSubscriptionSyncTimestamp(0L);
+ GpodnetPreferences.setLastEpisodeActionsSyncTimestamp(0L);
+ GpodnetPreferences.setLastSyncAttempt(false, 0);
+ updateLastGpodnetSyncReport(false, 0);
+ GpodnetSyncService.sendSyncIntent(ui.getActivity().getApplicationContext());
+ Toast toast = Toast.makeText(ui.getActivity(), R.string.pref_gpodnet_sync_started,
+ Toast.LENGTH_SHORT);
+ toast.show();
+ return true;
+ });
ui.findPreference(PreferenceController.PREF_GPODNET_LOGOUT).setOnPreferenceClickListener(
preference -> {
GpodnetPreferences.logout();
@@ -440,6 +459,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 +517,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 &&
@@ -505,6 +564,7 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
ui.findPreference(PreferenceController.PREF_GPODNET_LOGIN).setEnabled(!loggedIn);
ui.findPreference(PreferenceController.PREF_GPODNET_SETLOGIN_INFORMATION).setEnabled(loggedIn);
ui.findPreference(PreferenceController.PREF_GPODNET_SYNC).setEnabled(loggedIn);
+ ui.findPreference(PreferenceController.PREF_GPODNET_FORCE_FULL_SYNC).setEnabled(loggedIn);
ui.findPreference(PreferenceController.PREF_GPODNET_LOGOUT).setEnabled(loggedIn);
ui.findPreference(PREF_GPODNET_NOTIFICATIONS).setEnabled(loggedIn);
if(loggedIn) {
@@ -524,7 +584,7 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
private void updateLastGpodnetSyncReport(boolean successful, long lastTime) {
Preference sync = ui.findPreference(PREF_GPODNET_SYNC);
if (lastTime != 0) {
- sync.setSummary(ui.getActivity().getString(R.string.pref_gpodnet_sync_sum) + "\n" +
+ sync.setSummary(ui.getActivity().getString(R.string.pref_gpodnet_sync_changes_sum) + "\n" +
ui.getActivity().getString(R.string.pref_gpodnet_sync_sum_last_sync_line,
ui.getActivity().getString(successful ?
R.string.gpodnetsync_pref_report_successful :
@@ -535,7 +595,7 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
DateUtils.WEEK_IN_MILLIS,
DateUtils.FORMAT_SHOW_TIME)));
} else {
- sync.setSummary(ui.getActivity().getString(R.string.pref_gpodnet_sync_sum));
+ sync.setSummary(ui.getActivity().getString(R.string.pref_gpodnet_sync_changes_sum));
}
}
@@ -703,6 +763,12 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
List<WifiConfiguration> networks = wifiservice.getConfiguredNetworks();
if (networks != null) {
+ Collections.sort(networks, new Comparator<WifiConfiguration>() {
+ @Override
+ public int compare(WifiConfiguration x, WifiConfiguration y) {
+ return x.SSID.compareTo(y.SSID);
+ }
+ });
selectedNetworks = new CheckBoxPreference[networks.size()];
List<String> prefValues = Arrays.asList(UserPreferences
.getAutodownloadSelectedNetworks());
@@ -787,9 +853,8 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
hiddenDrawerItems.add(NAV_DRAWER_TAGS[which]);
}
});
- builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> {
- UserPreferences.setHiddenDrawerItems(hiddenDrawerItems);
- });
+ builder.setPositiveButton(R.string.confirm_label, (dialog, which) ->
+ UserPreferences.setHiddenDrawerItems(hiddenDrawerItems));
builder.setNegativeButton(R.string.cancel_label, null);
builder.create().show();
}
@@ -833,9 +898,8 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
preferredButtons.remove((Integer) which);
}
});
- builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> {
- UserPreferences.setCompactNotificationButtons(preferredButtons);
- });
+ builder.setPositiveButton(R.string.confirm_label, (dialog, which) ->
+ UserPreferences.setCompactNotificationButtons(preferredButtons));
builder.setNegativeButton(R.string.cancel_label, null);
builder.create().show();
}
diff --git a/app/src/main/play/ast_ES/listing/fulldescription b/app/src/main/play/ast_ES/listing/fulldescription
new file mode 100644
index 000000000..87b477fdc
--- /dev/null
+++ b/app/src/main/play/ast_ES/listing/fulldescription
@@ -0,0 +1,43 @@
+AntennaPod is a podcast manager and player that gives you instant access to millions of free and paid podcasts, from independent podcasters to large publishing houses such as the BBC, NPR and CNN. Add, import and export their feeds hassle-free using the iTunes podcast database, OPML files or simple RSS URLs. Save effort, battery power and mobile data usage with powerful automation controls for downloading episodes (specify times, intervals and WiFi networks) and deleting episodes (based your favourites and delay settings).<br>
+But most importantly: Download, stream or queue episodes and enjoy them the way you like with adjustable playback speeds, chapter support and a sleep timer. You can even show your love to the content creators with our Flattr integration.
+
+Made by podcast-enthousiast, AntennaPod is free in all senses of the word: open source, no costs, no ads.
+
+<b>All features:</b><br>
+IMPORT, ORGANIZE AND PLAY<br>
+&#8226; Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br>
+&#8226; Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br>
+&#8226; Enjoy listening your way with adjustable playback speed, chapter support (MP3, VorbisComment and Podlove), remembered playback position and an advanced sleep timer (shake to reset, lower volume and slow down playback)<br>
+&#8226; Access password-protected feeds and episodes<br>
+&#8226; Take advantage of paged feeds (www.podlove.org/paged-feeds)
+
+KEEP TRACK, SHARE & APPRECIATE<br>
+&#8226; Keep track of the best of the best by marking episodes as favourites<br>
+&#8226; Find that one episode through the playback history or by searching (titles and shownotes)<br>
+&#8226; Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br>
+&#8226; Support content creators with Flattr integration including automatic flattring
+
+CONTROL THE SYSTEM<br>
+&#8226; Take control over automated downloading: choose feeds, exclude mobile networks, select specific WiFi networks, require the phone to be charging and set times or intervals<br>
+&#8226; Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br>
+&#8226; Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br>
+&#8226; Adapt to your environment using the light and dark theme<br>
+&#8226; Back-up your subscriptions with the gPodder.net integration and OPML export
+
+<b>Join the AntennaPod community!</b><br>
+AntennaPod is under active development by volunteers. You can contribute too, with code or with comment!
+
+GitHub is the place to go for feature requests, bug reports and code contributions:<br>
+https://www.github.com/AntennaPod/AntennaPod
+
+Our Google Group is the place to share your ideas, favourite podcasting moments and gratitude to all the volunteers:<br>
+https://groups.google.com/forum/#!forum/antennapod
+
+Have a question or want to give us feedback?
+https://twitter.com/@AntennaPod
+
+Transifex is the place to help with translations:<br>
+https://www.transifex.com/antennapod/antennapod
+
+Check out our Beta Testing programme to get the latest features first:<br>
+https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod \ No newline at end of file
diff --git a/app/src/main/play/lt/listing/fulldescription b/app/src/main/play/lt/listing/fulldescription
new file mode 100644
index 000000000..87b477fdc
--- /dev/null
+++ b/app/src/main/play/lt/listing/fulldescription
@@ -0,0 +1,43 @@
+AntennaPod is a podcast manager and player that gives you instant access to millions of free and paid podcasts, from independent podcasters to large publishing houses such as the BBC, NPR and CNN. Add, import and export their feeds hassle-free using the iTunes podcast database, OPML files or simple RSS URLs. Save effort, battery power and mobile data usage with powerful automation controls for downloading episodes (specify times, intervals and WiFi networks) and deleting episodes (based your favourites and delay settings).<br>
+But most importantly: Download, stream or queue episodes and enjoy them the way you like with adjustable playback speeds, chapter support and a sleep timer. You can even show your love to the content creators with our Flattr integration.
+
+Made by podcast-enthousiast, AntennaPod is free in all senses of the word: open source, no costs, no ads.
+
+<b>All features:</b><br>
+IMPORT, ORGANIZE AND PLAY<br>
+&#8226; Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br>
+&#8226; Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br>
+&#8226; Enjoy listening your way with adjustable playback speed, chapter support (MP3, VorbisComment and Podlove), remembered playback position and an advanced sleep timer (shake to reset, lower volume and slow down playback)<br>
+&#8226; Access password-protected feeds and episodes<br>
+&#8226; Take advantage of paged feeds (www.podlove.org/paged-feeds)
+
+KEEP TRACK, SHARE & APPRECIATE<br>
+&#8226; Keep track of the best of the best by marking episodes as favourites<br>
+&#8226; Find that one episode through the playback history or by searching (titles and shownotes)<br>
+&#8226; Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br>
+&#8226; Support content creators with Flattr integration including automatic flattring
+
+CONTROL THE SYSTEM<br>
+&#8226; Take control over automated downloading: choose feeds, exclude mobile networks, select specific WiFi networks, require the phone to be charging and set times or intervals<br>
+&#8226; Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br>
+&#8226; Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br>
+&#8226; Adapt to your environment using the light and dark theme<br>
+&#8226; Back-up your subscriptions with the gPodder.net integration and OPML export
+
+<b>Join the AntennaPod community!</b><br>
+AntennaPod is under active development by volunteers. You can contribute too, with code or with comment!
+
+GitHub is the place to go for feature requests, bug reports and code contributions:<br>
+https://www.github.com/AntennaPod/AntennaPod
+
+Our Google Group is the place to share your ideas, favourite podcasting moments and gratitude to all the volunteers:<br>
+https://groups.google.com/forum/#!forum/antennapod
+
+Have a question or want to give us feedback?
+https://twitter.com/@AntennaPod
+
+Transifex is the place to help with translations:<br>
+https://www.transifex.com/antennapod/antennapod
+
+Check out our Beta Testing programme to get the latest features first:<br>
+https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod \ No newline at end of file
diff --git a/app/src/main/play/te/listing/fulldescription b/app/src/main/play/te/listing/fulldescription
new file mode 100644
index 000000000..87b477fdc
--- /dev/null
+++ b/app/src/main/play/te/listing/fulldescription
@@ -0,0 +1,43 @@
+AntennaPod is a podcast manager and player that gives you instant access to millions of free and paid podcasts, from independent podcasters to large publishing houses such as the BBC, NPR and CNN. Add, import and export their feeds hassle-free using the iTunes podcast database, OPML files or simple RSS URLs. Save effort, battery power and mobile data usage with powerful automation controls for downloading episodes (specify times, intervals and WiFi networks) and deleting episodes (based your favourites and delay settings).<br>
+But most importantly: Download, stream or queue episodes and enjoy them the way you like with adjustable playback speeds, chapter support and a sleep timer. You can even show your love to the content creators with our Flattr integration.
+
+Made by podcast-enthousiast, AntennaPod is free in all senses of the word: open source, no costs, no ads.
+
+<b>All features:</b><br>
+IMPORT, ORGANIZE AND PLAY<br>
+&#8226; Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br>
+&#8226; Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br>
+&#8226; Enjoy listening your way with adjustable playback speed, chapter support (MP3, VorbisComment and Podlove), remembered playback position and an advanced sleep timer (shake to reset, lower volume and slow down playback)<br>
+&#8226; Access password-protected feeds and episodes<br>
+&#8226; Take advantage of paged feeds (www.podlove.org/paged-feeds)
+
+KEEP TRACK, SHARE & APPRECIATE<br>
+&#8226; Keep track of the best of the best by marking episodes as favourites<br>
+&#8226; Find that one episode through the playback history or by searching (titles and shownotes)<br>
+&#8226; Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br>
+&#8226; Support content creators with Flattr integration including automatic flattring
+
+CONTROL THE SYSTEM<br>
+&#8226; Take control over automated downloading: choose feeds, exclude mobile networks, select specific WiFi networks, require the phone to be charging and set times or intervals<br>
+&#8226; Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br>
+&#8226; Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br>
+&#8226; Adapt to your environment using the light and dark theme<br>
+&#8226; Back-up your subscriptions with the gPodder.net integration and OPML export
+
+<b>Join the AntennaPod community!</b><br>
+AntennaPod is under active development by volunteers. You can contribute too, with code or with comment!
+
+GitHub is the place to go for feature requests, bug reports and code contributions:<br>
+https://www.github.com/AntennaPod/AntennaPod
+
+Our Google Group is the place to share your ideas, favourite podcasting moments and gratitude to all the volunteers:<br>
+https://groups.google.com/forum/#!forum/antennapod
+
+Have a question or want to give us feedback?
+https://twitter.com/@AntennaPod
+
+Transifex is the place to help with translations:<br>
+https://www.transifex.com/antennapod/antennapod
+
+Check out our Beta Testing programme to get the latest features first:<br>
+https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod \ No newline at end of file
diff --git a/app/src/main/play/zh_TW/listing/fulldescription b/app/src/main/play/zh_TW/listing/fulldescription
new file mode 100644
index 000000000..87b477fdc
--- /dev/null
+++ b/app/src/main/play/zh_TW/listing/fulldescription
@@ -0,0 +1,43 @@
+AntennaPod is a podcast manager and player that gives you instant access to millions of free and paid podcasts, from independent podcasters to large publishing houses such as the BBC, NPR and CNN. Add, import and export their feeds hassle-free using the iTunes podcast database, OPML files or simple RSS URLs. Save effort, battery power and mobile data usage with powerful automation controls for downloading episodes (specify times, intervals and WiFi networks) and deleting episodes (based your favourites and delay settings).<br>
+But most importantly: Download, stream or queue episodes and enjoy them the way you like with adjustable playback speeds, chapter support and a sleep timer. You can even show your love to the content creators with our Flattr integration.
+
+Made by podcast-enthousiast, AntennaPod is free in all senses of the word: open source, no costs, no ads.
+
+<b>All features:</b><br>
+IMPORT, ORGANIZE AND PLAY<br>
+&#8226; Add and import feeds via the iTunes and gPodder.net directories, OPML files and RSS or Atom links<br>
+&#8226; Manage playback from anywhere: homescreen widget, system notification and earplug and bluetooth controls<br>
+&#8226; Enjoy listening your way with adjustable playback speed, chapter support (MP3, VorbisComment and Podlove), remembered playback position and an advanced sleep timer (shake to reset, lower volume and slow down playback)<br>
+&#8226; Access password-protected feeds and episodes<br>
+&#8226; Take advantage of paged feeds (www.podlove.org/paged-feeds)
+
+KEEP TRACK, SHARE & APPRECIATE<br>
+&#8226; Keep track of the best of the best by marking episodes as favourites<br>
+&#8226; Find that one episode through the playback history or by searching (titles and shownotes)<br>
+&#8226; Share episodes and feeds through advanced social media and email options, the gPodder.net services and via OPML export<br>
+&#8226; Support content creators with Flattr integration including automatic flattring
+
+CONTROL THE SYSTEM<br>
+&#8226; Take control over automated downloading: choose feeds, exclude mobile networks, select specific WiFi networks, require the phone to be charging and set times or intervals<br>
+&#8226; Manage storage by setting the amount of cached episodes, smart deletion (based on your favourites and play status) and selecting your preferred location<br>
+&#8226; Use AntennaPod in your language (EN, DE, CS, NL, NB, JA, PT, ES, SV, CA, UK, FR, KO, TR, ZH)<br>
+&#8226; Adapt to your environment using the light and dark theme<br>
+&#8226; Back-up your subscriptions with the gPodder.net integration and OPML export
+
+<b>Join the AntennaPod community!</b><br>
+AntennaPod is under active development by volunteers. You can contribute too, with code or with comment!
+
+GitHub is the place to go for feature requests, bug reports and code contributions:<br>
+https://www.github.com/AntennaPod/AntennaPod
+
+Our Google Group is the place to share your ideas, favourite podcasting moments and gratitude to all the volunteers:<br>
+https://groups.google.com/forum/#!forum/antennapod
+
+Have a question or want to give us feedback?
+https://twitter.com/@AntennaPod
+
+Transifex is the place to help with translations:<br>
+https://www.transifex.com/antennapod/antennapod
+
+Check out our Beta Testing programme to get the latest features first:<br>
+https://www.github.com/AntennaPod/AntennaPod/wiki/Help-test-AntennaPod \ No newline at end of file
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/nav_list.xml b/app/src/main/res/layout/nav_list.xml
index 9fcf9d9fc..7e72bb39b 100644
--- a/app/src/main/res/layout/nav_list.xml
+++ b/app/src/main/res/layout/nav_list.xml
@@ -1,7 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<RelativeLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
+<?xml version='1.0' encoding='utf-8'?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_layout"
android:layout_width="@dimen/drawer_width"
@@ -23,8 +21,6 @@
android:id="@+id/imgvCover"
android:layout_width="@dimen/thumbnail_length_navlist"
android:layout_height="@dimen/thumbnail_length_navlist"
- android:layout_alignParentLeft="true"
- android:layout_centerVertical="true"
android:layout_marginBottom="4dp"
android:layout_marginLeft="@dimen/listitem_icon_leftpadding"
android:layout_marginTop="4dp"
@@ -34,8 +30,8 @@
android:padding="8dp"
android:scaleType="centerCrop"
android:src="?attr/ic_settings"
- tools:src="@android:drawable/sym_def_app_icon"
- tools:background="@android:color/holo_orange_dark" />
+ tools:background="@android:color/holo_orange_dark"
+ tools:src="@android:drawable/sym_def_app_icon"></ImageView>
<TextView
android:layout_width="wrap_content"
@@ -47,16 +43,15 @@
android:text="@string/settings_label"
android:textColor="?android:attr/textColorPrimary"
android:textSize="@dimen/text_size_navdrawer"
- tools:background="@android:color/holo_green_light"/>
-
+ tools:background="@android:color/holo_green_light" />
</LinearLayout>
<View
android:id="@+id/divider"
android:layout_width="@dimen/drawer_width"
android:layout_height="1dp"
- android:layout_centerVertical="true"
android:layout_above="@id/nav_settings"
+ android:layout_centerVertical="true"
android:background="?android:attr/listDivider"
tools:background="@android:color/holo_red_dark" />
@@ -64,7 +59,6 @@
android:id="@+id/nav_list"
android:layout_width="@dimen/drawer_width"
android:layout_height="wrap_content"
- android:layout_weight="1"
android:layout_above="@id/divider"
android:layout_alignParentTop="true"
android:choiceMode="singleChoice"
@@ -74,7 +68,6 @@
android:paddingBottom="@dimen/list_vertical_padding"
android:paddingTop="@dimen/list_vertical_padding"
android:scrollbarStyle="outsideOverlay"
- tools:listitem="@layout/nav_listitem"
- tools:background="@android:color/holo_purple" />
-
+ tools:background="@android:color/holo_purple"
+ tools:listitem="@layout/nav_listitem"></ListView>
</RelativeLayout>
diff --git a/app/src/main/res/layout/subscription_item.xml b/app/src/main/res/layout/subscription_item.xml
index 19b9943e4..8f0539dfa 100644
--- a/app/src/main/res/layout/subscription_item.xml
+++ b/app/src/main/res/layout/subscription_item.xml
@@ -1,7 +1,7 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version='1.0' encoding='utf-8'?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
@@ -10,31 +10,28 @@
android:id="@+id/imgvCover"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
- android:layout_centerHorizontal="true"
- android:layout_centerVertical="true"
android:scaleType="centerCrop"
- tools:src="@drawable/ic_launcher" />
+ tools:src="@drawable/ic_launcher">
+ </de.danoeh.antennapod.view.SquareImageView>
<com.joanzapata.iconify.widget.IconTextView
android:id="@+id/txtvTitle"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:background="@color/light_gray"
android:ellipsize="end"
android:gravity="center"
- android:background="@color/light_gray"
tools:text="@string/app_name" />
<jp.shts.android.library.TriangleLabelView
android:id="@+id/triangleCountView"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:layout_alignParentRight="true"
- android:layout_alignParentTop="true"
+ android:layout_gravity="right|top"
app:backgroundColor="@color/antennapod_blue"
app:corner="rightTop"
app:primaryText="Test"
app:primaryTextColor="@color/white"
- app:primaryTextSize="12sp"
- android:layout_gravity="right|top"/>
-
+ app:primaryTextSize="12sp">
+ </jp.shts.android.library.TriangleLabelView>
</FrameLayout>
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/menu/episodes_apply_action_options.xml b/app/src/main/res/menu/episodes_apply_action_options.xml
index 3df88046d..c3f117386 100644
--- a/app/src/main/res/menu/episodes_apply_action_options.xml
+++ b/app/src/main/res/menu/episodes_apply_action_options.xml
@@ -46,6 +46,8 @@
android:title="@string/queued_label"/>
<item android:id="@+id/check_not_queued"
android:title="@string/not_queued_label"/>
+ <item android:id="@+id/check_has_media"
+ android:title="@string/has_media"/>
</menu>
</item>
diff --git a/app/src/main/res/menu/feedlist.xml b/app/src/main/res/menu/feedlist.xml
index ed03c08d6..0646dc70f 100644
--- a/app/src/main/res/menu/feedlist.xml
+++ b/app/src/main/res/menu/feedlist.xml
@@ -66,6 +66,12 @@
</item>
<item
+ android:id="@+id/rename_item"
+ android:menuCategory="container"
+ android:title="@string/rename_feed_label"
+ custom:showAsAction="never" />
+
+ <item
android:id="@+id/remove_item"
android:icon="?attr/content_discard"
android:menuCategory="container"
diff --git a/app/src/main/res/menu/nav_feed_context.xml b/app/src/main/res/menu/nav_feed_context.xml
index 4bf067d25..4da40441f 100644
--- a/app/src/main/res/menu/nav_feed_context.xml
+++ b/app/src/main/res/menu/nav_feed_context.xml
@@ -12,6 +12,11 @@
android:title="@string/mark_all_read_label" />
<item
+ android:id="@+id/rename_item"
+ android:menuCategory="container"
+ android:title="@string/rename_feed_label" />
+
+ <item
android:id="@+id/remove_item"
android:menuCategory="container"
android:title="@string/remove_feed_label" />
diff --git a/app/src/main/res/xml/automotive_app_desc.xml b/app/src/main/res/xml/automotive_app_desc.xml
deleted file mode 100644
index 0a6a3c9fb..000000000
--- a/app/src/main/res/xml/automotive_app_desc.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<automotiveApp>
- <uses name="media"/>
-</automotiveApp> \ No newline at end of file
diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml
index 2aa736cb2..0f1175ca3 100644
--- a/app/src/main/res/xml/preferences.xml
+++ b/app/src/main/res/xml/preferences.xml
@@ -118,6 +118,12 @@
android:summary="@string/pref_rewind_sum"
android:title="@string/pref_rewind" />
<de.danoeh.antennapod.preferences.SwitchCompatPreference
+ android:defaultValue="false"
+ android:enabled="true"
+ android:key="prefHardwarePreviousButtonRestarts"
+ android:summary="@string/pref_hardwarePreviousButtonRestarts_sum"
+ android:title="@string/pref_hardwarePreviousButtonRestarts_title"/>
+ <de.danoeh.antennapod.preferences.SwitchCompatPreference
android:defaultValue="true"
android:enabled="true"
android:key="prefFollowQueue"
@@ -162,6 +168,12 @@
</PreferenceCategory>
<PreferenceCategory android:title="@string/network_pref">
+ <de.danoeh.antennapod.preferences.SwitchCompatPreference
+ android:defaultValue="true"
+ android:enabled="true"
+ android:key="prefEnqueueDownloaded"
+ android:summary="@string/pref_enqueue_downloaded_summary"
+ android:title="@string/pref_enqueue_downloaded_title" />
<Preference
android:key="prefAutoUpdateIntervall"
android:summary="@string/pref_autoUpdateIntervallOrTime_sum"
@@ -254,8 +266,12 @@
android:summary="@string/pref_gpodnet_setlogin_information_sum"/>
<Preference
android:key="pref_gpodnet_sync"
- android:title="@string/pref_gpodnet_sync_title"
- android:summary="@string/pref_gpodnet_sync_sum"/>
+ android:title="@string/pref_gpodnet_sync_changes_title"
+ android:summary="@string/pref_gpodnet_sync_changes_sum"/>
+ <Preference
+ android:key="pref_gpodnet_force_full_sync"
+ android:title="@string/pref_gpodnet_full_sync_title"
+ android:summary="@string/pref_gpodnet_full_sync_sum"/>
<Preference
android:key="pref_gpodnet_logout"
android:title="@string/pref_gpodnet_logout_title"/>
@@ -286,6 +302,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/app/src/main/templates/about.html b/app/src/main/templates/about.html
index 5c7a3cbd0..400727c46 100644
--- a/app/src/main/templates/about.html
+++ b/app/src/main/templates/about.html
@@ -52,7 +52,7 @@
<p>Created by Daniel Oeh</p>
- <p>Copyright &copy; 2015 AntennaPod Contributors <a href="CONTRIBUTORS.txt">(View)</a></p>
+ <p>Copyright &copy; 2012-@year@ AntennaPod Contributors <a href="CONTRIBUTORS.txt">(View)</a></p>
<p>Licensed under the MIT License <a href="LICENSE.txt">(View)</a></p>
</div>