NeutrinosPlatform / cordova-plugin-document-scanner

cordova plugin for document scan
https://www.neutrinos.co/
MIT License
85 stars 61 forks source link

Manifest merger failed when using v5.0.0-beta.1 / permission error on Android <=10 #96

Open SchmidtKBS opened 3 years ago

SchmidtKBS commented 3 years ago

Hello, I did a update from plugin version 4.2.5 to 5.0.0-beta.1. After opening the android folder of my project in Android Studio I tried to run a build, but it failed because of an error during the manifest merging:

Error: Attribute provider#androidx.core.content.FileProvider@authorities value=(my.package.id.fileprovider)
from AndroidManifest.xml:36:13-64 is also present at AndroidManifest.xml:32:13-76
value=(my.package.id.com.scanlibrary.provider).
Suggestion: add 'tools:replace="android:authorities"'
to <provider> element at AndroidManifest.xml:34:9-42:20 to override.

android.app main manifest (this file), line 35 Error:
Attribute meta-data#android.support.FILE_PROVIDER_PATHS@resource value=(@xml/file_paths)
from AndroidManifest.xml:41:17-51 is also present at AndroidManifest.xml:37:17-55 value=(@xml/provider_paths).
Suggestion: add 'tools:replace="android:resource"' to <meta-data> element at AndroidManifest.xml:39:13-41:54 to
override. android.app main manifest (this file), line 40 

My xml looks like this:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="my.package.id">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/app_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/app_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode"
            android:name="my.package.id.MainActivity"
            android:label="@string/title_activity_main"
            android:theme="@style/AppTheme.NoActionBarLaunch"
            android:launchMode="singleTask">

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data android:scheme="@string/custom_url_scheme" />
            </intent-filter>

        </activity>

        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>
    </application>

    <!-- Permissions -->

    <uses-permission android:name="android.permission.INTERNET" />
    <!-- Camera, Photos, input file -->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <!-- Geolocation API -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-feature android:name="android.hardware.location.gps" />
    <!-- Network API -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <!-- Navigator.getUserMedia -->
    <!-- Video -->
    <uses-permission android:name="android.permission.CAMERA" />
    <!-- Audio -->
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
</manifest>

It tried to follow the suggestions made by Android Studio. This fixed the build, but when I run the App (on Android 9 Device and Pixel 2 Emulator) it crashes when I open the ScannerPlugin:

    java.lang.RuntimeException: Unable to start activity ComponentInfo{my.package.id/com.scanlibrary.ScanActivity}: java.lang.IllegalArgumentException: Couldn't find meta-data for provider with authority my.package.id.com.scanlibrary.provider
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3430)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3614)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:86)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2199)
        at android.os.Handler.dispatchMessage(Handler.java:112)
        at android.os.Looper.loop(Looper.java:216)
        at android.app.ActivityThread.main(ActivityThread.java:7625)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)
     Caused by: java.lang.IllegalArgumentException: Couldn't find meta-data for provider with authority my.package.id.com.scanlibrary.provider
        at androidx.core.content.FileProvider.parsePathStrategy(FileProvider.java:606)
        at androidx.core.content.FileProvider.getPathStrategy(FileProvider.java:579)
        at androidx.core.content.FileProvider.getUriForFile(FileProvider.java:417)
        at com.scanlibrary.PickImageFragment.openCamera(PickImageFragment.java:135)
        at com.scanlibrary.PickImageFragment.handleIntentPreference(PickImageFragment.java:87)
        at com.scanlibrary.PickImageFragment.init(PickImageFragment.java:68)
        at com.scanlibrary.PickImageFragment.onCreateView(PickImageFragment.java:57)
        at android.app.Fragment.performCreateView(Fragment.java:2537)
        at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1301)
        at android.app.FragmentManagerImpl.addAddedFragments(FragmentManager.java:2433)
        at android.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2212)
        at android.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2168)
        at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2069)
        at android.app.FragmentManagerImpl.dispatchMoveToState(FragmentManager.java:3059)
        at android.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3006)
        at android.app.FragmentController.dispatchActivityCreated(FragmentController.java:182)
        at android.app.Activity.performCreate(Activity.java:7465)
        at android.app.Activity.performCreate(Activity.java:7448)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1286)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3409)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3614) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:86) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2199) 
        at android.os.Handler.dispatchMessage(Handler.java:112) 
        at android.os.Looper.loop(Looper.java:216) 
        at android.app.ActivityThread.main(ActivityThread.java:7625) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987) 

Any ideas, what is wrong here?

SchmidtKBS commented 3 years ago

Short update: I found out that I had to remove following part from the manifest:

        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>

This fixed the merge problem and the project builds. Plugin works now fine on Android 9 and 11, but on Android 7 and 8 the Plugin opens and I can take a photo. Then the App crashes with this permission error:

    java.lang.SecurityException: Permission Denial: writing com.android.providers.media.MediaProvider uri content://media/external/images/media from pid=14106, uid=10085 requires android.permission.WRITE_EXTERNAL_STORAGE, or grantUriPermission()
        at android.os.Parcel.readException(Parcel.java:1683)
        at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:183)
        at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135)
        at android.content.ContentProviderProxy.insert(ContentProviderNative.java:476)
        at android.content.ContentResolver.insert(ContentResolver.java:1274)
        at android.provider.MediaStore$Images$Media.insertImage(MediaStore.java:968)
        at com.scanlibrary.Utils.getUri(Utils.java:28)
        at com.scanlibrary.PickImageFragment.postImagePick(PickImageFragment.java:225)
        at com.scanlibrary.PickImageFragment.onActivityResult(PickImageFragment.java:220)
        at android.app.Activity.dispatchActivityResult(Activity.java:6939)
        at android.app.ActivityThread.deliverResults(ActivityThread.java:4049)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:4096)
        at android.app.ActivityThread.-wrap20(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1516)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6077)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)

@ChrisTomAlx Any ideas?

SchmidtKBS commented 3 years ago

Another update. After some more testing i noticed following: Android 11 (simulator/device) is fine Android 8, 9, 10 simulator is fine Android 10 device: Plugin seems to work normal, but i got an promise rejection from scanDoc when using 'returnBase64 = true' open failed: EACCES (Permission denied)

Android <=9 device: App crashes and restart when switching from camera view to image cropper view. So far I wasn't able to check the error.

My solution so far: Open Android App Settings, go to Permissions. The 'Storage' permission is marked as declined, but I was never asked for granting access to storage. When setting this manually to accept, the Plugin works fine on all Devices with Android <=10.

Is there any way to request permissions for storage in a propper way?

ChrisTomAlx commented 3 years ago

@SchmidtKBS sorry about the delay, you could try and use the diagnostic plugin to request for permissions

Cheers, Chris Neutrinos

SchmidtKBS commented 3 years ago

Hey @ChrisTomAlx, I managed to get it running. I didn't use the diagnostic plugin. I made a small 'fix' to the scanlibrary and i got it running on Android <=9. You can check these to commits on my fork: first, second Maybe you can add it to the scanlibary? I'm not sure if this is a suitable solution. For Andorid 10 I had to add android:requestLegacyExternalStorage="true" AndoridManifest.xml in my projects android folder.

I also noticed another problem, when using the plugin the first time. After opening the plugin for the first time, it asks for camera permissions. After granting permissions the library stays in PickImageFragment instead of redirectiong to camera. I found a fix for this to get the code working as intended, but this requires at least Android 6: click

Best regards, Rob

hembachrterran commented 3 years ago

Hi, I faced this issue too after implement this plugin. If the app asks permissions in runtime and I add to AndroidManifest.xml: android:requestLegacyExternalStorage="true" and remove

<provider
          android:name="androidx.core.content.FileProvider"
          android:authorities="${applicationId}.fileprovider"
          android:exported="false"
          android:grantUriPermissions="true">
          <meta-data
              android:name="android.support.FILE_PROVIDER_PATHS"
              android:resource="@xml/file_paths" />
</provider>

The plugin work properly on Android 11 (target API 29). In this case I have an issue with Camera plugin from Capacitor (https://github.com/ionic-team/capacitor/issues/4514).

I tried to add back the provider to AndroidManifest, I could solve the merge problem with this modification: https://github.com/jkwiecien/EasyImage/issues/108#issuecomment-417521587 So the build works with these lines without error:

<provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true"
            tools:replace="android:authorities">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths"
                tools:replace="android:resource"></meta-data>
</provider>

After that the Capacitor Camera plugin works again, but this Document scanner crashed the app on call .scanDoc(). (Tested on Android 11), with the same error mentioned by @SchmidtKBS: Couldn't find meta-data for provider with authority hu.appname.app.com.scanlibrary.provider

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: hu.appname.app, PID: 8697
    java.lang.RuntimeException: Unable to start activity ComponentInfo{hu.appname.app/com.scanlibrary.ScanActivity}: java.lang.IllegalArgumentException: Couldn't find meta-data for provider with authority hu.appname.app.com.scanlibrary.provider
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3782)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3961)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:91)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:149)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:103)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2386)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:213)
        at android.app.ActivityThread.main(ActivityThread.java:8178)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101)
     Caused by: java.lang.IllegalArgumentException: Couldn't find meta-data for provider with authority hu.appname.app.com.scanlibrary.provider
        at androidx.core.content.FileProvider.parsePathStrategy(FileProvider.java:662)
        at androidx.core.content.FileProvider.getPathStrategy(FileProvider.java:635)
        at androidx.core.content.FileProvider.getUriForFile(FileProvider.java:441)
        at com.scanlibrary.PickImageFragment.openCamera(PickImageFragment.java:135)
        at com.scanlibrary.PickImageFragment.handleIntentPreference(PickImageFragment.java:87)
        at com.scanlibrary.PickImageFragment.init(PickImageFragment.java:68)
        at com.scanlibrary.PickImageFragment.onCreateView(PickImageFragment.java:57)
        at android.app.Fragment.performCreateView(Fragment.java:2550)
        at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1306)
        at android.app.FragmentManagerImpl.addAddedFragments(FragmentManager.java:2447)
        at android.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2226)
        at android.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2182)
        at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2083)
        at android.app.FragmentManagerImpl.dispatchMoveToState(FragmentManager.java:3073)
        at android.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3020)
        at android.app.FragmentController.dispatchActivityCreated(FragmentController.java:184)
        at android.app.Activity.performCreate(Activity.java:8093)
        at android.app.Activity.performCreate(Activity.java:8074)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1313)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3755)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3961) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:91) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:149) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:103) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2386) 
        at android.os.Handler.dispatchMessage(Handler.java:107) 
        at android.os.Looper.loop(Looper.java:213) 
        at android.app.ActivityThread.main(ActivityThread.java:8178) 
hembachrterran commented 3 years ago

Any update on this? @ChrisTomAlx

Cheers, Roland

Fayozjon commented 2 years ago

Still facing this issue

rkreutzer commented 2 years ago

@hembachrterran did you find a workaround for using Capacitor Camera and this plugin in the same app?

hembachrterran commented 2 years ago

@rkreutzer Sorry, but no. The problem is with this package. We skipped this feature. I have no time to make a PR. @ChrisTomAlx Any update on this problem? Can you provide a solution?

ChrisTomAlx commented 2 years ago

Sorry don't have the time to look at this at the moment @hembachrterran. But always welcoming PR's.

EDIT - Apologies accidentally closed the issue.

Cheers, Chris Neutrinos

colegioestomatologico commented 2 years ago

Hello, did anyone got a solution? Thank you so much.

rkreutzer commented 2 years ago

As a workaround for now, I removed the Capacitor/camera and installed cordova-plugin-camera. I removed the section from the AndroidManifest file and the camera now functions with this plug-in.

ciclick commented 1 year ago

@SchmidtKBS how can I apply your changes to the scanlibary in my project?

Thank you!