FolioReader-Android
FolioReader-Android copied to clipboard
Help to integrate into our project
Hi,
Some time ago (months ago) we help r2 streamer to parse the ebooks correctly. We are using an old version of Folio Reader for Android with a lot of crashes. Im friend of Heberti from iOS version and i develop lot of things there too (https://github.com/prsolucoes/FolioReaderKit).
Now, more than months, we need use the latest version from Folio Reader for Android. So i need make some questions to understand if i need fork the project to make somethings or everything is already implemented here too in Android version.
- Only show the main content of ebook fragment without the Folio bars to change fonts etc. We have our own interface to do this things, we need only show the ebook content.
- Receive callback about the position of click to understand if we need change page or show our own top/bottom menu
- Callback for "page" loaded
- Callback for "page" changed
- Callback for "chapter" changed
- Method to get current page number and chapter (we have our implementation for sync of pause and bookmarks)
- Method to set current page and chapter (we have our implementation for sync of pause and bookmarks)
- Method to get current progress (0-100) (we have our implementation for sync of pause and bookmarks)
- Method to set current progress (0-100) (we have our implementation for sync of pause and bookmarks)
- Method to change theme (light, dark and sepia)
- Method to get all chapters, with their file names (TOC)
Thanks if anyone can help understand if this things already exists and/or methods names.
@prsolucoes No, progress & page number features are not in FolioReader android. So, you will need to fork and implement those.
in recent versions we did following improvements:
- uses epub-cfi in last read position and search position
- make last read position and highlights syncable across devices
- using r2-streamer-kotlin (instead of r2-streamer-java)
Now further plan is to use epub-cfi for highlights & bookmarks.
I will publish my changes in our fork
Changed min SDK version:
- Changed min SDK supported to 16 and tested on API 16 devices without problems. Our main app is SDK 16 min API too.


A strange problem is happening. My own application has our icon but the name of application was changed.
I changed all the "app_name" strings to their context.
- folio_app_name : to the library string
- view_pager_app_name : to view pager project
With this the problem was solved.
I have another problem now when the library inside our project when i open any epub:
ERROR:
Caused by: java.lang.ClassNotFoundException: Didn't find class "org.readium.r2.shared.Publication$EXTENSION" on path: DexPathList[[zip file "/data/app/br.com.ubook.ubookapp-2/base.apk"],nativeLibraryDirectories=[/data/app/br.com.ubook.ubookapp-2/lib/arm, /data/app/br.com.ubook.ubookapp-2/base.apk!/lib/armeabi-v7a, /system/lib, /vendor/lib]]
STACKTRACE:
2018-12-13 19:48:19.869 14587-14587/br.com.ubook.ubookapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: br.com.ubook.ubookapp, PID: 14587
java.lang.NoClassDefFoundError: Failed resolution of: Lorg/readium/r2/shared/Publication$EXTENSION;
at com.folioreader.ui.folio.activity.FolioActivity.initBook(FolioActivity.java:450)
at com.folioreader.ui.folio.activity.FolioActivity.setupBook(FolioActivity.java:432)
at com.folioreader.ui.folio.activity.FolioActivity.onCreate(FolioActivity.java:283)
at android.app.Activity.performCreate(Activity.java:6977)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1126)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2946)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3064)
at android.app.ActivityThread.-wrap14(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1659)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6823)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1563)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1451)
Caused by: java.lang.ClassNotFoundException: Didn't find class "org.readium.r2.shared.Publication$EXTENSION" on path: DexPathList[[zip file "/data/app/br.com.ubook.ubookapp-2/base.apk"],nativeLibraryDirectories=[/data/app/br.com.ubook.ubookapp-2/lib/arm, /data/app/br.com.ubook.ubookapp-2/base.apk!/lib/armeabi-v7a, /system/lib, /vendor/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:380)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
at com.folioreader.ui.folio.activity.FolioActivity.initBook(FolioActivity.java:450)
at com.folioreader.ui.folio.activity.FolioActivity.setupBook(FolioActivity.java:432)
at com.folioreader.ui.folio.activity.FolioActivity.onCreate(FolioActivity.java:283)
at android.app.Activity.performCreate(Activity.java:6977)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1126)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2946)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3064)
at android.app.ActivityThread.-wrap14(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1659)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6823)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1563)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1451)
MY CODE:
String ebookPath = EnvironmentHelper.getEpubDownloadFilePath(product.getCatalogId());
folioReader = FolioReader.get()
.setReadPositionListener(this)
.setOnClosedListener(this);
folioReaderConfig = new Config();
folioReaderConfig.setAllowedDirection(Config.AllowedDirection.ONLY_HORIZONTAL);
folioReader.setConfig(folioReaderConfig, true);
folioReader.openBook(ebookPath);
Can you help me? Some bytecode incompatibility?
@prsolucoes Publication$EXTENSION is an enum from r2-shared-kotlin lib.
Building .aar from FolioReader would not be sufficient as a lib. You would also have to generate .pom. As the dependency for r2-shared-kotlin and all the other dependencies in folioreader/build.gradle can only be known through .pom files.
The best way would be to publish your modified FolioReader locally or remotely and import it through gradle.
Hi @hrishikesh-kadam,
I cloned into our vendor directory:
git submodule add [url] vendor/folio-reader
After, i have assed to settings.gradle:
include ':folio-reader'
project(':folio-reader').projectDir = file("../vendor/folio-reader")
After, i have added to dependencies:
implementation project(':folioreader')
But i got error:
Unable to resolve dependency for ':app@ubookDebug/compileClasspath': Could not resolve project :folioreader.
And if i use the "folioreader" module inside Folio Reader folder:
project(':folioreader').projectDir = file("../vendor/folio-reader/folioreader")
I got error:
Plugin with id 'com.github.dcendents.android-maven' not found.
Can you help me?
Hi,
I try use it as local dependency:
1 - I have modified installv1 file to use a different version name "0.5.1.internal". 2 - I run "./gradlew install" on root folder 3 - I put in my gradle:
repositories {
mavenLocal()
...
}
...
dependencies {
implementation 'com.folioreader:folioreader:0.5.1.internal@aar'
}
It is syncing, building and compiling.
But when i run, i got the same problem:
Caused by: java.lang.ClassNotFoundException: Didn't find class "org.readium.r2.shared.Publication$EXTENSION" on path: DexPathList[[zip file "/data/app/br.com.ubook.ubookapp-2/base.apk"],nativeLibraryDirectories=[/data/app/br.com.ubook.ubookapp-2/lib/arm, /data/app/br.com.ubook.ubookapp-2/base.apk!/lib/armeabi-v7a, /system/lib, /vendor/lib]]
Can anyone help me?
@prsolucoes I replied to above doubt here - https://github.com/FolioReader/FolioReader-Android/issues/316#issuecomment-448116080
After use this lines in my app:
android {
...
packagingOptions {
pickFirst 'META-INF/nanohttpd/default-mimetypes.properties'
pickFirst 'META-INF/nanohttpd/mimetypes.properties'
}
...
}
I got error:
2018-12-18 14:08:44.411 3981-3981/br.com.ubook.ubookapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: br.com.ubook.ubookapp, PID: 3981
android.view.InflateException: Binary XML file line #28: Binary XML file line #28: Error inflating class com.folioreader.view.LoadingView
Caused by: android.view.InflateException: Binary XML file line #28: Error inflating class com.folioreader.view.LoadingView
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
at android.view.LayoutInflater.createView(LayoutInflater.java:652)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:794)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:734)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:865)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:828)
at android.view.LayoutInflater.inflate(LayoutInflater.java:525)
at android.view.LayoutInflater.inflate(LayoutInflater.java:427)
at com.folioreader.ui.folio.fragment.FolioPageFragment.onCreateView(FolioPageFragment.java:183)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2439)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1460)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1852)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:802)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2625)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2411)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2366)
at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:2243)
at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:654)
at android.support.v4.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:168)
at com.folioreader.view.DirectionalViewpager.populate(DirectionalViewpager.java:1327)
at com.folioreader.view.DirectionalViewpager.populate(DirectionalViewpager.java:1105)
at com.folioreader.view.DirectionalViewpager.onMeasure(DirectionalViewpager.java:1828)
at android.view.View.measure(View.java:21291)
at android.support.constraint.ConstraintLayout.onMeasure(ConstraintLayout.java:1676)
at android.view.View.measure(View.java:21291)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6443)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:143)
at android.view.View.measure(View.java:21291)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6443)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:758)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:640)
at android.view.View.measure(View.java:21291)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6443)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.view.View.measure(View.java:21291)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6443)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:758)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:640)
at android.view.View.measure(View.java:21291)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6443)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at com.android.internal.policy.DecorView.onMeasure(DecorView.java:916)
at android.view.View.measure(View.java:21291)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2639)
2018-12-18 14:08:44.414 3981-3981/br.com.ubook.ubookapp E/AndroidRuntime: at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1697)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1952)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1569)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7296)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:930)
at android.view.Choreographer.doCallbacks(Choreographer.java:705)
at android.view.Choreographer.doFrame(Choreographer.java:640)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:916)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6823)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1563)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1451)
Caused by: java.lang.NoSuchFieldError: No static field progressBar of type I in class Lcom/folioreader/R$id; or its superclasses (declaration of 'com.folioreader.R$id' appears in /data/app/br.com.ubook.ubookapp-1/base.apk)
at com.folioreader.view.LoadingView.init(LoadingView.java:63)
at com.folioreader.view.LoadingView.<init>(LoadingView.java:41)
... 64 more
Can anyone help me?
@hrishikesh-kadam Please, help me integrate it.
Hi, Can we sync android highlight data with ios devices or vice-vera? Is this possible in folio reader? Please help me. Thanks if anyone, can help me in this.
Right now it is not possible @SophiaSonam
Hi, did you solve it? How can I get the current page? 😞
Hi, Can we sync android highlight data with ios devices or vice-vera? Is this possible in folio reader? Please help me. Thanks if anyone, can help me in this.
This is possible only if you implement Rangy in iOS. I've achieved this and it's working fine.
Hi, Can we sync android highlight data with ios devices or vice-vera? Is this possible in folio reader? Please help me. Thanks if anyone, can help me in this.
This is possible only if you implement Rangy in iOS. I've achieved this and it's working fine.
Can you please provide this file for reference purpose, that will be pretty helpful Thanks!
@SophiaSonam Sorry, I don't have code to share but it's pretty straight forward. Add Rangy files in iOS (only from android code, not from the rangy library) and call functions similar in android-Bridge.js
@SophiaSonam You'll also need to update realm highlight object or create a new entity to store data and sync between both platforms. just follow android in this case. Let me know if you need further help.
@SophiaSonam You'll also need to update realm highlight object or create a new entity to store data and sync between both platforms. just follow android in this case. Let me know if you need further help.
Thanks @shubhankarbhavsar looking forward to it.
@paulo-coutinho
I have another problem now when the library inside our project when i open any epub:
ERROR:
Caused by: java.lang.ClassNotFoundException: Didn't find class "org.readium.r2.shared.Publication$EXTENSION" on path: DexPathList[[zip file "/data/app/br.com.ubook.ubookapp-2/base.apk"],nativeLibraryDirectories=[/data/app/br.com.ubook.ubookapp-2/lib/arm, /data/app/br.com.ubook.ubookapp-2/base.apk!/lib/armeabi-v7a, /system/lib, /vendor/lib]]
STACKTRACE:
2018-12-13 19:48:19.869 14587-14587/br.com.ubook.ubookapp E/AndroidRuntime: FATAL EXCEPTION: main Process: br.com.ubook.ubookapp, PID: 14587 java.lang.NoClassDefFoundError: Failed resolution of: Lorg/readium/r2/shared/Publication$EXTENSION; at com.folioreader.ui.folio.activity.FolioActivity.initBook(FolioActivity.java:450) at com.folioreader.ui.folio.activity.FolioActivity.setupBook(FolioActivity.java:432) at com.folioreader.ui.folio.activity.FolioActivity.onCreate(FolioActivity.java:283) at android.app.Activity.performCreate(Activity.java:6977) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1126) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2946) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3064) at android.app.ActivityThread.-wrap14(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1659) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6823) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1563) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1451) Caused by: java.lang.ClassNotFoundException: Didn't find class "org.readium.r2.shared.Publication$EXTENSION" on path: DexPathList[[zip file "/data/app/br.com.ubook.ubookapp-2/base.apk"],nativeLibraryDirectories=[/data/app/br.com.ubook.ubookapp-2/lib/arm, /data/app/br.com.ubook.ubookapp-2/base.apk!/lib/armeabi-v7a, /system/lib, /vendor/lib]] at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56) at java.lang.ClassLoader.loadClass(ClassLoader.java:380) at java.lang.ClassLoader.loadClass(ClassLoader.java:312) at com.folioreader.ui.folio.activity.FolioActivity.initBook(FolioActivity.java:450) at com.folioreader.ui.folio.activity.FolioActivity.setupBook(FolioActivity.java:432) at com.folioreader.ui.folio.activity.FolioActivity.onCreate(FolioActivity.java:283) at android.app.Activity.performCreate(Activity.java:6977) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1126) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2946) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3064) at android.app.ActivityThread.-wrap14(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1659) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6823) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1563) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1451)
MY CODE:
String ebookPath = EnvironmentHelper.getEpubDownloadFilePath(product.getCatalogId()); folioReader = FolioReader.get() .setReadPositionListener(this) .setOnClosedListener(this); folioReaderConfig = new Config(); folioReaderConfig.setAllowedDirection(Config.AllowedDirection.ONLY_HORIZONTAL); folioReader.setConfig(folioReaderConfig, true); folioReader.openBook(ebookPath);
Can you help me? Some bytecode incompatibility?
hi buddy im facing the same problem , could you resolve this issue and would you please help me how you did it? im really stocked :(
Hi,
Do you have all dependencies in your project?
Something is missing:
// R2 modules
api("com.github.codetoart:r2-shared-kotlin:$versions.r2SharedKotlin") {
changing = true
}
api("com.github.codetoart:r2-streamer-kotlin:$versions.r2StreamerKotlin") {
exclude group: "org.slf4j", module: "slf4j-api"
changing = true
}
Try "api" or "implementation".
Hi,
Do you have all dependencies in your project?
Something is missing:
// R2 modules api("com.github.codetoart:r2-shared-kotlin:$versions.r2SharedKotlin") { changing = true } api("com.github.codetoart:r2-streamer-kotlin:$versions.r2StreamerKotlin") { exclude group: "org.slf4j", module: "slf4j-api" changing = true }
Try "api" or "implementation".
hi I finally could resolve it , the problem was .pom file which was empty ,I recreated it and placed it in C:\Users\your name.m2\repository where my aar was locally published. thanks for your reply
@vaaniiaa Can you please share the pom file Or give the instructions to create the pom file.