diff --git a/build.gradle b/build.gradle index 143e57b76..2e1198a78 100644 --- a/build.gradle +++ b/build.gradle @@ -4,8 +4,13 @@ buildscript { apply from: 'versions.gradle' repositories { + maven { + url = uri("https://repo.grails.org/grails/core") + } + maven { url "https://jitpack.io" } + mavenCentral() google() - jcenter() + //jcenter() } dependencies { @@ -29,10 +34,10 @@ allprojects { } repositories { - mavenLocal() - google() - jcenter() maven { url "https://jitpack.io" } + mavenCentral() // Replaced jcenter with mavenCentral + google() + mavenLocal() } } diff --git a/folioreader/AndroidManifest.xml b/folioreader/AndroidManifest.xml index 96e7be6ee..79ffeb4b7 100644 --- a/folioreader/AndroidManifest.xml +++ b/folioreader/AndroidManifest.xml @@ -3,7 +3,7 @@ xmlns:tools="http://schemas.android.com/tools" package="com.folioreader"> - + @@ -21,14 +21,17 @@ @@ -40,4 +43,4 @@ - \ No newline at end of file + diff --git a/folioreader/build.gradle b/folioreader/build.gradle index f41712cc4..74bc3f9e1 100644 --- a/folioreader/build.gradle +++ b/folioreader/build.gradle @@ -104,11 +104,15 @@ dependencies { implementation "com.squareup.retrofit2:converter-jackson:$versions.retrofit" implementation "com.squareup.retrofit2:converter-gson:$versions.retrofit" + + implementation("com.github.kittinunf.fuel:fuel:2.2.3") + implementation("com.github.kittinunf.fuel:fuel-android:2.2.3") + // R2 modules - api("com.github.codetoart:r2-shared-kotlin:$versions.r2SharedKotlin") { + implementation("com.github.codetoart:r2-shared-kotlin:$versions.r2SharedKotlin") { changing = true } - api("com.github.codetoart:r2-streamer-kotlin:$versions.r2StreamerKotlin") { + implementation("com.github.codetoart:r2-streamer-kotlin:$versions.r2StreamerKotlin") { exclude group: "org.slf4j", module: "slf4j-api" changing = true } @@ -119,4 +123,6 @@ dependencies { // Lifecycle implementation "androidx.lifecycle:lifecycle-extensions:$versions.lifecycle" } + + apply from: '../folioreader/bintray/bintrayv1.gradle' diff --git a/folioreader/res/layout/progress_dialog.xml b/folioreader/res/layout/progress_dialog.xml index 0d823fe0e..0ea2bf2fc 100644 --- a/folioreader/res/layout/progress_dialog.xml +++ b/folioreader/res/layout/progress_dialog.xml @@ -14,7 +14,7 @@ android:id="@+id/loading" android:layout_width="wrap_content" android:layout_height="wrap_content" - style="?android:attr/android:progressBarStyle" /> + /> - \ No newline at end of file + diff --git a/folioreader/src/main/java/com/folioreader/Config.java b/folioreader/src/main/java/com/folioreader/Config.java index c947b69b9..9e4106982 100644 --- a/folioreader/src/main/java/com/folioreader/Config.java +++ b/folioreader/src/main/java/com/folioreader/Config.java @@ -23,6 +23,7 @@ public class Config implements Parcelable { public static final String CONFIG_IS_NIGHT_MODE = "is_night_mode"; public static final String CONFIG_THEME_COLOR_INT = "theme_color_int"; public static final String CONFIG_IS_TTS = "is_tts"; + public static final String CONFIG_IS_SEARCH = "is_search"; public static final String CONFIG_ALLOWED_DIRECTION = "allowed_direction"; public static final String CONFIG_DIRECTION = "direction"; private static final AllowedDirection DEFAULT_ALLOWED_DIRECTION = AllowedDirection.ONLY_VERTICAL; @@ -38,6 +39,7 @@ public class Config implements Parcelable { private boolean showTts = true; private AllowedDirection allowedDirection = DEFAULT_ALLOWED_DIRECTION; private Direction direction = DEFAULT_DIRECTION; + private boolean showSearch = true; /** * Reading modes available @@ -77,6 +79,7 @@ public void writeToParcel(Parcel dest, int flags) { dest.writeByte((byte) (nightMode ? 1 : 0)); dest.writeInt(themeColor); dest.writeByte((byte) (showTts ? 1 : 0)); + dest.writeByte((byte) (showSearch ? 1 : 0)); dest.writeString(allowedDirection.toString()); dest.writeString(direction.toString()); } @@ -87,6 +90,7 @@ protected Config(Parcel in) { nightMode = in.readByte() != 0; themeColor = in.readInt(); showTts = in.readByte() != 0; + showSearch = in.readByte() != 0; allowedDirection = getAllowedDirectionFromString(LOG_TAG, in.readString()); direction = getDirectionFromString(LOG_TAG, in.readString()); } @@ -100,6 +104,7 @@ public Config(JSONObject jsonObject) { nightMode = jsonObject.optBoolean(CONFIG_IS_NIGHT_MODE); themeColor = getValidColorInt(jsonObject.optInt(CONFIG_THEME_COLOR_INT)); showTts = jsonObject.optBoolean(CONFIG_IS_TTS); + showSearch = jsonObject.optBoolean(CONFIG_IS_SEARCH); allowedDirection = getAllowedDirectionFromString(LOG_TAG, jsonObject.optString(CONFIG_ALLOWED_DIRECTION)); direction = getDirectionFromString(LOG_TAG, jsonObject.optString(CONFIG_DIRECTION)); @@ -205,6 +210,14 @@ public Config setShowTts(boolean showTts) { return this; } + public boolean isShowSearch() { + return showSearch; + } + + public void setShowSearch(boolean showSearch) { + this.showSearch = showSearch; + } + public AllowedDirection getAllowedDirection() { return allowedDirection; } @@ -288,10 +301,9 @@ public String toString() { ", nightMode=" + nightMode + ", themeColor=" + themeColor + ", showTts=" + showTts + + ", showSearch=" + showSearch + ", allowedDirection=" + allowedDirection + ", direction=" + direction + '}'; } } - - diff --git a/folioreader/src/main/java/com/folioreader/Constants.java b/folioreader/src/main/java/com/folioreader/Constants.java index d48df8e0d..082d1e52a 100644 --- a/folioreader/src/main/java/com/folioreader/Constants.java +++ b/folioreader/src/main/java/com/folioreader/Constants.java @@ -30,6 +30,7 @@ public class Constants { public static final int WRITE_EXTERNAL_STORAGE_REQUEST = 102; public static final String CHAPTER_ID = "id"; public static final String HREF = "href"; + public static final String LAST_READ_LOCATOR = "com.folioreader.model.locators.last_read_locator"; public static String[] getWriteExternalStoragePerms() { return new String[]{ diff --git a/folioreader/src/main/java/com/folioreader/FolioReader.java b/folioreader/src/main/java/com/folioreader/FolioReader.java index d02a16d90..cda98a4fa 100644 --- a/folioreader/src/main/java/com/folioreader/FolioReader.java +++ b/folioreader/src/main/java/com/folioreader/FolioReader.java @@ -6,8 +6,12 @@ import android.content.Intent; import android.content.IntentFilter; import android.os.Parcelable; + +import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.RawRes; import androidx.localbroadcastmanager.content.LocalBroadcastManager; + import com.folioreader.model.HighLight; import com.folioreader.model.HighlightImpl; import com.folioreader.model.locators.ReadLocator; @@ -17,16 +21,18 @@ import com.folioreader.ui.activity.FolioActivity; import com.folioreader.ui.base.OnSaveHighlight; import com.folioreader.ui.base.SaveReceivedHighlightTask; +import com.folioreader.util.DefaultReadLocatorManager; import com.folioreader.util.OnHighlightListener; import com.folioreader.util.ReadLocatorListener; + +import java.util.List; +import java.util.concurrent.TimeUnit; + import okhttp3.OkHttpClient; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; import retrofit2.converter.jackson.JacksonConverterFactory; -import java.util.List; -import java.util.concurrent.TimeUnit; - /** * Created by avez raj on 9/13/2017. */ @@ -121,41 +127,62 @@ private FolioReader(Context context) { DbAdapter.initialize(context); LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context); - localBroadcastManager.registerReceiver(highlightReceiver, - new IntentFilter(HighlightImpl.BROADCAST_EVENT)); - localBroadcastManager.registerReceiver(readLocatorReceiver, - new IntentFilter(ACTION_SAVE_READ_LOCATOR)); - localBroadcastManager.registerReceiver(closedReceiver, - new IntentFilter(ACTION_FOLIOREADER_CLOSED)); + localBroadcastManager.registerReceiver( + highlightReceiver, + new IntentFilter(HighlightImpl.BROADCAST_EVENT) + ); + localBroadcastManager.registerReceiver( + readLocatorReceiver, + new IntentFilter(ACTION_SAVE_READ_LOCATOR) + ); + localBroadcastManager.registerReceiver( + closedReceiver, + new IntentFilter(ACTION_FOLIOREADER_CLOSED) + ); + } + + public FolioReader openBook(String deviceStoragePath, boolean isInternalStorage) { + Intent intent = getIntentFromUrl(deviceStoragePath, 0, isInternalStorage); + context.startActivity(intent); + return singleton; } - public FolioReader openBook(String assetOrSdcardPath) { - Intent intent = getIntentFromUrl(assetOrSdcardPath, 0); + public FolioReader openBook(String assetPath) { + Intent intent = getIntentFromUrl(assetPath, 0, true); context.startActivity(intent); return singleton; } - public FolioReader openBook(int rawId) { - Intent intent = getIntentFromUrl(null, rawId); + public FolioReader openBook(@RawRes int rawId) { + Intent intent = getIntentFromUrl(null, rawId, true); context.startActivity(intent); return singleton; } - public FolioReader openBook(String assetOrSdcardPath, String bookId) { - Intent intent = getIntentFromUrl(assetOrSdcardPath, 0); + public FolioReader openBook(String assetPath, String bookId) { + Intent intent = getIntentFromUrl(assetPath, 0, true); intent.putExtra(EXTRA_BOOK_ID, bookId); context.startActivity(intent); return singleton; } + + public FolioReader openBook(String deviceStoragePath, boolean isInternalStorage, String bookId) { + Intent intent = getIntentFromUrl(deviceStoragePath, 0, isInternalStorage); + intent.putExtra(EXTRA_BOOK_ID, bookId); + context.startActivity(intent); + return singleton; + } + + public FolioReader openBook(int rawId, String bookId) { - Intent intent = getIntentFromUrl(null, rawId); + Intent intent = getIntentFromUrl(null, rawId, true); intent.putExtra(EXTRA_BOOK_ID, bookId); context.startActivity(intent); return singleton; } - private Intent getIntentFromUrl(String assetOrSdcardPath, int rawId) { + private Intent getIntentFromUrl(String path, int rawId, boolean isInternalStorage) { Intent intent = new Intent(context, FolioActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); @@ -166,18 +193,27 @@ private Intent getIntentFromUrl(String assetOrSdcardPath, int rawId) { if (rawId != 0) { intent.putExtra(FolioActivity.INTENT_EPUB_SOURCE_PATH, rawId); - intent.putExtra(FolioActivity.INTENT_EPUB_SOURCE_TYPE, - FolioActivity.EpubSourceType.RAW); - } else if (assetOrSdcardPath.contains(Constants.ASSET)) { - intent.putExtra(FolioActivity.INTENT_EPUB_SOURCE_PATH, assetOrSdcardPath); - intent.putExtra(FolioActivity.INTENT_EPUB_SOURCE_TYPE, - FolioActivity.EpubSourceType.ASSETS); + intent.putExtra( + FolioActivity.INTENT_EPUB_SOURCE_TYPE, + FolioActivity.EpubSourceType.RAW + ); + } else if (path.contains(Constants.ASSET)) { + intent.putExtra(FolioActivity.INTENT_EPUB_SOURCE_PATH, path); + intent.putExtra( + FolioActivity.INTENT_EPUB_SOURCE_TYPE, + FolioActivity.EpubSourceType.ASSETS + ); } else { - intent.putExtra(FolioActivity.INTENT_EPUB_SOURCE_PATH, assetOrSdcardPath); - intent.putExtra(FolioActivity.INTENT_EPUB_SOURCE_TYPE, - FolioActivity.EpubSourceType.SD_CARD); + intent.putExtra(FolioActivity.INTENT_EPUB_SOURCE_PATH, path); + intent.putExtra( + FolioActivity.INTENT_EPUB_SOURCE_TYPE, + FolioActivity.EpubSourceType.DEVICE_STORAGE + ); } + intent.putExtra(FolioActivity.INTENT_EPUB_SOURCE_STORAGE_TYPE, isInternalStorage); + + return intent; } @@ -215,7 +251,8 @@ public static void initRetrofit(String streamerUrl) { .baseUrl(streamerUrl) .addConverterFactory(new QualifiedTypeConverterFactory( JacksonConverterFactory.create(), - GsonConverterFactory.create())) + GsonConverterFactory.create() + )) .client(client) .build(); @@ -232,6 +269,14 @@ public FolioReader setReadLocatorListener(ReadLocatorListener readLocatorListene return singleton; } + + public FolioReader defaultReadLocator(@NonNull final Context context) { + DefaultReadLocatorManager defaultReadLocatorManager = new DefaultReadLocatorManager(context); + setReadLocatorListener(defaultReadLocatorManager); + setReadLocator(defaultReadLocatorManager.getLastReadLocator()); + return singleton; + } + public FolioReader setOnClosedListener(OnClosedListener onClosedListener) { this.onClosedListener = onClosedListener; return singleton; diff --git a/folioreader/src/main/java/com/folioreader/mediaoverlay/MediaController.java b/folioreader/src/main/java/com/folioreader/mediaoverlay/MediaController.java index be9d2ee90..8a8ace3f6 100644 --- a/folioreader/src/main/java/com/folioreader/mediaoverlay/MediaController.java +++ b/folioreader/src/main/java/com/folioreader/mediaoverlay/MediaController.java @@ -104,25 +104,27 @@ public void setTextToSpeech(final Context context) { mTextToSpeech = new TextToSpeech(context, new TextToSpeech.OnInitListener() { @Override public void onInit(int status) { - if (status != TextToSpeech.ERROR) { - mTextToSpeech.setLanguage(Locale.UK); - mTextToSpeech.setSpeechRate(0.70f); - } + if (mTextToSpeech != null) { + if (status != TextToSpeech.ERROR) { + mTextToSpeech.setLanguage(Locale.UK); + mTextToSpeech.setSpeechRate(0.70f); + } - mTextToSpeech.setOnUtteranceCompletedListener( - new TextToSpeech.OnUtteranceCompletedListener() { - @Override - public void onUtteranceCompleted(String utteranceId) { - ((AppCompatActivity) context).runOnUiThread(new Runnable() { - @Override - public void run() { - if (mIsSpeaking) { - callbacks.highLightTTS(); + mTextToSpeech.setOnUtteranceCompletedListener( + new TextToSpeech.OnUtteranceCompletedListener() { + @Override + public void onUtteranceCompleted(String utteranceId) { + ((AppCompatActivity) context).runOnUiThread(new Runnable() { + @Override + public void run() { + if (mIsSpeaking) { + callbacks.highLightTTS(); + } } - } - }); - } - }); + }); + } + }); + } } }); } diff --git a/folioreader/src/main/java/com/folioreader/model/locators/ReadLocator.kt b/folioreader/src/main/java/com/folioreader/model/locators/ReadLocator.kt index 97ce9bb45..0865aaf26 100644 --- a/folioreader/src/main/java/com/folioreader/model/locators/ReadLocator.kt +++ b/folioreader/src/main/java/com/folioreader/model/locators/ReadLocator.kt @@ -40,7 +40,7 @@ open class ReadLocator : Locator, Parcelable { parcel.readSerializable() as LocatorText? ) - override fun writeToParcel(dest: Parcel?, flags: Int) { + override fun writeToParcel(dest: Parcel, flags: Int) { dest?.writeString(bookId) dest?.writeString(href) dest?.writeLong(created) @@ -94,4 +94,4 @@ open class ReadLocator : Locator, Parcelable { null } } -} \ No newline at end of file +} diff --git a/folioreader/src/main/java/com/folioreader/model/sqlite/DbAdapter.java b/folioreader/src/main/java/com/folioreader/model/sqlite/DbAdapter.java index 869541dd9..f7096500f 100644 --- a/folioreader/src/main/java/com/folioreader/model/sqlite/DbAdapter.java +++ b/folioreader/src/main/java/com/folioreader/model/sqlite/DbAdapter.java @@ -6,6 +6,8 @@ import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; +import androidx.annotation.Nullable; + public class DbAdapter { private static final String TAG = "DBAdapter"; @@ -80,7 +82,11 @@ public static boolean updateHighLight(ContentValues highlightContentValues, Stri return mDatabase.update(HighLightTable.TABLE_NAME, highlightContentValues, HighLightTable.ID + " = " + id, null) > 0; } + @Nullable public static Cursor getHighlightsForPageId(String query, String pageId) { + if (mDatabase == null) { + return null; + } return mDatabase.rawQuery(query, null); } diff --git a/folioreader/src/main/java/com/folioreader/model/sqlite/HighLightTable.java b/folioreader/src/main/java/com/folioreader/model/sqlite/HighLightTable.java index 29a4462fc..52985f3bb 100644 --- a/folioreader/src/main/java/com/folioreader/model/sqlite/HighLightTable.java +++ b/folioreader/src/main/java/com/folioreader/model/sqlite/HighLightTable.java @@ -4,13 +4,20 @@ import android.database.Cursor; import android.text.TextUtils; import android.util.Log; + import com.folioreader.Constants; import com.folioreader.model.HighLight; import com.folioreader.model.HighlightImpl; +import org.jetbrains.annotations.NotNull; + import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.*; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Locale; +import java.util.UUID; @SuppressWarnings("PMD.AvoidDuplicateLiterals") public class HighLightTable { @@ -110,14 +117,20 @@ public static boolean deleteHighlight(int highlightId) { return DbAdapter.deleteById(TABLE_NAME, ID, String.valueOf(highlightId)); } + @NotNull public static List getHighlightsForPageId(String pageId) { String query = "SELECT " + COL_RANGY + " FROM " + TABLE_NAME + " WHERE " + COL_PAGE_ID + " = \"" + pageId + "\""; Cursor c = DbAdapter.getHighlightsForPageId(query, pageId); List rangyList = new ArrayList<>(); - while (c.moveToNext()) { - rangyList.add(c.getString(c.getColumnIndex(COL_RANGY))); + if (c != null) { + while (c.moveToNext()) { + int index = c.getColumnIndex(COL_RANGY); + if (index >= 0) { + rangyList.add(c.getString(index)); + } + } + c.close(); } - c.close(); return rangyList; } @@ -190,6 +203,3 @@ public static void saveHighlightIfNotExists(HighLight highLight) { } } } - - - diff --git a/folioreader/src/main/java/com/folioreader/ui/activity/FolioActivity.kt b/folioreader/src/main/java/com/folioreader/ui/activity/FolioActivity.kt index 8df26fbe8..5d622a378 100644 --- a/folioreader/src/main/java/com/folioreader/ui/activity/FolioActivity.kt +++ b/folioreader/src/main/java/com/folioreader/ui/activity/FolioActivity.kt @@ -15,20 +15,19 @@ */ package com.folioreader.ui.activity -import android.Manifest import android.app.Activity import android.app.ActivityManager import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.content.IntentFilter -import android.content.pm.PackageManager import android.graphics.Rect import android.graphics.drawable.ColorDrawable import android.net.Uri import android.os.Build import android.os.Bundle import android.os.Handler +import android.os.Looper import android.text.TextUtils import android.util.DisplayMetrics import android.util.Log @@ -36,12 +35,10 @@ import android.view.Menu import android.view.MenuItem import android.view.View import android.view.WindowManager -import android.widget.Toast import androidx.appcompat.app.ActionBar import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.widget.Toolbar -import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat import androidx.localbroadcastmanager.content.LocalBroadcastManager import com.folioreader.Config @@ -99,11 +96,12 @@ class FolioActivity : AppCompatActivity(), FolioActivityCallback, MediaControlle private var mBookId: String? = null private var mEpubFilePath: String? = null + private var mIsInternalStorage: Boolean? = null private var mEpubSourceType: EpubSourceType? = null private var mEpubRawId = 0 private var mediaControllerFragment: MediaControllerFragment? = null private var direction: Config.Direction = Config.Direction.VERTICAL - private var portNumber: Int = Constants.DEFAULT_PORT_NUMBER + private var portNumber: Int = DEFAULT_PORT_NUMBER private var streamerUri: Uri? = null private var searchUri: Uri? = null @@ -122,6 +120,7 @@ class FolioActivity : AppCompatActivity(), FolioActivityCallback, MediaControlle val LOG_TAG: String = FolioActivity::class.java.simpleName const val INTENT_EPUB_SOURCE_PATH = "com.folioreader.epub_asset_path" + const val INTENT_EPUB_SOURCE_STORAGE_TYPE = "intent.epub.source.storage.type" const val INTENT_EPUB_SOURCE_TYPE = "epub_source_type" const val EXTRA_READ_LOCATOR = "com.folioreader.extra.READ_LOCATOR" private const val BUNDLE_READ_LOCATOR_CONFIG_CHANGE = "BUNDLE_READ_LOCATOR_CONFIG_CHANGE" @@ -139,7 +138,8 @@ class FolioActivity : AppCompatActivity(), FolioActivityCallback, MediaControlle if (action != null && action == FolioReader.ACTION_CLOSE_FOLIOREADER) { try { - val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager + val activityManager = + context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager val tasks = activityManager.runningAppProcesses taskImportance = tasks[0].importance } catch (e: Exception) { @@ -147,7 +147,8 @@ class FolioActivity : AppCompatActivity(), FolioActivityCallback, MediaControlle } val closeIntent = Intent(applicationContext, FolioActivity::class.java) - closeIntent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP + closeIntent.flags = + Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP closeIntent.action = FolioReader.ACTION_CLOSE_FOLIOREADER this@FolioActivity.startActivity(closeIntent) } @@ -185,7 +186,7 @@ class FolioActivity : AppCompatActivity(), FolioActivityCallback, MediaControlle enum class EpubSourceType { RAW, ASSETS, - SD_CARD + DEVICE_STORAGE } private enum class RequestCode private constructor(internal val value: Int) { @@ -193,59 +194,13 @@ class FolioActivity : AppCompatActivity(), FolioActivityCallback, MediaControlle SEARCH(101) } - override fun onNewIntent(intent: Intent) { - super.onNewIntent(intent) - setIntent(intent) - Log.v(LOG_TAG, "-> onNewIntent") - - val action = getIntent().action - if (action != null && action == FolioReader.ACTION_CLOSE_FOLIOREADER) { - - if (topActivity == null || topActivity == false) { - // FolioActivity was already left, so no need to broadcast ReadLocator again. - // Finish activity without going through onPause() and onStop() - finish() - - // To determine if app in background or foreground - var 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) - } - } - } - - override fun onResume() { - super.onResume() - Log.v(LOG_TAG, "-> onResume") - topActivity = true - - val action = intent.action - if (action != null && action == FolioReader.ACTION_CLOSE_FOLIOREADER) { - // FolioActivity is topActivity, so need to broadcast ReadLocator. - finish() - } - } - - override fun onStop() { - super.onStop() - Log.v(LOG_TAG, "-> onStop") - topActivity = false - } - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Need to add when vector drawables support library is used. AppCompatDelegate.setCompatVectorFromResourcesEnabled(true) - handler = Handler() + handler = Handler(Looper.getMainLooper()) val display = windowManager.defaultDisplay displayMetrics = resources.displayMetrics display.getRealMetrics(displayMetrics) @@ -267,11 +222,70 @@ class FolioActivity : AppCompatActivity(), FolioActivityCallback, MediaControlle if (savedInstanceState != null) { searchAdapterDataBundle = savedInstanceState.getBundle(SearchAdapter.DATA_BUNDLE) - searchQuery = savedInstanceState.getCharSequence(SearchActivity.BUNDLE_SAVE_SEARCH_QUERY) + searchQuery = + savedInstanceState.getCharSequence(SearchActivity.BUNDLE_SAVE_SEARCH_QUERY) + } + + getIntentExtrasAndAssignFields() + + initActionBar() + initMediaController() + + setupBook() + } + + + override fun onResume() { + super.onResume() + Log.v(LOG_TAG, "-> onResume") + topActivity = true + + val action = intent.action + if (action != null && action == FolioReader.ACTION_CLOSE_FOLIOREADER) { + // FolioActivity is topActivity, so need to broadcast ReadLocator. + finish() + } + } + + override fun onStop() { + super.onStop() + Log.v(LOG_TAG, "-> onStop") + topActivity = false + } + + override fun onNewIntent(intent: Intent) { + super.onNewIntent(intent) + setIntent(intent) + Log.v(LOG_TAG, "-> onNewIntent") + + val action = getIntent().action + if (action != null && action == FolioReader.ACTION_CLOSE_FOLIOREADER) { + + if (topActivity == null || topActivity == false) { + // FolioActivity was already left, so no need to broadcast ReadLocator again. + // Finish activity without going through onPause() and onStop() + finish() + + // To determine if app in background or foreground + var 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) + } } + } + + private fun getIntentExtrasAndAssignFields() { mBookId = intent.getStringExtra(FolioReader.EXTRA_BOOK_ID) - mEpubSourceType = intent.extras!!.getSerializable(FolioActivity.INTENT_EPUB_SOURCE_TYPE) as EpubSourceType + mEpubSourceType = + intent.extras!!.getSerializable(FolioActivity.INTENT_EPUB_SOURCE_TYPE) as EpubSourceType if (mEpubSourceType == EpubSourceType.RAW) { mEpubRawId = intent.extras!!.getInt(FolioActivity.INTENT_EPUB_SOURCE_PATH) } else { @@ -279,22 +293,7 @@ class FolioActivity : AppCompatActivity(), FolioActivityCallback, MediaControlle .getString(FolioActivity.INTENT_EPUB_SOURCE_PATH) } - initActionBar() - initMediaController() - - if (ContextCompat.checkSelfPermission( - this@FolioActivity, - Manifest.permission.WRITE_EXTERNAL_STORAGE - ) != PackageManager.PERMISSION_GRANTED - ) { - ActivityCompat.requestPermissions( - this@FolioActivity, - Constants.getWriteExternalStoragePerms(), - Constants.WRITE_EXTERNAL_STORAGE_REQUEST - ) - } else { - setupBook() - } + mIsInternalStorage = intent.extras!!.getBoolean(INTENT_EPUB_SOURCE_STORAGE_TYPE, true) } private fun initActionBar() { @@ -366,8 +365,13 @@ class FolioActivity : AppCompatActivity(), FolioActivityCallback, MediaControlle UiUtil.setColorIntToDrawable(config.themeColor, menu.findItem(R.id.itemConfig).icon) UiUtil.setColorIntToDrawable(config.themeColor, menu.findItem(R.id.itemTts).icon) - if (!config.isShowTts) + if (!config.isShowTts) { menu.findItem(R.id.itemTts).isVisible = false + } + + if (!config.isShowSearch) { + menu.findItem(R.id.itemSearch).isVisible = false + } return true } @@ -459,8 +463,11 @@ class FolioActivity : AppCompatActivity(), FolioActivityCallback, MediaControlle bookFileName = FileUtil.getEpubFilename(this, mEpubSourceType!!, mEpubFilePath, mEpubRawId) val path = FileUtil.saveEpubFileAndLoadLazyBook( - this, mEpubSourceType, mEpubFilePath, - mEpubRawId, bookFileName + this, + mEpubSourceType, + mEpubFilePath, + mEpubRawId, + bookFileName ) val extension: Publication.EXTENSION var extensionString: String? = null @@ -480,18 +487,18 @@ class FolioActivity : AppCompatActivity(), FolioActivityCallback, MediaControlle val cbzParser = CbzParser() cbzParser.parse(path!!, "") } - else -> { - null - } + else -> null } - portNumber = intent.getIntExtra(FolioReader.EXTRA_PORT_NUMBER, Constants.DEFAULT_PORT_NUMBER) + portNumber = intent.getIntExtra(FolioReader.EXTRA_PORT_NUMBER, DEFAULT_PORT_NUMBER) portNumber = AppUtil.getAvailablePortNumber(portNumber) r2StreamerServer = Server(portNumber) r2StreamerServer!!.addEpub( - pubBox!!.publication, pubBox!!.container, - "/" + bookFileName!!, null + pubBox!!.publication, + pubBox!!.container, + "/" + bookFileName!!, + null ) r2StreamerServer!!.start() @@ -501,6 +508,7 @@ class FolioActivity : AppCompatActivity(), FolioActivityCallback, MediaControlle private fun onBookInitFailure() { //TODO -> Fail gracefully + finish() } private fun onBookInitSuccess() { @@ -510,13 +518,13 @@ class FolioActivity : AppCompatActivity(), FolioActivityCallback, MediaControlle title = publication.metadata.title if (mBookId == null) { - if (!publication.metadata.identifier.isEmpty()) { - mBookId = publication.metadata.identifier + mBookId = if (publication.metadata.identifier.isNotEmpty()) { + publication.metadata.identifier } else { - if (!publication.metadata.title.isEmpty()) { - mBookId = publication.metadata.title.hashCode().toString() + if (publication.metadata.title.isNotEmpty()) { + publication.metadata.title.hashCode().toString() } else { - mBookId = bookFileName!!.hashCode().toString() + bookFileName!!.hashCode().toString() } } } @@ -538,7 +546,8 @@ class FolioActivity : AppCompatActivity(), FolioActivityCallback, MediaControlle override fun getStreamerUrl(): String { if (streamerUri == null) { - streamerUri = Uri.parse(String.format(STREAMER_URL_TEMPLATE, LOCALHOST, portNumber, bookFileName)) + streamerUri = + Uri.parse(String.format(STREAMER_URL_TEMPLATE, LOCALHOST, portNumber, bookFileName)) } return streamerUri.toString() } @@ -575,7 +584,8 @@ class FolioActivity : AppCompatActivity(), FolioActivityCallback, MediaControlle hideSystemUI() showSystemUI() - distractionFreeMode = savedInstanceState != null && savedInstanceState.getBoolean(BUNDLE_DISTRACTION_FREE_MODE) + distractionFreeMode = + savedInstanceState != null && savedInstanceState.getBoolean(BUNDLE_DISTRACTION_FREE_MODE) } override fun onPostCreate(savedInstanceState: Bundle?) { @@ -599,12 +609,12 @@ class FolioActivity : AppCompatActivity(), FolioActivityCallback, MediaControlle topDistraction += actionBar!!.height } - when (unit) { - DisplayUnit.PX -> return topDistraction + return when (unit) { + DisplayUnit.PX -> topDistraction DisplayUnit.DP -> { topDistraction /= density.toInt() - return topDistraction + topDistraction } else -> throw IllegalArgumentException("-> Illegal argument -> unit = $unit") @@ -624,12 +634,12 @@ class FolioActivity : AppCompatActivity(), FolioActivityCallback, MediaControlle if (!distractionFreeMode) bottomDistraction = appBarLayout!!.navigationBarHeight - when (unit) { - DisplayUnit.PX -> return bottomDistraction + return when (unit) { + DisplayUnit.PX -> bottomDistraction DisplayUnit.DP -> { bottomDistraction /= density.toInt() - return bottomDistraction + bottomDistraction } else -> throw IllegalArgumentException("-> Illegal argument -> unit = $unit") @@ -801,7 +811,7 @@ class FolioActivity : AppCompatActivity(), FolioActivityCallback, MediaControlle // In case if SearchActivity is recreated due to screen rotation then FolioActivity // will also be recreated, so mFolioPageViewPager might be null. if (mFolioPageViewPager == null) return - currentChapterIndex = getChapterIndex(Constants.HREF, searchLocator!!.href) + currentChapterIndex = getChapterIndex(HREF, searchLocator!!.href) mFolioPageViewPager!!.currentItem = currentChapterIndex val folioPageFragment = currentFragment ?: return folioPageFragment.highlightSearchLocator(searchLocator!!) @@ -815,16 +825,22 @@ class FolioActivity : AppCompatActivity(), FolioActivityCallback, MediaControlle val type = data.getStringExtra(TYPE) if (type == CHAPTER_SELECTED) { - goToChapter(data.getStringExtra(SELECTED_CHAPTER_POSITION)) + data.getStringExtra(SELECTED_CHAPTER_POSITION)?.let { + goToChapter(it) + } } else if (type == HIGHLIGHT_SELECTED) { val highlightImpl = data.getParcelableExtra(HIGHLIGHT_ITEM) - currentChapterIndex = highlightImpl.pageNumber + if (highlightImpl != null) { + currentChapterIndex = highlightImpl.pageNumber + } mFolioPageViewPager!!.currentItem = currentChapterIndex val folioPageFragment = currentFragment ?: return - folioPageFragment.scrollToHighlightId(highlightImpl.rangy) + highlightImpl?.let { folioPageFragment.scrollToHighlightId(it.rangy) } } } + + super.onActivityResult(requestCode, resultCode, data) } override fun onDestroy() { @@ -855,8 +871,14 @@ class FolioActivity : AppCompatActivity(), FolioActivityCallback, MediaControlle mFolioPageViewPager = findViewById(R.id.folioPageViewPager) // Replacing with addOnPageChangeListener(), onPageSelected() is not invoked - mFolioPageViewPager!!.setOnPageChangeListener(object : DirectionalViewpager.OnPageChangeListener { - override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {} + mFolioPageViewPager!!.setOnPageChangeListener(object : + DirectionalViewpager.OnPageChangeListener { + override fun onPageScrolled( + position: Int, + positionOffset: Float, + positionOffsetPixels: Int + ) { + } override fun onPageSelected(position: Int) { Log.v(LOG_TAG, "-> onPageSelected -> DirectionalViewpager -> position = $position") @@ -879,14 +901,16 @@ class FolioActivity : AppCompatActivity(), FolioActivityCallback, MediaControlle "position = " + position ) - var folioPageFragment = mFolioPageFragmentAdapter!!.getItem(position - 1) as FolioPageFragment? + var folioPageFragment = + mFolioPageFragmentAdapter!!.getItem(position - 1) as FolioPageFragment? if (folioPageFragment != null) { folioPageFragment.scrollToLast() if (folioPageFragment.mWebview != null) folioPageFragment.mWebview!!.dismissPopupWindow() } - folioPageFragment = mFolioPageFragmentAdapter!!.getItem(position + 1) as FolioPageFragment? + folioPageFragment = + mFolioPageFragmentAdapter!!.getItem(position + 1) as FolioPageFragment? if (folioPageFragment != null) { folioPageFragment.scrollToFirst() if (folioPageFragment.mWebview != null) @@ -907,7 +931,7 @@ class FolioActivity : AppCompatActivity(), FolioActivityCallback, MediaControlle // will also be recreated, so searchLocator is checked here. if (searchLocator != null) { - currentChapterIndex = getChapterIndex(Constants.HREF, searchLocator!!.href) + currentChapterIndex = getChapterIndex(HREF, searchLocator!!.href) mFolioPageViewPager!!.currentItem = currentChapterIndex val folioPageFragment = currentFragment ?: return folioPageFragment.highlightSearchLocator(searchLocator!!) @@ -938,7 +962,7 @@ class FolioActivity : AppCompatActivity(), FolioActivityCallback, MediaControlle if (readLocator == null) { return 0 } else if (!TextUtils.isEmpty(readLocator.href)) { - return getChapterIndex(Constants.HREF, readLocator.href) + return getChapterIndex(HREF, readLocator.href) } return 0 @@ -947,8 +971,9 @@ class FolioActivity : AppCompatActivity(), FolioActivityCallback, MediaControlle private fun getChapterIndex(caseString: String, value: String): Int { for (i in spine!!.indices) { when (caseString) { - Constants.HREF -> if (spine!![i].href == value) + HREF -> if (spine!![i].href == value) { return i + } } } return 0 @@ -984,28 +1009,17 @@ class FolioActivity : AppCompatActivity(), FolioActivityCallback, MediaControlle val overrideConfig = intent.getBooleanExtra(Config.EXTRA_OVERRIDE_CONFIG, false) val savedConfig = AppUtil.getSavedConfig(this) - if (savedInstanceState != null) { - config = savedConfig - - } else if (savedConfig == null) { - if (intentConfig == null) { - config = Config() - } else { - config = intentConfig - } - - } else { - if (intentConfig != null && overrideConfig) { - config = intentConfig - } else { - config = savedConfig - } + config = when { + savedInstanceState != null -> savedConfig + savedConfig == null -> intentConfig ?: Config() + else -> if (intentConfig != null && overrideConfig) intentConfig else savedConfig } // Code would never enter this if, just added for any unexpected error // and to avoid lint warning - if (config == null) + if (config == null) { config = Config() + } AppUtil.saveConfig(this, config) direction = config.direction @@ -1027,17 +1041,6 @@ class FolioActivity : AppCompatActivity(), FolioActivityCallback, MediaControlle ) } - override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { - when (requestCode) { - Constants.WRITE_EXTERNAL_STORAGE_REQUEST -> if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { - setupBook() - } else { - Toast.makeText(this, getString(R.string.cannot_access_epub_message), Toast.LENGTH_LONG).show() - finish() - } - } - } - override fun getDirection(): Config.Direction { return direction } @@ -1060,4 +1063,4 @@ class FolioActivity : AppCompatActivity(), FolioActivityCallback, MediaControlle } } } -} \ No newline at end of file +} diff --git a/folioreader/src/main/java/com/folioreader/ui/activity/FolioActivityCallback.java b/folioreader/src/main/java/com/folioreader/ui/activity/FolioActivityCallback.java index 502a54cfa..aa380f9ae 100644 --- a/folioreader/src/main/java/com/folioreader/ui/activity/FolioActivityCallback.java +++ b/folioreader/src/main/java/com/folioreader/ui/activity/FolioActivityCallback.java @@ -1,6 +1,7 @@ package com.folioreader.ui.activity; import android.graphics.Rect; + import com.folioreader.Config; import com.folioreader.model.DisplayUnit; import com.folioreader.model.locators.ReadLocator; diff --git a/folioreader/src/main/java/com/folioreader/ui/view/FolioWebView.kt b/folioreader/src/main/java/com/folioreader/ui/view/FolioWebView.kt index e6416d52f..7533edf89 100644 --- a/folioreader/src/main/java/com/folioreader/ui/view/FolioWebView.kt +++ b/folioreader/src/main/java/com/folioreader/ui/view/FolioWebView.kt @@ -11,8 +11,16 @@ import android.os.Looper import android.util.AttributeSet import android.util.DisplayMetrics import android.util.Log -import android.view.* +import android.view.ActionMode import android.view.ActionMode.Callback +import android.view.ContextThemeWrapper +import android.view.GestureDetector +import android.view.Gravity +import android.view.LayoutInflater +import android.view.Menu +import android.view.MenuItem +import android.view.MotionEvent +import android.view.View import android.view.ViewGroup.LayoutParams.WRAP_CONTENT import android.webkit.ConsoleMessage import android.webkit.JavascriptInterface @@ -20,7 +28,6 @@ import android.webkit.WebView import android.widget.PopupWindow import android.widget.Toast import androidx.annotation.RequiresApi -import androidx.core.content.ContextCompat import androidx.core.view.GestureDetectorCompat import com.folioreader.Config import com.folioreader.Constants @@ -156,13 +163,23 @@ class FolioWebView : WebView { private inner class HorizontalGestureListener : GestureDetector.SimpleOnGestureListener() { - override fun onScroll(e1: MotionEvent?, e2: MotionEvent?, distanceX: Float, distanceY: Float): Boolean { + override fun onScroll( + e1: MotionEvent, + e2: MotionEvent, + distanceX: Float, + distanceY: Float + ): Boolean { //Log.d(LOG_TAG, "-> onScroll -> e1 = " + e1 + ", e2 = " + e2 + ", distanceX = " + distanceX + ", distanceY = " + distanceY); lastScrollType = LastScrollType.USER return false } - override fun onFling(e1: MotionEvent?, e2: MotionEvent?, velocityX: Float, velocityY: Float): Boolean { + override fun onFling( + e1: MotionEvent, + e2: MotionEvent, + velocityX: Float, + velocityY: Float + ): Boolean { //Log.d(LOG_TAG, "-> onFling -> e1 = " + e1 + ", e2 = " + e2 + ", velocityX = " + velocityX + ", velocityY = " + velocityY); if (!webViewPager.isScrolling) { @@ -179,7 +196,7 @@ class FolioWebView : WebView { return true } - override fun onDown(event: MotionEvent?): Boolean { + override fun onDown(event: MotionEvent): Boolean { //Log.v(LOG_TAG, "-> onDown -> " + event.toString()); eventActionDown = MotionEvent.obtain(event) @@ -198,7 +215,7 @@ class FolioWebView : WebView { uiHandler.post { popupWindow.dismiss() } } selectionRect = Rect() - uiHandler.removeCallbacks(isScrollingRunnable) + isScrollingRunnable?.let { uiHandler.removeCallbacks(it) } isScrollingCheckDuration = 0 return wasShowing } @@ -212,13 +229,23 @@ class FolioWebView : WebView { private inner class VerticalGestureListener : GestureDetector.SimpleOnGestureListener() { - override fun onScroll(e1: MotionEvent?, e2: MotionEvent?, distanceX: Float, distanceY: Float): Boolean { + override fun onScroll( + e1: MotionEvent, + e2: MotionEvent, + distanceX: Float, + distanceY: Float + ): Boolean { //Log.v(LOG_TAG, "-> onScroll -> e1 = " + e1 + ", e2 = " + e2 + ", distanceX = " + distanceX + ", distanceY = " + distanceY); lastScrollType = LastScrollType.USER return false } - override fun onFling(e1: MotionEvent?, e2: MotionEvent?, velocityX: Float, velocityY: Float): Boolean { + override fun onFling( + e1: MotionEvent, + e2: MotionEvent, + velocityX: Float, + velocityY: Float + ): Boolean { //Log.v(LOG_TAG, "-> onFling -> e1 = " + e1 + ", e2 = " + e2 + ", velocityX = " + velocityX + ", velocityY = " + velocityY); lastScrollType = LastScrollType.USER return false @@ -227,7 +254,11 @@ class FolioWebView : WebView { constructor(context: Context) : super(context) constructor(context: Context, attrs: AttributeSet) : super(context, attrs) - constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super( + context, + attrs, + defStyleAttr + ) private fun init() { Log.v(LOG_TAG, "-> init") @@ -248,11 +279,11 @@ class FolioWebView : WebView { fun initViewTextSelection() { Log.v(LOG_TAG, "-> initViewTextSelection") - val textSelectionMiddleDrawable = ContextCompat.getDrawable( - context, - R.drawable.abc_text_select_handle_middle_mtrl_dark - ) - handleHeight = textSelectionMiddleDrawable?.intrinsicHeight ?: (24 * density).toInt() +// val textSelectionMiddleDrawable = ContextCompat.getDrawable( +// context, +// R.drawable.abc_text_select_handle_middle_mtrl_dark +// ) +// handleHeight = textSelectionMiddleDrawable?.intrinsicHeight ?: (24 * density).toInt() val config = AppUtil.getSavedConfig(context)!! val ctw = if (config.isNightMode) { @@ -315,7 +346,8 @@ class FolioWebView : WebView { R.id.copySelection -> { Log.v(LOG_TAG, "-> onTextSelectionItemClicked -> copySelection -> $selectedText") UiUtil.copyToClipboard(context, selectedText) - Toast.makeText(context, context.getString(R.string.copied), Toast.LENGTH_SHORT).show() + Toast.makeText(context, context.getString(R.string.copied), Toast.LENGTH_SHORT) + .show() } R.id.shareSelection -> { Log.v(LOG_TAG, "-> onTextSelectionItemClicked -> shareSelection -> $selectedText") @@ -336,7 +368,12 @@ class FolioWebView : WebView { val bundle = Bundle() bundle.putString(Constants.SELECTED_WORD, selectedText?.trim()) dictionaryFragment.arguments = bundle - dictionaryFragment.show(parentFragment.fragmentManager!!, DictionaryFragment::class.java.name) + parentFragment.fragmentManager?.let { + dictionaryFragment.show( + it, + DictionaryFragment::class.java.name + ) + } } private fun onHighlightColorItemsClicked(style: HighlightStyle, isAlreadyCreated: Boolean) { @@ -391,8 +428,9 @@ class FolioWebView : WebView { override fun onTouchEvent(event: MotionEvent?): Boolean { //Log.v(LOG_TAG, "-> onTouchEvent -> " + AppUtil.actionToString(event.getAction())); - if (event == null) + if (event == null) { return false + } lastTouchAction = event.action @@ -580,7 +618,8 @@ class FolioWebView : WebView { if (Build.VERSION.SDK_INT < 23) { val folioActivityRef: WeakReference = folioActivityCallback.activity - val mWindowManagerField = ReflectionUtils.findField(FolioActivity::class.java, "mWindowManager") + val mWindowManagerField = + ReflectionUtils.findField(FolioActivity::class.java, "mWindowManager") mWindowManagerField.isAccessible = true val mWindowManager = mWindowManagerField.get(folioActivityRef.get()) @@ -596,7 +635,8 @@ class FolioWebView : WebView { val config = AppUtil.getSavedConfig(context)!! for (view in mViews) { - val handleViewClass = Class.forName("com.android.org.chromium.content.browser.input.HandleView") + val handleViewClass = + Class.forName("com.android.org.chromium.content.browser.input.HandleView") if (handleViewClass.isInstance(view)) { val mDrawableField = ReflectionUtils.findField(handleViewClass, "mDrawable") @@ -608,7 +648,8 @@ class FolioWebView : WebView { } else { val folioActivityRef: WeakReference = folioActivityCallback.activity - val mWindowManagerField = ReflectionUtils.findField(FolioActivity::class.java, "mWindowManager") + val mWindowManagerField = + ReflectionUtils.findField(FolioActivity::class.java, "mWindowManager") mWindowManagerField.isAccessible = true val mWindowManager = mWindowManagerField.get(folioActivityRef.get()) @@ -624,7 +665,8 @@ class FolioWebView : WebView { val config = AppUtil.getSavedConfig(context)!! for (view in mViews) { - val popupDecorViewClass = Class.forName("android.widget.PopupWindow\$PopupDecorView") + val popupDecorViewClass = + Class.forName("android.widget.PopupWindow\$PopupDecorView") if (!popupDecorViewClass.isInstance(view)) continue @@ -636,7 +678,10 @@ class FolioWebView : WebView { //val pathClassLoader = PathClassLoader("/system/app/Chrome/Chrome.apk", ClassLoader.getSystemClassLoader()) val pathClassLoader = - PathClassLoader("/system/app/Chrome/Chrome.apk", folioActivityRef.get()?.classLoader) + PathClassLoader( + "/system/app/Chrome/Chrome.apk", + folioActivityRef.get()?.classLoader + ) val popupTouchHandleDrawableClass = Class.forName( "org.chromium.android_webview.PopupTouchHandleDrawable", @@ -646,7 +691,8 @@ class FolioWebView : WebView { //if (!popupTouchHandleDrawableClass.isInstance(mChildren[0])) // continue - val mDrawableField = ReflectionUtils.findField(popupTouchHandleDrawableClass, "mDrawable") + val mDrawableField = + ReflectionUtils.findField(popupTouchHandleDrawableClass, "mDrawable") mDrawableField.isAccessible = true val mDrawable = mDrawableField.get(mChildren[0]) as Drawable UiUtil.setColorIntToDrawable(config.themeColor, mDrawable) @@ -678,7 +724,7 @@ class FolioWebView : WebView { Log.i(LOG_TAG, "-> currentSelectionRect doesn't intersects viewportRect") uiHandler.post { popupWindow.dismiss() - uiHandler.removeCallbacks(isScrollingRunnable) + isScrollingRunnable?.let { uiHandler.removeCallbacks(it) } } return } @@ -770,7 +816,7 @@ class FolioWebView : WebView { oldScrollY = scrollY isScrollingRunnable = Runnable { - uiHandler.removeCallbacks(isScrollingRunnable) + isScrollingRunnable?.let { uiHandler.removeCallbacks(it) } val currentScrollX = scrollX val currentScrollY = scrollY val inTouchMode = lastTouchAction == MotionEvent.ACTION_DOWN || @@ -791,13 +837,24 @@ class FolioWebView : WebView { oldScrollY = currentScrollY isScrollingCheckDuration += IS_SCROLLING_CHECK_TIMER if (isScrollingCheckDuration < IS_SCROLLING_CHECK_MAX_DURATION && !destroyed) - uiHandler.postDelayed(isScrollingRunnable, IS_SCROLLING_CHECK_TIMER.toLong()) + isScrollingRunnable?.let { + uiHandler.postDelayed( + it, + IS_SCROLLING_CHECK_TIMER.toLong() + ) + } } } - - uiHandler.removeCallbacks(isScrollingRunnable) + isScrollingRunnable?.let { + uiHandler.removeCallbacks(it) + } isScrollingCheckDuration = 0 - if (!destroyed) - uiHandler.postDelayed(isScrollingRunnable, IS_SCROLLING_CHECK_TIMER.toLong()) + if (!destroyed) { + isScrollingRunnable?.let { + uiHandler.postDelayed(it, IS_SCROLLING_CHECK_TIMER.toLong()) + + } + } + } } diff --git a/folioreader/src/main/java/com/folioreader/util/AppUtil.kt b/folioreader/src/main/java/com/folioreader/util/AppUtil.kt index 9b7958f44..37b135056 100644 --- a/folioreader/src/main/java/com/folioreader/util/AppUtil.kt +++ b/folioreader/src/main/java/com/folioreader/util/AppUtil.kt @@ -102,7 +102,7 @@ class AppUtil { obj.toString() ) } catch (e: JSONException) { - Log.e(LOG_TAG, e.message) + Log.e(LOG_TAG, e.message.orEmpty()) } } @@ -115,7 +115,7 @@ class AppUtil { val jsonObject = JSONObject(json) return Config(jsonObject) } catch (e: JSONException) { - Log.e(LOG_TAG, e.message) + Log.e(LOG_TAG, e.message.orEmpty()) return null } @@ -187,10 +187,3 @@ class AppUtil { } } } - - - - - - - diff --git a/folioreader/src/main/java/com/folioreader/util/DefaultReadLocatorManager.kt b/folioreader/src/main/java/com/folioreader/util/DefaultReadLocatorManager.kt new file mode 100644 index 000000000..052e97f21 --- /dev/null +++ b/folioreader/src/main/java/com/folioreader/util/DefaultReadLocatorManager.kt @@ -0,0 +1,26 @@ +package com.folioreader.util + +import android.content.Context +import com.folioreader.Constants +import com.folioreader.model.locators.ReadLocator + +class DefaultReadLocatorManager(private val context: Context) : ReadLocatorListener { + override fun saveReadLocator(readLocator: ReadLocator?) { + val locator = readLocator ?: return + SharedPreferenceUtil.putSharedPreferencesString( + context, + Constants.LAST_READ_LOCATOR, + readLocator.toJson() + ) + } + + fun getLastReadLocator(): ReadLocator? { + return ReadLocator.fromJson( + SharedPreferenceUtil.getSharedPreferencesString( + context, + Constants.LAST_READ_LOCATOR, + null + ) + ) + } +} \ No newline at end of file diff --git a/folioreader/src/main/java/com/folioreader/util/FileUtil.java b/folioreader/src/main/java/com/folioreader/util/FileUtil.java index 64b488a77..a69597c3f 100644 --- a/folioreader/src/main/java/com/folioreader/util/FileUtil.java +++ b/folioreader/src/main/java/com/folioreader/util/FileUtil.java @@ -3,13 +3,17 @@ import android.content.Context; import android.content.res.AssetManager; import android.content.res.Resources; -import android.os.Environment; import android.text.TextUtils; import android.util.Log; + import com.folioreader.Constants; import com.folioreader.ui.activity.FolioActivity; -import java.io.*; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; /** * Created by Mahavir on 12/15/16. @@ -19,26 +23,28 @@ public class FileUtil { private static final String TAG = FileUtil.class.getSimpleName(); private static final String FOLIO_READER_ROOT = "folioreader"; - public static String saveEpubFileAndLoadLazyBook(final Context context, - FolioActivity.EpubSourceType epubSourceType, - String epubFilePath, - int epubRawId, String epubFileName) { - String filePath; - InputStream epubInputStream; - boolean isFolderAvailable; + public static String saveEpubFileAndLoadLazyBook( + final Context context, + FolioActivity.EpubSourceType epubSourceType, + String epubFilePath, + int epubRawId, + String epubFileName + ) { try { - isFolderAvailable = isFolderAvailable(epubFileName); - filePath = getFolioEpubFilePath(epubSourceType, epubFilePath, epubFileName); + boolean isFolderAvailable = isFolderAvailable(epubFileName, context); + String filePath = getFolioEpubFilePath(epubSourceType, epubFilePath, epubFileName, context); + + InputStream epubInputStream; if (!isFolderAvailable) { if (epubSourceType.equals(FolioActivity.EpubSourceType.RAW)) { epubInputStream = context.getResources().openRawResource(epubRawId); - saveTempEpubFile(filePath, epubFileName, epubInputStream); + saveTempEpubFile(filePath, epubFileName, epubInputStream, context); } else if (epubSourceType.equals(FolioActivity.EpubSourceType.ASSETS)) { AssetManager assetManager = context.getAssets(); epubFilePath = epubFilePath.replaceAll(Constants.ASSET, ""); epubInputStream = assetManager.open(epubFilePath); - saveTempEpubFile(filePath, epubFileName, epubInputStream); + saveTempEpubFile(filePath, epubFileName, epubInputStream, context); } else { filePath = epubFilePath; } @@ -51,26 +57,36 @@ public static String saveEpubFileAndLoadLazyBook(final Context context, return null; } - public static String getFolioEpubFolderPath(String epubFileName) { - return Environment.getExternalStorageDirectory().getAbsolutePath() - + "/" + FOLIO_READER_ROOT + "/" + epubFileName; + + private static boolean isFolderAvailable(String epubFileName, Context context) { + File file = new File(getFolioEpubFolderPath(epubFileName, context)); + return file.exists() && file.isDirectory(); + } + + public static String getFolioEpubFolderPath(String epubFileName, Context context) { + return context.getCacheDir().getAbsolutePath() + "/" + FOLIO_READER_ROOT + "/" + epubFileName; } - public static String getFolioEpubFilePath(FolioActivity.EpubSourceType sourceType, String epubFilePath, String epubFileName) { - if (FolioActivity.EpubSourceType.SD_CARD.equals(sourceType)) { + public static String getFolioEpubFilePath( + FolioActivity.EpubSourceType sourceType, + String epubFilePath, + String epubFileName, + Context context + ) { + if (FolioActivity.EpubSourceType.DEVICE_STORAGE.equals(sourceType)) { return epubFilePath; } else { - return getFolioEpubFolderPath(epubFileName) + "/" + epubFileName + ".epub"; + return getFolioEpubFolderPath(epubFileName, context) + "/" + epubFileName + ".epub"; } } - private static boolean isFolderAvailable(String epubFileName) { - File file = new File(getFolioEpubFolderPath(epubFileName)); - return file.isDirectory(); - } - public static String getEpubFilename(Context context, FolioActivity.EpubSourceType epubSourceType, - String epubFilePath, int epubRawId) { + public static String getEpubFilename( + Context context, + FolioActivity.EpubSourceType epubSourceType, + String epubFilePath, + int epubRawId + ) { String epubFileName; if (epubSourceType.equals(FolioActivity.EpubSourceType.RAW)) { Resources res = context.getResources(); @@ -85,12 +101,13 @@ public static String getEpubFilename(Context context, FolioActivity.EpubSourceTy return epubFileName; } - public static Boolean saveTempEpubFile(String filePath, String fileName, InputStream inputStream) { - OutputStream outputStream = null; - File file = new File(filePath); + public static void saveTempEpubFile(String filePath, String fileName, InputStream inputStream, Context context) { try { + OutputStream outputStream; + File file = new File(filePath); + if (!file.exists()) { - File folder = new File(getFolioEpubFolderPath(fileName)); + File folder = new File(getFolioEpubFolderPath(fileName, context)); folder.mkdirs(); outputStream = new FileOutputStream(file); @@ -100,15 +117,13 @@ public static Boolean saveTempEpubFile(String filePath, String fileName, InputSt while ((read = inputStream.read(bytes)) != -1) { outputStream.write(bytes, 0, read); } - } else { - return true; + + inputStream.close(); + outputStream.close(); } - inputStream.close(); - outputStream.close(); } catch (IOException e) { Log.e(TAG, e.getMessage()); } - return false; } public static String getExtensionUppercase(String path) { diff --git a/sample/build.gradle b/sample/build.gradle index 54caa7c76..d75a398a0 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -71,4 +71,8 @@ dependencies { } } + implementation("com.github.codetoart:r2-shared-kotlin:$versions.r2SharedKotlin") { + changing = true + } + } diff --git a/sample/src/main/AndroidManifest.xml b/sample/src/main/AndroidManifest.xml index 314c99e98..491a70e44 100644 --- a/sample/src/main/AndroidManifest.xml +++ b/sample/src/main/AndroidManifest.xml @@ -13,6 +13,7 @@ @@ -22,4 +23,4 @@ - \ No newline at end of file + 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 25c63427d..f561f3d5c 100644 --- a/sample/src/main/java/com/folioreader/android/sample/HomeActivity.java +++ b/sample/src/main/java/com/folioreader/android/sample/HomeActivity.java @@ -65,7 +65,7 @@ public void onClick(View v) { if (config == null) config = new Config(); config.setAllowedDirection(Config.AllowedDirection.VERTICAL_AND_HORIZONTAL); - + config.setShowSearch(false); folioReader.setConfig(config, true) .openBook(R.raw.accessible_epub_3); } @@ -81,6 +81,7 @@ public void onClick(View v) { if (config == null) config = new Config(); config.setAllowedDirection(Config.AllowedDirection.VERTICAL_AND_HORIZONTAL); + config.setShowSearch(false); folioReader.setReadLocator(readLocator); folioReader.setConfig(config, true) @@ -179,4 +180,4 @@ public void onHighlight(HighLight highlight, HighLight.HighLightAction type) { public void onFolioReaderClosed() { Log.v(LOG_TAG, "-> onFolioReaderClosed"); } -} \ No newline at end of file +} diff --git a/versions.gradle b/versions.gradle index ec456b157..fda74c1e4 100644 --- a/versions.gradle +++ b/versions.gradle @@ -8,8 +8,8 @@ versions.projectVersionCode = 1 versions.projectVersionName = "1.0" versions.androidMinSdk = 21 -versions.androidCompileSdk = 28 -versions.androidTargetSdk = 28 +versions.androidCompileSdk = 33 +versions.androidTargetSdk = 33 versions.androidGradlePlugin = "3.5.3" versions.kotlin = "1.3.11" @@ -23,6 +23,6 @@ versions.retrofit = "2.5.0" versions.jackson = "2.9.7" versions.gson = "2.8.5" -versions.lifecycle = "2.1.0" +versions.lifecycle = "2.2.0" -ext.versions = versions \ No newline at end of file +ext.versions = versions