From 2464320f33ad708312398cfc4b2392cefd38e2cf Mon Sep 17 00:00:00 2001 From: Hrishikesh Kadam Date: Wed, 29 Aug 2018 16:38:50 +0530 Subject: [PATCH 1/6] Fix special characters in epub file name <= API 22 Fixes FolioReader/FolioReader-Android#261 API <= 22 throws java.io.EOFException at urlConnection.getInputStream() when url has space or special character in it. --- .../java/com/folioreader/ui/folio/activity/FolioActivity.java | 2 +- .../com/folioreader/ui/folio/fragment/FolioPageFragment.java | 2 +- .../ui/tableofcontents/view/TableOfContentFragment.java | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/folioreader/src/main/java/com/folioreader/ui/folio/activity/FolioActivity.java b/folioreader/src/main/java/com/folioreader/ui/folio/activity/FolioActivity.java index ea84cbd72..8e64e5a43 100644 --- a/folioreader/src/main/java/com/folioreader/ui/folio/activity/FolioActivity.java +++ b/folioreader/src/main/java/com/folioreader/ui/folio/activity/FolioActivity.java @@ -340,7 +340,7 @@ private void initBook(String mEpubFileName, int mEpubRawId, String mEpubFilePath mEpubRawId, mEpubFileName); addEpub(path); - String urlString = Constants.LOCALHOST + bookFileName + "/manifest"; + String urlString = Constants.LOCALHOST + Uri.encode(bookFileName) + "/manifest"; new MainPresenter(this).parseManifest(urlString); } catch (IOException e) { diff --git a/folioreader/src/main/java/com/folioreader/ui/folio/fragment/FolioPageFragment.java b/folioreader/src/main/java/com/folioreader/ui/folio/fragment/FolioPageFragment.java index 3068af25e..fc7bfc0bb 100644 --- a/folioreader/src/main/java/com/folioreader/ui/folio/fragment/FolioPageFragment.java +++ b/folioreader/src/main/java/com/folioreader/ui/folio/fragment/FolioPageFragment.java @@ -204,7 +204,7 @@ public View onCreateView(LayoutInflater inflater, } private String getWebviewUrl() { - return Constants.LOCALHOST + mBookTitle + "/" + spineItem.href; + return Constants.LOCALHOST + Uri.encode(mBookTitle) + "/" + spineItem.href; } /** diff --git a/folioreader/src/main/java/com/folioreader/ui/tableofcontents/view/TableOfContentFragment.java b/folioreader/src/main/java/com/folioreader/ui/tableofcontents/view/TableOfContentFragment.java index c9a63b5fa..67a513b38 100644 --- a/folioreader/src/main/java/com/folioreader/ui/tableofcontents/view/TableOfContentFragment.java +++ b/folioreader/src/main/java/com/folioreader/ui/tableofcontents/view/TableOfContentFragment.java @@ -2,6 +2,7 @@ import android.app.Activity; import android.content.Intent; +import android.net.Uri; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; @@ -72,7 +73,7 @@ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); mTableOfContentsRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view_menu); errorView = (TextView) view.findViewById(R.id.tv_error); - String urlString = Constants.LOCALHOST + mBookTitle + "/manifest"; + String urlString = Constants.LOCALHOST + Uri.encode(mBookTitle) + "/manifest"; configRecyclerViews(); presenter.getTOCContent(urlString); From 6ab537e7dd3866c07b9caca8c6e44149cea2b663 Mon Sep 17 00:00:00 2001 From: Hrishikesh Kadam Date: Thu, 30 Aug 2018 14:35:25 +0530 Subject: [PATCH 2/6] Fix font size issue Fixes FolioReader/FolioReader-Android/issues/243 Epub attached to this issue had a font size in body style of it, so p, span, div tag scaled accordingly to the body style. When 'rem'(root em) is specified, font size changes according to font size specified in root element i.e. html. --- folioreader/src/main/assets/css/Style.css | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/folioreader/src/main/assets/css/Style.css b/folioreader/src/main/assets/css/Style.css index ba1c71e6d..8500ff7d2 100755 --- a/folioreader/src/main/assets/css/Style.css +++ b/folioreader/src/main/assets/css/Style.css @@ -87,7 +87,7 @@ b, strong, th {font-weight: bolder !important;} /* Forced font overrides */ code, kbd, pre, samp, tt { font-family: monospace, monospace !important; - font-size: 1em; + font-size: 1rem; } button, input, select, textarea { display: inline-block !important; } /*h1, h2, h3, h4, h5, h6 { font-weight: 400!important; }*/ @@ -100,8 +100,8 @@ hr { /* Sub and Super */ -big { font-size: 1.15em !important; } -small, sub, sup { font-size: .65em !important; } +big { font-size: 1.15rem !important; } +small, sub, sup { font-size: .65rem !important; } sub { vertical-align: sub !important; } sup { font-family: monospace !important; @@ -269,27 +269,27 @@ html.textSizeFour { font-size: 19px !important; } html.textSizeFive { font-size: 21px !important; } h1 { - font-size: 2em; + font-size: 2rem; line-height: 1.2; } h2 { - font-size: 1.5em; + font-size: 1.5rem; line-height: 1.2; } h3 { - font-size: 1.17em; + font-size: 1.17rem; line-height: 1.2; } h4 { - font-size: 1em; + font-size: 1rem; line-height: 1.2; } h5 { - font-size: 0.83em; + font-size: 0.83rem; line-height: 1.2; } h6 { - font-size: 0.67em; + font-size: 0.67rem; line-height: 1.2; } body { @@ -298,12 +298,12 @@ body { hyphens: auto !important; } p, span, div { - font-size: 1em; + font-size: 1rem; line-height: 1.5 !important; } @media only screen and (min-device-width: 600px) { div { - font-size: 1em; + font-size: 1rem; line-height: 1.438em !important; } body { From 34fb154efc0f08b7a6e731e05f3592ceb955147a Mon Sep 17 00:00:00 2001 From: Hrishikesh Kadam Date: Fri, 31 Aug 2018 13:14:25 +0530 Subject: [PATCH 3/6] Close API with all the edge cases --- .../java/com/folioreader/FolioReader.java | 84 ++++++++++++++++++- .../ui/folio/activity/FolioActivity.java | 72 ++++++++++++++++ .../ui/folio/activity/SearchActivity.kt | 4 +- .../android/sample/HomeActivity.java | 8 ++ 4 files changed, 163 insertions(+), 5 deletions(-) diff --git a/folioreader/src/main/java/com/folioreader/FolioReader.java b/folioreader/src/main/java/com/folioreader/FolioReader.java index e44fa2c8d..8d25ef99b 100644 --- a/folioreader/src/main/java/com/folioreader/FolioReader.java +++ b/folioreader/src/main/java/com/folioreader/FolioReader.java @@ -1,11 +1,15 @@ package com.folioreader; import android.annotation.SuppressLint; +import android.app.Activity; +import android.app.Application; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.os.Bundle; import android.support.v4.content.LocalBroadcastManager; +import android.util.Log; import com.folioreader.model.HighLight; import com.folioreader.model.HighlightImpl; @@ -13,20 +17,24 @@ import com.folioreader.model.sqlite.DbAdapter; import com.folioreader.ui.base.OnSaveHighlight; import com.folioreader.ui.base.SaveReceivedHighlightTask; +import com.folioreader.ui.folio.activity.ContentHighlightActivity; import com.folioreader.ui.folio.activity.FolioActivity; +import com.folioreader.ui.folio.activity.SearchActivity; import com.folioreader.util.OnHighlightListener; import com.folioreader.util.ReadPositionListener; +import java.lang.ref.WeakReference; import java.util.List; /** * Created by avez raj on 9/13/2017. */ -public class FolioReader { +public class FolioReader implements Application.ActivityLifecycleCallbacks { @SuppressLint("StaticFieldLeak") private static FolioReader singleton = null; + private static final String LOG_TAG = FolioReader.class.getSimpleName(); public static final String INTENT_BOOK_ID = "book_id"; private Context context; private Config config; @@ -35,8 +43,14 @@ public class FolioReader { private ReadPositionListener readPositionListener; private ReadPosition readPosition; public static final String ACTION_SAVE_READ_POSITION = "com.folioreader.action.SAVE_READ_POSITION"; + public static final String ACTION_CLOSE_FOLIOREADER = "com.folioreader.action.CLOSE_FOLIOREADER"; public static final String EXTRA_READ_POSITION = "com.folioreader.extra.READ_POSITION"; + //TODO -> Check for memory leak + public static WeakReference folioActivity = null; + public static WeakReference contentHighlightActivity = null; + public static WeakReference searchActivity = null; + private BroadcastReceiver highlightReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -55,7 +69,7 @@ public void onReceive(Context context, Intent intent) { ReadPosition readPosition = intent.getParcelableExtra(FolioReader.EXTRA_READ_POSITION); - if (readPositionListener != null ) + if (readPositionListener != null) readPositionListener.saveReadPosition(readPosition); } }; @@ -160,7 +174,8 @@ private Intent getIntentFromUrl(String assetOrSdcardPath, int rawId) { /** * Pass your configuration and choose to override it every time or just for first execution. - * @param config custom configuration. + * + * @param config custom configuration. * @param overrideConfig true will override the config, false will use either this * config if it is null in application context or will fetch previously * saved one while execution. @@ -219,8 +234,71 @@ public static synchronized void stop() { } } + public static synchronized void close() { + + if (singleton != null) { + Intent intent = new Intent(FolioReader.ACTION_CLOSE_FOLIOREADER); + LocalBroadcastManager.getInstance(singleton.context).sendBroadcast(intent); + } + } + private void unregisterListeners() { LocalBroadcastManager.getInstance(context).unregisterReceiver(highlightReceiver); LocalBroadcastManager.getInstance(context).unregisterReceiver(readPositionReceiver); } + + @Override + public void onActivityCreated(Activity activity, Bundle savedInstanceState) { + + } + + @Override + public void onActivityStarted(Activity activity) { + + } + + @Override + public void onActivityResumed(Activity activity) { + if (activity instanceof FolioActivity) { + folioActivity = new WeakReference<>(activity); + } else if (activity instanceof ContentHighlightActivity) { + contentHighlightActivity = new WeakReference<>(activity); + } else if (activity instanceof SearchActivity) { + searchActivity = new WeakReference<>(activity); + } + } + + @Override + public void onActivityPaused(Activity activity) { + + } + + @Override + public void onActivityStopped(Activity activity) { + Log.d(LOG_TAG, "-> onActivityStopped -> " + activity.getClass().getSimpleName()); + + if (activity instanceof FolioActivity) { + folioActivity = null; + } else if (activity instanceof ContentHighlightActivity) { + contentHighlightActivity = null; + } else if (activity instanceof SearchActivity) { + searchActivity = null; + } + } + + @Override + public void onActivitySaveInstanceState(Activity activity, Bundle outState) { + + } + + @Override + public void onActivityDestroyed(Activity activity) { + if (activity instanceof FolioActivity) { + folioActivity = null; + } else if (activity instanceof ContentHighlightActivity) { + contentHighlightActivity = null; + } else if (activity instanceof SearchActivity) { + searchActivity = null; + } + } } diff --git a/folioreader/src/main/java/com/folioreader/ui/folio/activity/FolioActivity.java b/folioreader/src/main/java/com/folioreader/ui/folio/activity/FolioActivity.java index 8e64e5a43..9bf5f4b1d 100644 --- a/folioreader/src/main/java/com/folioreader/ui/folio/activity/FolioActivity.java +++ b/folioreader/src/main/java/com/folioreader/ui/folio/activity/FolioActivity.java @@ -149,12 +149,70 @@ private enum RequestCode { } } + private BroadcastReceiver closeBroadcastReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + Log.d(LOG_TAG, "-> closeBroadcastReceiver -> onReceive -> " + intent.getAction()); + if (intent.getAction() == null) + return; + if (intent.getAction().equals(FolioReader.ACTION_CLOSE_FOLIOREADER)) { + + Intent closeIntent = new Intent(getApplicationContext(), FolioActivity.class); + closeIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); + closeIntent.setAction(FolioReader.ACTION_CLOSE_FOLIOREADER); + FolioActivity.this.startActivity(closeIntent); + } + } + }; + + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + setIntent(intent); + Log.d(LOG_TAG, "-> onNewIntent"); + String action = getIntent().getAction(); + + if (action != null && action.equals(FolioReader.ACTION_CLOSE_FOLIOREADER)) { + + // Calling finish() in onNewIntent() will not call onPause() and onStop() + if (FolioReader.folioActivity == null && FolioReader.contentHighlightActivity == null && + FolioReader.searchActivity == null) { + Log.i(LOG_TAG, "-> onNewIntent -> FolioActivity not visible and App is in " + + "background means ReadPosition already broadcasted"); + finish(); + moveTaskToBack(true); + + } else if (FolioReader.contentHighlightActivity != null || + FolioReader.searchActivity != null) { + Log.i(LOG_TAG, "-> onNewIntent -> App in foreground but FolioActivity was " + + "already left means ReadPosition already broadcasted"); + finish(); + } + } + } + + @Override + protected void onResume() { + super.onResume(); + Log.d(LOG_TAG, "-> onResume"); + + String action = getIntent().getAction(); + if (action != null && action.equals(FolioReader.ACTION_CLOSE_FOLIOREADER)) { + Log.i(LOG_TAG, "-> onResume -> FolioActivity visible so need to broadcast " + + "ReadPosition"); + finish(); + } + } + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); handler = new Handler(); density = getResources().getDisplayMetrics().density; + registerBroadcasts(); + getApplication().registerActivityLifecycleCallbacks(FolioReader.get()); + // Fix for screen get turned off while reading // TODO: -> Make this configurable // getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); @@ -543,6 +601,9 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == RequestCode.SEARCH.value) { Log.v(LOG_TAG, "-> onActivityResult -> " + RequestCode.SEARCH); + if (resultCode == RESULT_CANCELED) + return; + searchAdapterDataBundle = data.getBundleExtra(SearchAdapter.DATA_BUNDLE); searchQuery = data.getCharSequenceExtra(SearchActivity.BUNDLE_SAVE_SEARCH_QUERY); @@ -587,6 +648,11 @@ protected void onDestroy() { outState.putParcelable(BUNDLE_READ_POSITION_CONFIG_CHANGE, lastReadPosition); LocalBroadcastManager.getInstance(this).unregisterReceiver(searchReceiver); + LocalBroadcastManager.getInstance(this).unregisterReceiver(closeBroadcastReceiver); + FolioReader.folioActivity = null; + FolioReader.searchActivity = null; + FolioReader.contentHighlightActivity = null; + getApplication().unregisterActivityLifecycleCallbacks(FolioReader.get()); if (mEpubServer != null) { mEpubServer.stop(); @@ -895,4 +961,10 @@ private FolioPageFragment getCurrentFragment() { return null; } } + + private void registerBroadcasts() { + Log.d(LOG_TAG, "-> registerBroadcasts"); + LocalBroadcastManager.getInstance(this).registerReceiver(closeBroadcastReceiver, + new IntentFilter(FolioReader.ACTION_CLOSE_FOLIOREADER)); + } } \ No newline at end of file diff --git a/folioreader/src/main/java/com/folioreader/ui/folio/activity/SearchActivity.kt b/folioreader/src/main/java/com/folioreader/ui/folio/activity/SearchActivity.kt index 0c6635e4b..73299c9bc 100644 --- a/folioreader/src/main/java/com/folioreader/ui/folio/activity/SearchActivity.kt +++ b/folioreader/src/main/java/com/folioreader/ui/folio/activity/SearchActivity.kt @@ -48,8 +48,8 @@ class SearchActivity : AppCompatActivity(), LoaderManager.LoaderCallbacks, } enum class ResultCode(val value: Int) { - ITEM_SELECTED(1), - BACK_BUTTON_PRESSED(2) + ITEM_SELECTED(2), + BACK_BUTTON_PRESSED(3) } private lateinit var searchUri: Uri diff --git a/sample/src/main/java/com/folioreader/android/sample/HomeActivity.java b/sample/src/main/java/com/folioreader/android/sample/HomeActivity.java index 05a9fdfc7..2a196400c 100644 --- a/sample/src/main/java/com/folioreader/android/sample/HomeActivity.java +++ b/sample/src/main/java/com/folioreader/android/sample/HomeActivity.java @@ -16,6 +16,7 @@ package com.folioreader.android.sample; import android.os.Bundle; +import android.os.Handler; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.util.Log; @@ -86,6 +87,13 @@ public void onClick(View v) { folioReader.setReadPosition(readPosition) .setConfig(config, true) .openBook("file:///android_asset/TheSilverChair.epub"); + + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + FolioReader.close(); + } + }, 15000); } }); } From 2ca3280f1e027f3792bfa796679cfa482d687ead Mon Sep 17 00:00:00 2001 From: Hrishikesh Kadam Date: Fri, 31 Aug 2018 17:20:03 +0530 Subject: [PATCH 4/6] Close API feature Close FolioReader/FolioReader-Android#251 --- .../java/com/folioreader/FolioReader.java | 130 +++++++----------- .../ui/folio/activity/FolioActivity.java | 64 ++++----- .../ui/folio/fragment/FolioPageFragment.java | 3 +- .../android/sample/HomeActivity.java | 18 ++- 4 files changed, 86 insertions(+), 129 deletions(-) diff --git a/folioreader/src/main/java/com/folioreader/FolioReader.java b/folioreader/src/main/java/com/folioreader/FolioReader.java index 8d25ef99b..6f1c123d6 100644 --- a/folioreader/src/main/java/com/folioreader/FolioReader.java +++ b/folioreader/src/main/java/com/folioreader/FolioReader.java @@ -1,15 +1,11 @@ package com.folioreader; import android.annotation.SuppressLint; -import android.app.Activity; -import android.app.Application; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.os.Bundle; import android.support.v4.content.LocalBroadcastManager; -import android.util.Log; import com.folioreader.model.HighLight; import com.folioreader.model.HighlightImpl; @@ -17,39 +13,42 @@ import com.folioreader.model.sqlite.DbAdapter; import com.folioreader.ui.base.OnSaveHighlight; import com.folioreader.ui.base.SaveReceivedHighlightTask; -import com.folioreader.ui.folio.activity.ContentHighlightActivity; import com.folioreader.ui.folio.activity.FolioActivity; -import com.folioreader.ui.folio.activity.SearchActivity; import com.folioreader.util.OnHighlightListener; import com.folioreader.util.ReadPositionListener; -import java.lang.ref.WeakReference; import java.util.List; /** * Created by avez raj on 9/13/2017. */ -public class FolioReader implements Application.ActivityLifecycleCallbacks { +public class FolioReader { @SuppressLint("StaticFieldLeak") private static FolioReader singleton = null; - private static final String LOG_TAG = FolioReader.class.getSimpleName(); public static final String INTENT_BOOK_ID = "book_id"; private Context context; private Config config; private boolean overrideConfig; private OnHighlightListener onHighlightListener; private ReadPositionListener readPositionListener; + private OnClosedListener onClosedListener; private ReadPosition readPosition; public static final String ACTION_SAVE_READ_POSITION = "com.folioreader.action.SAVE_READ_POSITION"; public static final String ACTION_CLOSE_FOLIOREADER = "com.folioreader.action.CLOSE_FOLIOREADER"; + public static final String ACTION_FOLIOREADER_CLOSED = "com.folioreader.action.FOLIOREADER_CLOSED"; public static final String EXTRA_READ_POSITION = "com.folioreader.extra.READ_POSITION"; - //TODO -> Check for memory leak - public static WeakReference folioActivity = null; - public static WeakReference contentHighlightActivity = null; - public static WeakReference searchActivity = null; + public interface OnClosedListener { + /** + * You may call {@link FolioReader#clear()} in this method, if you wont't require to open + * an epub again from the current activity. + * Or you may call {@link FolioReader#stop()} in this method, if you wont't require to open + * an epub again from your application. + */ + void onFolioReaderClosed(); + } private BroadcastReceiver highlightReceiver = new BroadcastReceiver() { @Override @@ -74,13 +73,21 @@ public void onReceive(Context context, Intent intent) { } }; + private BroadcastReceiver closedReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (onClosedListener != null) + onClosedListener.onFolioReaderClosed(); + } + }; + public static FolioReader get() { if (singleton == null) { synchronized (FolioReader.class) { if (singleton == null) { if (AppContext.get() == null) { - throw new IllegalArgumentException("-> context == null"); + throw new IllegalStateException("-> context == null"); } singleton = new FolioReader(AppContext.get()); } @@ -95,10 +102,14 @@ private FolioReader() { private FolioReader(Context context) { this.context = context; DbAdapter.initialize(context); - LocalBroadcastManager.getInstance(context).registerReceiver(highlightReceiver, + + LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context); + localBroadcastManager.registerReceiver(highlightReceiver, new IntentFilter(HighlightImpl.BROADCAST_EVENT)); - LocalBroadcastManager.getInstance(context).registerReceiver(readPositionReceiver, + localBroadcastManager.registerReceiver(readPositionReceiver, new IntentFilter(ACTION_SAVE_READ_POSITION)); + localBroadcastManager.registerReceiver(closedReceiver, + new IntentFilter(ACTION_FOLIOREADER_CLOSED)); } public FolioReader openBook(String assetOrSdcardPath) { @@ -196,6 +207,11 @@ public FolioReader setReadPositionListener(ReadPositionListener readPositionList return singleton; } + public FolioReader setOnClosedListener(OnClosedListener onClosedListener) { + this.onClosedListener = onClosedListener; + return singleton; + } + public FolioReader setReadPosition(ReadPosition readPosition) { this.readPosition = readPosition; return singleton; @@ -205,6 +221,18 @@ public void saveReceivedHighLights(List highlights, OnSaveHighlight o new SaveReceivedHighlightTask(onSaveHighlight, highlights).execute(); } + /** + * Closes all the activities related to FolioReader. + * After closing all the activities of FolioReader, callback can be received in + * {@link OnClosedListener#onFolioReaderClosed()} if implemented. + * Developer is still bound to call {@link #clear()} or {@link #stop()} + * for clean up if required. + */ + public void close() { + Intent intent = new Intent(FolioReader.ACTION_CLOSE_FOLIOREADER); + LocalBroadcastManager.getInstance(context).sendBroadcast(intent); + } + /** * Nullifies readPosition and listeners. * This method ideally should be used in onDestroy() of Activity or Fragment. @@ -217,6 +245,7 @@ public static synchronized void clear() { singleton.readPosition = null; singleton.onHighlightListener = null; singleton.readPositionListener = null; + singleton.onClosedListener = null; } } @@ -234,71 +263,10 @@ public static synchronized void stop() { } } - public static synchronized void close() { - - if (singleton != null) { - Intent intent = new Intent(FolioReader.ACTION_CLOSE_FOLIOREADER); - LocalBroadcastManager.getInstance(singleton.context).sendBroadcast(intent); - } - } - private void unregisterListeners() { - LocalBroadcastManager.getInstance(context).unregisterReceiver(highlightReceiver); - LocalBroadcastManager.getInstance(context).unregisterReceiver(readPositionReceiver); - } - - @Override - public void onActivityCreated(Activity activity, Bundle savedInstanceState) { - - } - - @Override - public void onActivityStarted(Activity activity) { - - } - - @Override - public void onActivityResumed(Activity activity) { - if (activity instanceof FolioActivity) { - folioActivity = new WeakReference<>(activity); - } else if (activity instanceof ContentHighlightActivity) { - contentHighlightActivity = new WeakReference<>(activity); - } else if (activity instanceof SearchActivity) { - searchActivity = new WeakReference<>(activity); - } - } - - @Override - public void onActivityPaused(Activity activity) { - - } - - @Override - public void onActivityStopped(Activity activity) { - Log.d(LOG_TAG, "-> onActivityStopped -> " + activity.getClass().getSimpleName()); - - if (activity instanceof FolioActivity) { - folioActivity = null; - } else if (activity instanceof ContentHighlightActivity) { - contentHighlightActivity = null; - } else if (activity instanceof SearchActivity) { - searchActivity = null; - } - } - - @Override - public void onActivitySaveInstanceState(Activity activity, Bundle outState) { - - } - - @Override - public void onActivityDestroyed(Activity activity) { - if (activity instanceof FolioActivity) { - folioActivity = null; - } else if (activity instanceof ContentHighlightActivity) { - contentHighlightActivity = null; - } else if (activity instanceof SearchActivity) { - searchActivity = null; - } + LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context); + localBroadcastManager.unregisterReceiver(highlightReceiver); + localBroadcastManager.unregisterReceiver(readPositionReceiver); + localBroadcastManager.unregisterReceiver(closedReceiver); } } diff --git a/folioreader/src/main/java/com/folioreader/ui/folio/activity/FolioActivity.java b/folioreader/src/main/java/com/folioreader/ui/folio/activity/FolioActivity.java index 9bf5f4b1d..c731170da 100644 --- a/folioreader/src/main/java/com/folioreader/ui/folio/activity/FolioActivity.java +++ b/folioreader/src/main/java/com/folioreader/ui/folio/activity/FolioActivity.java @@ -137,6 +137,7 @@ public enum EpubSourceType { private CharSequence searchQuery; private SearchItem searchItem; private float density; + private Boolean topActivity; private enum RequestCode { CONTENT_HIGHLIGHT(77), @@ -152,11 +153,10 @@ private enum RequestCode { private BroadcastReceiver closeBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - Log.d(LOG_TAG, "-> closeBroadcastReceiver -> onReceive -> " + intent.getAction()); - if (intent.getAction() == null) - return; - if (intent.getAction().equals(FolioReader.ACTION_CLOSE_FOLIOREADER)) { + Log.v(LOG_TAG, "-> closeBroadcastReceiver -> onReceive -> " + intent.getAction()); + String action = intent.getAction(); + if (action != null && action.equals(FolioReader.ACTION_CLOSE_FOLIOREADER)) { Intent closeIntent = new Intent(getApplicationContext(), FolioActivity.class); closeIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); closeIntent.setAction(FolioReader.ACTION_CLOSE_FOLIOREADER); @@ -169,23 +169,13 @@ public void onReceive(Context context, Intent intent) { protected void onNewIntent(Intent intent) { super.onNewIntent(intent); setIntent(intent); - Log.d(LOG_TAG, "-> onNewIntent"); - String action = getIntent().getAction(); + Log.v(LOG_TAG, "-> onNewIntent"); + String action = getIntent().getAction(); if (action != null && action.equals(FolioReader.ACTION_CLOSE_FOLIOREADER)) { - - // Calling finish() in onNewIntent() will not call onPause() and onStop() - if (FolioReader.folioActivity == null && FolioReader.contentHighlightActivity == null && - FolioReader.searchActivity == null) { - Log.i(LOG_TAG, "-> onNewIntent -> FolioActivity not visible and App is in " + - "background means ReadPosition already broadcasted"); - finish(); - moveTaskToBack(true); - - } else if (FolioReader.contentHighlightActivity != null || - FolioReader.searchActivity != null) { - Log.i(LOG_TAG, "-> onNewIntent -> App in foreground but FolioActivity was " + - "already left means ReadPosition already broadcasted"); + if (topActivity == null || !topActivity) { + // FolioActivity was already left, so no need to broadcast ReadPosition again. + // Finish activity without going through onPause() and onStop() finish(); } } @@ -194,24 +184,30 @@ protected void onNewIntent(Intent intent) { @Override protected void onResume() { super.onResume(); - Log.d(LOG_TAG, "-> onResume"); + Log.v(LOG_TAG, "-> onResume"); + topActivity = true; String action = getIntent().getAction(); if (action != null && action.equals(FolioReader.ACTION_CLOSE_FOLIOREADER)) { - Log.i(LOG_TAG, "-> onResume -> FolioActivity visible so need to broadcast " + - "ReadPosition"); + // FolioActivity is topActivity, so need to broadcast ReadPosition. finish(); } } + @Override + protected void onStop() { + super.onStop(); + Log.v(LOG_TAG, "-> onStop"); + topActivity = false; + } + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); handler = new Handler(); density = getResources().getDisplayMetrics().density; - - registerBroadcasts(); - getApplication().registerActivityLifecycleCallbacks(FolioReader.get()); + LocalBroadcastManager.getInstance(this).registerReceiver(closeBroadcastReceiver, + new IntentFilter(FolioReader.ACTION_CLOSE_FOLIOREADER)); // Fix for screen get turned off while reading // TODO: -> Make this configurable @@ -647,16 +643,16 @@ protected void onDestroy() { if (outState != null) outState.putParcelable(BUNDLE_READ_POSITION_CONFIG_CHANGE, lastReadPosition); - LocalBroadcastManager.getInstance(this).unregisterReceiver(searchReceiver); - LocalBroadcastManager.getInstance(this).unregisterReceiver(closeBroadcastReceiver); - FolioReader.folioActivity = null; - FolioReader.searchActivity = null; - FolioReader.contentHighlightActivity = null; - getApplication().unregisterActivityLifecycleCallbacks(FolioReader.get()); + LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this); + localBroadcastManager.unregisterReceiver(searchReceiver); + localBroadcastManager.unregisterReceiver(closeBroadcastReceiver); if (mEpubServer != null) { mEpubServer.stop(); } + + if (isFinishing()) + localBroadcastManager.sendBroadcast(new Intent(FolioReader.ACTION_FOLIOREADER_CLOSED)); } @Override @@ -961,10 +957,4 @@ private FolioPageFragment getCurrentFragment() { return null; } } - - private void registerBroadcasts() { - Log.d(LOG_TAG, "-> registerBroadcasts"); - LocalBroadcastManager.getInstance(this).registerReceiver(closeBroadcastReceiver, - new IntentFilter(FolioReader.ACTION_CLOSE_FOLIOREADER)); - } } \ No newline at end of file diff --git a/folioreader/src/main/java/com/folioreader/ui/folio/fragment/FolioPageFragment.java b/folioreader/src/main/java/com/folioreader/ui/folio/fragment/FolioPageFragment.java index fc7bfc0bb..eccbb46e0 100644 --- a/folioreader/src/main/java/com/folioreader/ui/folio/fragment/FolioPageFragment.java +++ b/folioreader/src/main/java/com/folioreader/ui/folio/fragment/FolioPageFragment.java @@ -1141,7 +1141,8 @@ public void onDestroy() { if (isCurrentFragment()) { if (outState != null) outState.putParcelable(BUNDLE_READ_POSITION_CONFIG_CHANGE, lastReadPosition); - mActivityCallback.storeLastReadPosition(lastReadPosition); + if (getActivity() != null && !getActivity().isFinishing()) + mActivityCallback.storeLastReadPosition(lastReadPosition); } if (mWebview != null) mWebview.destroy(); } diff --git a/sample/src/main/java/com/folioreader/android/sample/HomeActivity.java b/sample/src/main/java/com/folioreader/android/sample/HomeActivity.java index 2a196400c..0ad457e05 100644 --- a/sample/src/main/java/com/folioreader/android/sample/HomeActivity.java +++ b/sample/src/main/java/com/folioreader/android/sample/HomeActivity.java @@ -16,7 +16,6 @@ package com.folioreader.android.sample; import android.os.Bundle; -import android.os.Handler; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.util.Log; @@ -43,7 +42,7 @@ import java.util.List; public class HomeActivity extends AppCompatActivity - implements OnHighlightListener, ReadPositionListener { + implements OnHighlightListener, ReadPositionListener, FolioReader.OnClosedListener { private static final String LOG_TAG = HomeActivity.class.getSimpleName(); private FolioReader folioReader; @@ -55,7 +54,8 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { folioReader = FolioReader.get() .setOnHighlightListener(this) - .setReadPositionListener(this); + .setReadPositionListener(this) + .setOnClosedListener(this); getHighlightsAndSave(); @@ -87,13 +87,6 @@ public void onClick(View v) { folioReader.setReadPosition(readPosition) .setConfig(config, true) .openBook("file:///android_asset/TheSilverChair.epub"); - - new Handler().postDelayed(new Runnable() { - @Override - public void run() { - FolioReader.close(); - } - }, 15000); } }); } @@ -185,4 +178,9 @@ public void onHighlight(HighLight highlight, HighLight.HighLightAction type) { "highlight id = " + highlight.getUUID() + " type = " + type, Toast.LENGTH_SHORT).show(); } + + @Override + public void onFolioReaderClosed() { + Log.v(LOG_TAG, "-> onFolioReaderClosed"); + } } \ No newline at end of file From 857926c3d778a3a6833d4248bc40ff3b69349b3b Mon Sep 17 00:00:00 2001 From: Hrishikesh Kadam Date: Fri, 31 Aug 2018 18:29:01 +0530 Subject: [PATCH 5/6] Add edge case for close API with minimal code FolioReader/FolioReader-Android#251 --- .../ui/folio/activity/FolioActivity.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/folioreader/src/main/java/com/folioreader/ui/folio/activity/FolioActivity.java b/folioreader/src/main/java/com/folioreader/ui/folio/activity/FolioActivity.java index c731170da..912c4a6d6 100644 --- a/folioreader/src/main/java/com/folioreader/ui/folio/activity/FolioActivity.java +++ b/folioreader/src/main/java/com/folioreader/ui/folio/activity/FolioActivity.java @@ -17,6 +17,7 @@ import android.Manifest; import android.app.Activity; +import android.app.ActivityManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -138,6 +139,7 @@ public enum EpubSourceType { private SearchItem searchItem; private float density; private Boolean topActivity; + private int taskImportance; private enum RequestCode { CONTENT_HIGHLIGHT(77), @@ -157,6 +159,17 @@ public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action != null && action.equals(FolioReader.ACTION_CLOSE_FOLIOREADER)) { + + try { + ActivityManager activityManager = (ActivityManager) + context.getSystemService(Context.ACTIVITY_SERVICE); + List tasks = + activityManager.getRunningAppProcesses(); + taskImportance = tasks.get(0).importance; + } catch (Exception e) { + Log.e(LOG_TAG, "-> ", e); + } + Intent closeIntent = new Intent(getApplicationContext(), FolioActivity.class); closeIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); closeIntent.setAction(FolioReader.ACTION_CLOSE_FOLIOREADER); @@ -173,10 +186,23 @@ protected void onNewIntent(Intent intent) { String action = getIntent().getAction(); if (action != null && action.equals(FolioReader.ACTION_CLOSE_FOLIOREADER)) { + if (topActivity == null || !topActivity) { // FolioActivity was already left, so no need to broadcast ReadPosition again. // Finish activity without going through onPause() and onStop() finish(); + + // To determine if app in background or foreground + boolean appInBackground = false; + if (Build.VERSION.SDK_INT < 26) { + if (ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND == taskImportance) + appInBackground = true; + } else { + if (ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED == taskImportance) + appInBackground = true; + } + if (appInBackground) + moveTaskToBack(true); } } } From ee1ae077969591823121ac3bb655bf62ab981cf7 Mon Sep 17 00:00:00 2001 From: Hrishikesh Kadam Date: Fri, 31 Aug 2018 19:44:19 +0530 Subject: [PATCH 6/6] Prepare v0.4.2 --- README.md | 2 +- build.gradle | 4 +++- folioreader/build.gradle | 2 +- .../java/com/folioreader/ui/folio/activity/FolioActivity.java | 1 + sample/build.gradle | 2 +- 5 files changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f3be5d31a..54cc7f904 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ repositories { } dependencies { - implementation 'com.folioreader:folioreader:0.4.1' + implementation 'com.folioreader:folioreader:0.4.2' } ``` diff --git a/build.gradle b/build.gradle index ce0c90d0b..3e8c21376 100644 --- a/build.gradle +++ b/build.gradle @@ -29,7 +29,7 @@ allprojects { } ext { - LIBRARY_VERSION = '0.4.1' + LIBRARY_VERSION = '0.4.2' R2_STREAMER_VERSION = '0.1.8' VERSION_NAME = "1.0" @@ -39,6 +39,8 @@ ext { ANDROID_COMPILE_SDK_VERSION = 28 ANDROID_TARGET_SDK_VERSION = 28 ANDROID_LIB_VERSION = '28.0.0-rc01' + + CONSTRAINT_LAYOUT_VERSION = "1.1.2" } task clean(type: Delete) { diff --git a/folioreader/build.gradle b/folioreader/build.gradle index 65eedf8e9..7b2ba0736 100644 --- a/folioreader/build.gradle +++ b/folioreader/build.gradle @@ -90,7 +90,7 @@ dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') implementation project(':webViewMarker') - implementation 'com.android.support.constraint:constraint-layout:1.1.2' + implementation "com.android.support.constraint:constraint-layout:$CONSTRAINT_LAYOUT_VERSION" implementation "com.android.support:appcompat-v7:$ANDROID_LIB_VERSION" implementation "com.android.support:recyclerview-v7:$ANDROID_LIB_VERSION" implementation "com.android.support:support-v4:$ANDROID_LIB_VERSION" diff --git a/folioreader/src/main/java/com/folioreader/ui/folio/activity/FolioActivity.java b/folioreader/src/main/java/com/folioreader/ui/folio/activity/FolioActivity.java index 912c4a6d6..fa771639c 100644 --- a/folioreader/src/main/java/com/folioreader/ui/folio/activity/FolioActivity.java +++ b/folioreader/src/main/java/com/folioreader/ui/folio/activity/FolioActivity.java @@ -178,6 +178,7 @@ public void onReceive(Context context, Intent intent) { } }; + @SuppressWarnings("PMD.CollapsibleIfStatements") @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); diff --git a/sample/build.gradle b/sample/build.gradle index cad555547..1a6b9f54c 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -61,7 +61,7 @@ repositories { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "com.android.support:appcompat-v7:$ANDROID_LIB_VERSION" - implementation 'com.android.support.constraint:constraint-layout:1.1.2' + implementation "com.android.support.constraint:constraint-layout:$CONSTRAINT_LAYOUT_VERSION" testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'