Lamelynx / GodotGetImagePlugin-Android

Godot plugin to select image from gallery or camera on Android device.
MIT License
71 stars 4 forks source link

Causing some incompatibility with Godot-Android-Share-Plugin #6

Closed PseudoC0de closed 3 years ago

PseudoC0de commented 3 years ago

This is an interesting one. This plugin works great, but it seems like it is creating some problem with this other plugin: https://github.com/Shin-NiL/Godot-Android-Share-Plugin

The Share plugin was working fine until it stopped suddenly with the following error output:

05-18 15:18:17.911  6314  6394 D godot   : sharePic called
05-18 15:18:17.914  6314  6394 E godot   : The selected file can't be shared: /data/user/0/com.example.app/files/tempshot.png
05-18 15:18:17.915  6314  6394 E godot   : SharePic error: java.lang.IllegalArgumentException: Failed to find configured root that contains /data/user/0/com.example.app/files/tempshot.png

Eventually I got it to work again AFTER I disabled this GetImage plugin

So, when both plugins are enabled the sharing one doesn't work, but when GetImage is disabled sharing works.

There must be something causing an incompatibility when both are enabled that prevents the Share plugin from being able to open/find the image to share.

The issue may very well be fixable by changing something in the share plugin, but is there any idea what can be causing it in the first place? (Already opened an issue in the share plugin's github) @Lamelynx

Lamelynx commented 3 years ago

Probably som error/mismatch with AndroidManifest.xml

This may be the cause?:

            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_provider_paths"/>
PseudoC0de commented 3 years ago

Ok, so I did a quick test of this by removing that meta-data from both plugins just to see what happened.

GetImagePlugin : has meta data SharePlugin : removed meta data result = no difference, GetImage still works and Share still gives the same error

GetImagePlugin : removed meta data SharePlugin : has meta data result = no difference, GetImage still works and Share still gives the same error

GetImagePlugin : removed meta data SharePlugin : removed meta data result = app crashes on startup with the following error

05-18 18:58:21.985 18919 18919 E AndroidRuntime: FATAL EXCEPTION: main
05-18 18:58:21.985 18919 18919 E AndroidRuntime: Process: com.my.app, PID: 18919
05-18 18:58:21.985 18919 18919 E AndroidRuntime: java.lang.RuntimeException: Unable to get provider androidx.core.content.FileProvider: java.lang.IllegalArgumentException: Missing android.support.FILE_PROVIDER_PATHS meta-data
05-18 18:58:21.985 18919 18919 E AndroidRuntime:        at android.app.ActivityThread.installProvider(ActivityThread.java:7247)
05-18 18:58:21.985 18919 18919 E AndroidRuntime:        at android.app.ActivityThread.installContentProviders(ActivityThread.java:6783)
05-18 18:58:21.985 18919 18919 E AndroidRuntime:        at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6700)
05-18 18:58:21.985 18919 18919 E AndroidRuntime:        at android.app.ActivityThread.access$1300(ActivityThread.java:237)
05-18 18:58:21.985 18919 18919 E AndroidRuntime:        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1913)
05-18 18:58:21.985 18919 18919 E AndroidRuntime:        at android.os.Handler.dispatchMessage(Handler.java:106)
05-18 18:58:21.985 18919 18919 E AndroidRuntime:        at android.os.Looper.loop(Looper.java:223)
05-18 18:58:21.985 18919 18919 E AndroidRuntime:        at android.app.ActivityThread.main(ActivityThread.java:7660)
05-18 18:58:21.985 18919 18919 E AndroidRuntime:        at java.lang.reflect.Method.invoke(Native Method)
05-18 18:58:21.985 18919 18919 E AndroidRuntime:        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
05-18 18:58:21.985 18919 18919 E AndroidRuntime:        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
05-18 18:58:21.985 18919 18919 E AndroidRuntime: Caused by: java.lang.IllegalArgumentException: Missing android.support.FILE_PROVIDER_PATHS meta-data
05-18 18:58:21.985 18919 18919 E AndroidRuntime:        at androidx.core.content.FileProvider.parsePathStrategy(FileProvider.java:608)
05-18 18:58:21.985 18919 18919 E AndroidRuntime:        at androidx.core.content.FileProvider.getPathStrategy(FileProvider.java:579)
05-18 18:58:21.985 18919 18919 E AndroidRuntime:        at androidx.core.content.FileProvider.attachInfo(FileProvider.java:392)
05-18 18:58:21.985 18919 18919 E AndroidRuntime:        at android.app.ActivityThread.installProvider(ActivityThread.java:7242)
05-18 18:58:21.985 18919 18919 E AndroidRuntime:        ... 10 more
05-18 18:58:21.987  1595  2221 W ActivityTaskManager:   Force finishing activity com.my.app/com.godot.game.GodotApp

The error itself seems expected, but the fact that as long as one of the plugins has the metadata confirms that something is causing them to clash resources/identifiers and preventing the Share Plugin from working/accessing files.

If there are any more ideas on what to try I'll give them a shot.

Lamelynx commented 3 years ago

I think it's actual this file that is the problem file_provider_paths.xml

When GetImagePlugin is built it may overwrite SharePlugin's file_provider_paths.xml (SharePlugin has the same filename).

If we change the name of the file_provider_path.xml to ggi_file_provider_path.xml and edit AndroidManifest.xml with the new filename:

            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/ggi_file_provider_paths"/>

BTW, file_provider_path.xml is only used when grab image from camera.

I made the changes and a new .aar file. Thanks' for your feedback if it works or not.

PseudoC0de commented 3 years ago

I thought for sure your fix would work but it didn't. Instead it prevented the app from building correctly/exporting to the android device with this error:

> Task :processDebugManifest FAILED
C:\Users\Pseudo\Documents\programming_projects\Godot Projects\my_project\android\build\src\debug\AndroidManifest.xml:31:17-64 Error:
    Attribute meta-data#android.support.FILE_PROVIDER_PATHS@resource value=(@xml/ggi_file_provider_paths) from [GodotGetImage.release.aar] AndroidManifest.xml:31:17-64
    is also present at [GodotShare.release.aar] AndroidManifest.xml:23:17-60 value=(@xml/file_provider_paths).
    Suggestion: add 'tools:replace="android:resource"' to <meta-data> element at AndroidManifest.xml to override.

See http://g.co/androidstudio/manifest-merger for more information about the manifest merger.

> Task :mergeDebugResources

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':processDebugManifest'.
> Manifest merger failed : Attribute meta-data#android.support.FILE_PROVIDER_PATHS@resource value=(@xml/ggi_file_provider_paths) from [GodotGetImage.release.aar] AndroidManifest.xml:31:17-64
    is also present at [GodotShare.release.aar] AndroidManifest.xml:23:17-60 value=(@xml/file_provider_paths).
    Suggestion: add 'tools:replace="android:resource"' to <meta-data> element at AndroidManifest.xml to override.

Not sure why it is just now giving this error.

But anyway, I tried adding that tools:replace="android:resource" suggestion from the error but it didn't do anything.

However, after more messing around I added this extra path declaration to ggi_file_provider_paths.xml and everything works now.

<files-path name="filesRoot" path="/" />

This seems like more of a workaround than an actual fix, since your plugin shouldn't have to account for other plugins' path dependencies. At least the general cause of the initial reported error is known now.

Feel free to close out this issue if this fix is good enough.

Lamelynx commented 3 years ago

I finally manage to get this to work by extending the FileProvider class (see of this link):

GodotGetImage.tk: class GGIFileProvider : FileProvider()

Then used this in AndroidManifest.xml:

        <provider
            android:name=".GGIFileProvider"
            android:grantUriPermissions="true"
            android:exported="false"
            android:authorities="${applicationId}.ggi_FileProvider">

            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/ggi_file_provider_paths"/>
        </provider>

The android:resource="@xml/ggi_file_provider_paths"/> needed also to be unique to not overwrite other plugin files.