Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

App crashes when trying to open raw using folioreader in android 11 but runs perfectly on 10 and below #503

Open
zeoharlem opened this issue Jul 3, 2021 · 11 comments

Comments

@zeoharlem
Copy link

Issue / Feature - Folioreader crashes app
FolioReader version - com.folioreader:folioreader:0.5.1
FolioReader Stock / Modified -
Android SDK - min(22) target(30)
Mobile / Tablet / Emulator Info -
Crash / Error - --------- beginning of crash
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.zeoharlem.ezivah, PID: 5844
java.lang.NullPointerException: Attempt to invoke virtual method 'int android.speech.tts.TextToSpeech.setOnUtteranceCompletedListener(android.speech.tts.TextToSpeech$OnUtteranceCompletedListener)' on a null object reference
at com.folioreader.ui.folio.mediaoverlay.MediaController$2.onInit(MediaController.java:114)
at android.speech.tts.TextToSpeech.dispatchOnInit(TextToSpeech.java:862)
at android.speech.tts.TextToSpeech.initTts(TextToSpeech.java:840)
at android.speech.tts.TextToSpeech.(TextToSpeech.java:771)
at android.speech.tts.TextToSpeech.(TextToSpeech.java:750)
at android.speech.tts.TextToSpeech.(TextToSpeech.java:734)
at com.folioreader.ui.folio.mediaoverlay.MediaController.setTextToSpeech(MediaController.java:106)
at com.folioreader.ui.folio.fragment.FolioPageFragment.onCreateView(FolioPageFragment.java:179)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2963)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:518)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2189)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:2100)
at androidx.fragment.app.FragmentManager.execSingleAction(FragmentManager.java:1971)
at androidx.fragment.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:311)
at androidx.fragment.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:274)
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:25466)
at androidx.constraintlayout.widget.ConstraintLayout$Measurer.measure(ConstraintLayout.java:792)
at androidx.constraintlayout.solver.widgets.ConstraintWidgetContainer.measure(ConstraintWidgetContainer.java:583)
at androidx.constraintlayout.solver.widgets.analyzer.Direct.verticalSolvingPass(Direct.java:355)
at androidx.constraintlayout.solver.widgets.analyzer.Direct.solveVerticalMatchConstraint(Direct.java:636)
at androidx.constraintlayout.solver.widgets.analyzer.Direct.verticalSolvingPass(Direct.java:407)
at androidx.constraintlayout.solver.widgets.analyzer.Direct.solvingPass(Direct.java:178)
at androidx.constraintlayout.solver.widgets.ConstraintWidgetContainer.layout(ConstraintWidgetContainer.java:642)
at androidx.constraintlayout.solver.widgets.analyzer.BasicMeasure.solveLinearSystem(BasicMeasure.java:159)
at androidx.constraintlayout.solver.widgets.analyzer.BasicMeasure.solverMeasure(BasicMeasure.java:290)
at androidx.constraintlayout.solver.widgets.ConstraintWidgetContainer.measure(ConstraintWidgetContainer.java:119)
at androidx.constraintlayout.widget.ConstraintLayout.resolveSystem(ConstraintLayout.java:1578)
at androidx.constraintlayout.widget.ConstraintLayout.onMeasure(ConstraintLayout.java:1690)
at android.view.View.measure(View.java:25466)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6957)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at androidx.appcompat.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:145)
at android.view.View.measure(View.java:25466)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6957)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
at android.view.View.measure(View.java:25466)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6957)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
E/AndroidRuntime: at android.view.View.measure(View.java:25466)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6957)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
at android.view.View.measure(View.java:25466)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6957)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at com.android.internal.policy.DecorView.onMeasure(DecorView.java:747)
at android.view.View.measure(View.java:25466)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:3397)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:2228)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2486)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1952)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8171)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:972)
at android.view.Choreographer.doCallbacks(Choreographer.java:796)
at android.view.Choreographer.doFrame(Choreographer.java:731)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:957)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

Steps to reproduce / Describe in detail -

@awaisabbasaa11
Copy link

Hi, Have you solved this issue

@awaisabbasaa11
Copy link

awaisabbasaa11 commented Jul 9, 2021

I have solved this issue, if your app is targeting android 11 then the READ/WRITE EXTERNAL_STORAGE Permissions are ignored, and also android:requestLegacyExternalStorage="true" is also ignore but you have to keep these in manifest in order to be compatible for devices below Android 11. So for android 11 add the following permission in the manifest file.

<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />

and in FileUtils.saveEpubFileAndLoadLazyBook(,,,) check for permission using the following method

private static boolean checkPermission(Context context) {
if (SDK_INT >= Build.VERSION_CODES.R) {
return Environment.isExternalStorageManager();
} else {
int result = ContextCompat.checkSelfPermission(context, READ_EXTERNAL_STORAGE);
int result1 = ContextCompat.checkSelfPermission(context, WRITE_EXTERNAL_STORAGE);
return result == PackageManager.PERMISSION_GRANTED && result1 == PackageManager.PERMISSION_GRANTED;
}
}

if the app doesn't have manage external storage permission or then request that permission by using the following method

private static void requestPermission(Context context) {
Activity activity = (Activity) context;
if (SDK_INT >= Build.VERSION_CODES.R) {
try {
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
intent.addCategory("android.intent.category.DEFAULT");
intent.setData(Uri.parse(String.format("package:%s", context.getApplicationContext().getPackageName())));
activity.startActivityForResult(intent, 2296);
} catch (Exception e) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
activity.startActivityForResult(intent, 2296);
}
} else {
//below android 11
ActivityCompat.requestPermissions((Activity) context, new String[]{WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
}
}

if the user has the permission then continue with the normal flow

@zeoharlem
Copy link
Author

I have solved this issue, if your app is targeting android 11 then the READ/WRITE EXTERNAL_STORAGE Permissions are ignored, and also android:requestLegacyExternalStorage="true" is also ignore but you have to keep these in manifest in order to be compatible for devices below Android 11. So for android 11 add the following permission in the manifest file.

<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />

and in FileUtils.saveEpubFileAndLoadLazyBook(,,,) check for permission using the following method

private static boolean checkPermission(Context context) {
if (SDK_INT >= Build.VERSION_CODES.R) {
return Environment.isExternalStorageManager();
} else {
int result = ContextCompat.checkSelfPermission(context, READ_EXTERNAL_STORAGE);
int result1 = ContextCompat.checkSelfPermission(context, WRITE_EXTERNAL_STORAGE);
return result == PackageManager.PERMISSION_GRANTED && result1 == PackageManager.PERMISSION_GRANTED;
}
}

if the app doesn't have manage external storage permission or then request that permission by using the following method

private static void requestPermission(Context context) {
Activity activity = (Activity) context;
if (SDK_INT >= Build.VERSION_CODES.R) {
try {
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
intent.addCategory("android.intent.category.DEFAULT");
intent.setData(Uri.parse(String.format("package:%s", context.getApplicationContext().getPackageName())));
activity.startActivityForResult(intent, 2296);
} catch (Exception e) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
activity.startActivityForResult(intent, 2296);
}
} else {
//below android 11
ActivityCompat.requestPermissions((Activity) context, new String[]{WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
}
}

if the user has the permission then continue with the normal flow

I will try this and revert.. thank you...

@zeoharlem
Copy link
Author

I have solved this issue, if your app is targeting android 11 then the READ/WRITE EXTERNAL_STORAGE Permissions are ignored, and also android:requestLegacyExternalStorage="true" is also ignore but you have to keep these in manifest in order to be compatible for devices below Android 11. So for android 11 add the following permission in the manifest file.

<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />

and in FileUtils.saveEpubFileAndLoadLazyBook(,,,) check for permission using the following method

private static boolean checkPermission(Context context) {
if (SDK_INT >= Build.VERSION_CODES.R) {
return Environment.isExternalStorageManager();
} else {
int result = ContextCompat.checkSelfPermission(context, READ_EXTERNAL_STORAGE);
int result1 = ContextCompat.checkSelfPermission(context, WRITE_EXTERNAL_STORAGE);
return result == PackageManager.PERMISSION_GRANTED && result1 == PackageManager.PERMISSION_GRANTED;
}
}

if the app doesn't have manage external storage permission or then request that permission by using the following method

private static void requestPermission(Context context) {
Activity activity = (Activity) context;
if (SDK_INT >= Build.VERSION_CODES.R) {
try {
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
intent.addCategory("android.intent.category.DEFAULT");
intent.setData(Uri.parse(String.format("package:%s", context.getApplicationContext().getPackageName())));
activity.startActivityForResult(intent, 2296);
} catch (Exception e) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
activity.startActivityForResult(intent, 2296);
}
} else {
//below android 11
ActivityCompat.requestPermissions((Activity) context, new String[]{WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
}
}

if the user has the permission then continue with the normal flow

thanks for your response.. checking that method saveEpubFileAndLoadLazyBook there was no checking of permission but i cannot edit it cos it's a readonly file... kindly advise on how to go about it

@awaisabbasaa11
Copy link

I have solved this issue, if your app is targeting android 11 then the READ/WRITE EXTERNAL_STORAGE Permissions are ignored, and also android:requestLegacyExternalStorage="true" is also ignore but you have to keep these in manifest in order to be compatible for devices below Android 11. So for android 11 add the following permission in the manifest file.
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
and in FileUtils.saveEpubFileAndLoadLazyBook(,,,) check for permission using the following method
private static boolean checkPermission(Context context) {
if (SDK_INT >= Build.VERSION_CODES.R) {
return Environment.isExternalStorageManager();
} else {
int result = ContextCompat.checkSelfPermission(context, READ_EXTERNAL_STORAGE);
int result1 = ContextCompat.checkSelfPermission(context, WRITE_EXTERNAL_STORAGE);
return result == PackageManager.PERMISSION_GRANTED && result1 == PackageManager.PERMISSION_GRANTED;
}
}
if the app doesn't have manage external storage permission or then request that permission by using the following method
private static void requestPermission(Context context) {
Activity activity = (Activity) context;
if (SDK_INT >= Build.VERSION_CODES.R) {
try {
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
intent.addCategory("android.intent.category.DEFAULT");
intent.setData(Uri.parse(String.format("package:%s", context.getApplicationContext().getPackageName())));
activity.startActivityForResult(intent, 2296);
} catch (Exception e) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
activity.startActivityForResult(intent, 2296);
}
} else {
//below android 11
ActivityCompat.requestPermissions((Activity) context, new String[]{WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
}
}
if the user has the permission then continue with the normal flow

thanks for your response.. checking that method saveEpubFileAndLoadLazyBook there was no checking of permission but i cannot edit it cos it's a readonly file... kindly advise on how to go about it

Hi I hope you are doing well, So as you said that file is readOnly that means you have implemented FolioReader dependency, this way libraries won't be editable so what you have that (that's what I do most of the time) you have to add the folioReader as a module in your project. This way you will have access to all of the file and you can change anything like you do in your app module.

Download the folioReader library code from this repo, place the folioReader folder in your project folder, add the name in gradle settings file and you are good to go for more information you can google or you can view the demo app in this repo. I hope this will help

@zeoharlem
Copy link
Author

@awaisabbasaa11 thanks for the response so far... it is difficult adding folioreader as module to project. i want to ask if you can add it to a dummy project and share the link to the project... your response is greatly appreciated

@awaisabbasaa11
Copy link

@zeoharlem Sorry for being late, https://github.com/UmarAlyas0078/FolioModule here is a link of demo repository with some customization already done, so to undo any customization please reimport the folio Reader. :)

@skewel
Copy link

skewel commented Sep 26, 2021

I have solved this issue, if your app is targeting android 11 then the READ/WRITE EXTERNAL_STORAGE Permissions are ignored, and also android:requestLegacyExternalStorage="true" is also ignore but you have to keep these in manifest in order to be compatible for devices below Android 11. So for android 11 add the following permission in the manifest file.

<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />

and in FileUtils.saveEpubFileAndLoadLazyBook(,,,) check for permission using the following method

private static boolean checkPermission(Context context) {
if (SDK_INT >= Build.VERSION_CODES.R) {
return Environment.isExternalStorageManager();
} else {
int result = ContextCompat.checkSelfPermission(context, READ_EXTERNAL_STORAGE);
int result1 = ContextCompat.checkSelfPermission(context, WRITE_EXTERNAL_STORAGE);
return result == PackageManager.PERMISSION_GRANTED && result1 == PackageManager.PERMISSION_GRANTED;
}
}

if the app doesn't have manage external storage permission or then request that permission by using the following method

private static void requestPermission(Context context) {
Activity activity = (Activity) context;
if (SDK_INT >= Build.VERSION_CODES.R) {
try {
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
intent.addCategory("android.intent.category.DEFAULT");
intent.setData(Uri.parse(String.format("package:%s", context.getApplicationContext().getPackageName())));
activity.startActivityForResult(intent, 2296);
} catch (Exception e) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
activity.startActivityForResult(intent, 2296);
}
} else {
//below android 11
ActivityCompat.requestPermissions((Activity) context, new String[]{WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
}
}

if the user has the permission then continue with the normal flow

I think we can fix this by replacing the permissions request :

if (ContextCompat.checkSelfPermission(...

with something like

if (!checkPermission(this)) {
requestPermission(this)
finish()
}else{
setupBook()
}

@AnonUnfeeling
Copy link

AnonUnfeeling commented Nov 8, 2021

Guys, we still have access to public directories :)
So, solution can be like this:
Before:
public static String getFolioEpubFolderPath(Context context, String epubFileName) { return Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + FOLIO_READER_ROOT + "/" + epubFileName; }

After:
public static String getFolioEpubFolderPath(Context context, String epubFileName) { return context.getExternalFilesDir(Environment.DIRECTORY_PICTURES) + "/" + FOLIO_READER_ROOT + "/" + epubFileName; }

@johnjericmoratas
Copy link

hi @awaisabbasaa11 do you have folioreader module in dummy project for kotlin? Thank you!

@zeoharlem
Copy link
Author

@zeoharlem Sorry for being late, https://github.com/UmarAlyas0078/FolioModule here is a link of demo repository with some customization already done, so to undo any customization please reimport the folio Reader. :)

Hi @awaisabbasaa11, i have tried everything but this is not working like the app not working 11 upwards, the code is breaking. do you have any suggestion

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants