Closed Hamata6 closed 2 years ago
I just found out that sometimes it happens on the second scan, sometimes on the third scan
Could you try with this version of the plugin? https://github.com/NeutrinosPlatform/cordova-plugin-document-scanner/issues/74#issuecomment-777267803
Thanks for your quick response @ChrisTomAlx. I did. However I'm using Capacitor so cordova plugin
commands won't work.
I did update it to the beta.1 with editing the package.json to contain "cordova-plugin-document-scanner": "^5.0.0-beta.1"
and rerun npm i
. It still gives me the same error (after i had encountered and fixed the same issue as #96 )
@ChrisTomAlx I updated my repo to install the beta.1 version. You can try it yourself: https://github.com/Hamata6/DocScanIssue
Generated a debug app of my repo so you can attach the Android debugger to it: app-debug.apk.zip
I think I found out the issue. When the .then() of .scanDoc() is called, the native library (in Androids case the Java code of the scan-library) is not finished yet. So when calling .scanDoc() in a immediate loop without any delay, the .scanDoc() function gets called again before the native code is finished cleaning up (or something).
I found out that the same was happening on iOS. The iOS simulator opened the camera the first time when calling .scanDoc(), but refused to open the camera a second time.
For example this code works perfectly fine:
private async makeScanHandler() {
let scanResult = await this.makeScan();
if (scanResult) {
setTimeout(() => {
this.makeScanHandler();
}, 500); //Timeout of 500ms
}
}
private makeScan(): Promise<boolean> {
return DocumentScanner.scanDoc()
.then((res) => {
console.log("res = ", res);
return true;
})
.catch((error) => {
console.log("catch, error = ", error);
return false;
});
}
While the old code without delay does not work:
private async makeScanHandler() {
let scanResult = false;
do {
scanResult = await this.makeScan();
} while (scanResult);
}
private makeScan(): Promise<boolean> {
return DocumentScanner.scanDoc()
.then((res) => {
console.log("res = ", res);
return true;
})
.catch((error) => {
console.log("catch, error = ", error);
return false;
});
}
I think I can handle this myself now xD. The remaining question is: Can you make .scanDoc() resolve only when the native library is finished doing its work? Then we don't need a delay for the second scan.
Describe the bug Fatal Exception on Android when calling scanDoc for the second time. java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@4693e70
Stacktrace
W/Bitmap: Called hasAlpha() on a recycle()'d bitmap! This is undefined behavior!Called hasAlpha() on a recycle()'d bitmap! This is undefined behavior!
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: io.ionic.starter, PID: 12600
java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@4693e70
at android.graphics.BaseCanvas.throwIfCannotDraw(BaseCanvas.java:77) at android.graphics.RecordingCanvas.throwIfCannotDraw(RecordingCanvas.java:278) at android.graphics.BaseRecordingCanvas.drawBitmap(BaseRecordingCanvas.java:91) at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:548) at android.widget.ImageView.onDraw(ImageView.java:1435) at android.view.View.draw(View.java:23901) at android.view.View.updateDisplayListIfDirty(View.java:22776) at android.view.View.draw(View.java:23631) at android.view.ViewGroup.drawChild(ViewGroup.java:5336) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:5093) at android.view.View.updateDisplayListIfDirty(View.java:22762) at android.view.View.draw(View.java:23631) at android.view.ViewGroup.drawChild(ViewGroup.java:5336) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:5093) at android.view.View.draw(View.java:23904) at android.view.View.updateDisplayListIfDirty(View.java:22776) at android.view.View.draw(View.java:23631) at android.view.ViewGroup.drawChild(ViewGroup.java:5336) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:5093) at android.view.View.updateDisplayListIfDirty(View.java:22762) at android.view.View.draw(View.java:23631) at android.view.ViewGroup.drawChild(ViewGroup.java:5336) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:5093) at android.view.View.updateDisplayListIfDirty(View.java:22762) at android.view.View.draw(View.java:23631) at android.view.ViewGroup.drawChild(ViewGroup.java:5336) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:5093) at android.view.View.updateDisplayListIfDirty(View.java:22762) at android.view.View.draw(View.java:23631) at android.view.ViewGroup.drawChild(ViewGroup.java:5336) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:5093) at android.view.View.updateDisplayListIfDirty(View.java:22762) at android.view.View.draw(View.java:23631) at android.view.ViewGroup.drawChild(ViewGroup.java:5336) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:5093) at android.view.View.draw(View.java:23904) at com.android.internal.policy.DecorView.draw(DecorView.java:1282) at android.view.View.updateDisplayListIfDirty(View.java:22776) at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:579) at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:585) at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:662) at android.view.ViewRootImpl.draw(ViewRootImpl.java:5042) at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:4749) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3866) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2618) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:9965) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1010) at android.view.Choreographer.doCallbacks(Choreographer.java:809) at android.view.Choreographer.doFrame(Choreographer.java:744) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:995) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:246) at android.app.ActivityThread.main(ActivityThread.java:8512) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130) I/Process: Sending signal. PID: 12600 SIG: 9
To Reproduce Let's make a brand new all clean project to reproduce:
Manually creating new project
1. Make a new Ionic Angular project with Capacitor: `ionic start DocScanIssue blank --type=angular --capacitor`
4. Run `ionic cap sync`2. Install this cordova scanner plugin for Capacitor:
`npm install cordova-plugin-document-scanner`
`npm install @ionic-native/core`
`npm install @ionic-native/document-scanner`
3. Make src/app/home/home.page.ts look like this:
5. Generate Android project: `ionic cap add android`
6. Open the Android project with Android Studio: `ionic cap open android`
7. If your physical device is Android 10+, set targetSdkVersion to 28 in Gradle Scripts/variables.gradle (don't forget to press Sync now) to bypass the storage permission issue for now (default targets 29)
8. Connect a physical device with USB debugging enabled, select it from the devices list, and run the project (I haven't tested it on emulator)
9. Try to make a second scan
Or just clone this repo in which I did all the work already ;) https://github.com/Hamata6/DocScanIssue Execute
npm i
,ionic cap sync
,ionic cap open android
Connect a physical device with USB debugging enabled, select it from the devices list, and run the project (I haven't tested it on emulator) Try to make a second scanExpected behavior Being able to make a second (and more) scan. The second time the native Android camera activity opens, but the activity in the background crashes.
Smartphone (please complete the following information):