diff options
10 files changed, 92 insertions, 35 deletions
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java index 9a4c9e030..ae9c60f65 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java @@ -1,5 +1,7 @@ package de.danoeh.antennapod.fragment; +import android.app.AlertDialog; +import android.app.Dialog; import android.content.res.TypedArray; import android.os.Bundle; import android.support.v4.app.ListFragment; @@ -13,9 +15,11 @@ import android.widget.ListView; import java.util.List; +import android.widget.TextView; import de.danoeh.antennapod.R; import de.danoeh.antennapod.adapter.DownloadLogAdapter; import de.danoeh.antennapod.core.feed.EventDistributor; +import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.service.download.DownloadStatus; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBWriter; @@ -82,6 +86,29 @@ public class DownloadLogFragment extends ListFragment { getActivity().supportInvalidateOptionsMenu(); } + @Override + public void onListItemClick(ListView l, View v, int position, long id) { + super.onListItemClick(l, v, position, id); + + DownloadStatus status = adapter.getItem(position); + String url = "unknown"; + String message = getString(R.string.download_successful); + FeedMedia media = DBReader.getFeedMedia(status.getFeedfileId()); + if (media != null) { + url = media.getDownload_url(); + } + if (!status.isSuccessful()) { + message = status.getReasonDetailed(); + } + + AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); + builder.setTitle(R.string.download_error_details); + builder.setMessage(getString(R.string.download_error_details_message, message, url)); + builder.setPositiveButton(android.R.string.ok, null); + Dialog dialog = builder.show(); + ((TextView) dialog.findViewById(android.R.id.message)).setTextIsSelectable(true); + } + private final DownloadLogAdapter.ItemAccess itemAccess = new DownloadLogAdapter.ItemAccess() { @Override 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 935fd7898..417af6133 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java @@ -33,6 +33,7 @@ import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.util.Converter; import de.danoeh.antennapod.core.util.IntentUtils; +import de.danoeh.antennapod.core.util.NetworkUtils; import de.danoeh.antennapod.core.util.ShareUtils; import de.danoeh.antennapod.core.util.ShownotesProvider; import de.danoeh.antennapod.core.util.playback.Playable; @@ -118,6 +119,10 @@ public class ItemDescriptionFragment extends Fragment implements MediaplayerInfo R.style.Theme_AntennaPod_Dark ? Color.BLACK : Color.WHITE); ta.recycle(); webvDescription.setBackgroundColor(backgroundColor); + if (!NetworkUtils.networkAvailable()) { + webvDescription.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); + // Use cached resources, even if they have expired + } webvDescription.getSettings().setUseWideViewPort(false); webvDescription.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN); webvDescription.getSettings().setLoadWithOverviewMode(true); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java index 4ae6b97ee..2d11e9f71 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java @@ -34,6 +34,7 @@ import com.bumptech.glide.Glide; import com.joanzapata.iconify.Iconify; import com.joanzapata.iconify.widget.IconButton; +import de.danoeh.antennapod.core.util.NetworkUtils; import org.apache.commons.lang3.ArrayUtils; import java.util.List; @@ -189,6 +190,10 @@ public class ItemFragment extends Fragment implements OnSwipeGesture { } webvDescription.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.black)); } + if (!NetworkUtils.networkAvailable()) { + webvDescription.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); + // Use cached resources, even if they have expired + } webvDescription.getSettings().setUseWideViewPort(false); webvDescription.getSettings().setLayoutAlgorithm( WebSettings.LayoutAlgorithm.NARROW_COLUMNS); 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 0f42dd01a..2c7d738dd 100644 --- a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java +++ b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java @@ -39,6 +39,7 @@ import android.widget.Toast; import com.afollestad.materialdialogs.MaterialDialog; import de.danoeh.antennapod.activity.ImportExportActivity; +import de.danoeh.antennapod.activity.OpmlImportFromPathActivity; import org.apache.commons.lang3.ArrayUtils; import java.io.File; @@ -89,6 +90,7 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc private static final String PREF_FLATTR_REVOKE = "prefRevokeAccess"; private static final String PREF_AUTO_FLATTR_PREFS = "prefAutoFlattrPrefs"; private static final String PREF_OPML_EXPORT = "prefOpmlExport"; + private static final String PREF_OPML_IMPORT = "prefOpmlImport"; private static final String PREF_HTML_EXPORT = "prefHtmlExport"; private static final String STATISTICS = "statistics"; private static final String IMPORT_EXPORT = "importExport"; @@ -185,6 +187,11 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc preference -> export(new OpmlWriter())); ui.findPreference(PreferenceController.PREF_HTML_EXPORT).setOnPreferenceClickListener( preference -> export(new HtmlWriter())); + ui.findPreference(PreferenceController.PREF_OPML_IMPORT).setOnPreferenceClickListener( + preference -> { + activity.startActivity(new Intent(activity, OpmlImportFromPathActivity.class)); + return true; + }); ui.findPreference(PreferenceController.PREF_CHOOSE_DATA_DIR).setOnPreferenceClickListener( preference -> { if (Build.VERSION_CODES.KITKAT <= Build.VERSION.SDK_INT && @@ -474,8 +481,8 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc 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.setTitle(R.string.export_success_title); + String message = context.getString(R.string.export_success_sum, output.toString()); alert.setMessage(message); alert.setPositiveButton(R.string.send_label, (dialog, which) -> { Uri fileUri = FileProvider.getUriForFile(context.getApplicationContext(), diff --git a/app/src/main/res/layout/downloadlog_item.xml b/app/src/main/res/layout/downloadlog_item.xml index 27b179f4e..712dda63e 100644 --- a/app/src/main/res/layout/downloadlog_item.xml +++ b/app/src/main/res/layout/downloadlog_item.xml @@ -8,6 +8,7 @@ android:paddingLeft="16dp" android:paddingRight="16dp" android:paddingBottom="8dp" + android:descendantFocusability="blocksDescendants" tools:background="@android:color/darker_gray"> <com.joanzapata.iconify.widget.IconTextView diff --git a/app/src/main/res/layout/import_export_activity.xml b/app/src/main/res/layout/import_export_activity.xml index 6614a8710..97ff34e41 100644 --- a/app/src/main/res/layout/import_export_activity.xml +++ b/app/src/main/res/layout/import_export_activity.xml @@ -1,28 +1,34 @@ <?xml version="1.0" encoding="utf-8"?> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="vertical" - android:id="@+id/import_export_layout" - android:padding="8dp"> +<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + android:id="@+id/import_export_layout" + android:padding="8dp" + android:clipToPadding="false"> - <TextView - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:text="@string/import_export_warning" - android:gravity="center_horizontal"/> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> - <Button - android:text="@string/label_export" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:id="@+id/button_export" - android:layout_marginTop="24dp"/> + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/import_export_warning" + android:gravity="center_horizontal"/> - <Button - android:text="@string/label_import" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:id="@+id/button_import"/> + <Button + android:text="@string/label_export" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:id="@+id/button_export" + android:layout_marginTop="24dp"/> -</LinearLayout> + <Button + android:text="@string/label_import" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:id="@+id/button_import"/> + </LinearLayout> +</ScrollView> diff --git a/app/src/main/res/layout/nav_list.xml b/app/src/main/res/layout/nav_list.xml index db4d44675..e2fe61e28 100644 --- a/app/src/main/res/layout/nav_list.xml +++ b/app/src/main/res/layout/nav_list.xml @@ -15,7 +15,8 @@ android:layout_alignParentBottom="true" android:background="?attr/selectableItemBackground" android:contentDescription="@string/settings_label" - android:orientation="horizontal"> + android:orientation="horizontal" + android:focusable="true"> <ImageView android:id="@+id/imgvCover" diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 8ed7da731..ba389fc3c 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -313,6 +313,9 @@ android:key="prefOpmlExport" android:title="@string/opml_export_label"/> <Preference + android:key="prefOpmlImport" + android:title="@string/opml_import_label"/> + <Preference android:key="prefHtmlExport" android:title="@string/html_export_label"/> <Preference diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java index 5ff3f70df..e82252310 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java @@ -308,7 +308,6 @@ public class PodDBAdapter { KEY_CONTENT_ENCODED, KEY_FEED}; private static Context context; - private static PodDBHelper dbHelper; private static volatile SQLiteDatabase db; private static int counter = 0; @@ -317,13 +316,14 @@ public class PodDBAdapter { PodDBAdapter.context = context.getApplicationContext(); } - private static class PodDBHelperholder { - public static final PodDBHelper dbHelper = new PodDBHelper(PodDBAdapter.context, DATABASE_NAME, null); + // Bill Pugh Singleton Implementation + private static class SingletonHolder { + private static final PodDBHelper dbHelper = new PodDBHelper(PodDBAdapter.context, DATABASE_NAME, null); + private static final PodDBAdapter dbAdapter = new PodDBAdapter(); } public static PodDBAdapter getInstance() { - dbHelper = PodDBHelperholder.dbHelper; - return new PodDBAdapter(); + return SingletonHolder.dbAdapter; } private PodDBAdapter() { @@ -342,11 +342,11 @@ public class PodDBAdapter { private SQLiteDatabase openDb() { SQLiteDatabase newDb; try { - newDb = dbHelper.getWritableDatabase(); + newDb = SingletonHolder.dbHelper.getWritableDatabase(); newDb.enableWriteAheadLogging(); } catch (SQLException ex) { Log.e(TAG, Log.getStackTraceString(ex)); - newDb = dbHelper.getReadableDatabase(); + newDb = SingletonHolder.dbHelper.getReadableDatabase(); } return newDb; } diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index f0eed3e38..aa36eab33 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -182,6 +182,8 @@ <string name="download_failed">failed</string> <string name="download_pending">Download pending</string> <string name="download_running">Download running</string> + <string name="download_error_details">Details</string> + <string name="download_error_details_message">%1$s \n\nFile URL:\n%2$s</string> <string name="download_error_device_not_found">Storage Device not found</string> <string name="download_error_insufficient_space">Insufficient Space</string> <string name="download_error_file_error">File Error</string> @@ -475,8 +477,8 @@ <string name="html_export_label">HTML export</string> <string name="exporting_label">Exporting…</string> <string name="export_error_label">Export error</string> - <string name="opml_export_success_title">OPML Export successful.</string> - <string name="opml_export_success_sum">The .opml file was written to:\u0020</string> + <string name="export_success_title">Export successful</string> + <string name="export_success_sum">The exported file was written to:\n\n%1$s</string> <string name="opml_import_ask_read_permission">Access to external storage is required to read the OPML file</string> <!-- Sleep timer --> |