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

bug: Filesystem.stat() crashes app with content urls #308

Open
1 of 4 tasks
ThomasKientz opened this issue Apr 29, 2020 · 9 comments · May be fixed by #2078
Open
1 of 4 tasks

bug: Filesystem.stat() crashes app with content urls #308

ThomasKientz opened this issue Apr 29, 2020 · 9 comments · May be fixed by #2078

Comments

@ThomasKientz
Copy link

Bug Report

Capacitor Version

npx cap doctor output:

  @capacitor/cli 2.0.1
  @capacitor/core 2.0.1
  @capacitor/android 2.0.1

Affected Platform(s)

  • Android
  • iOS
  • Electron
  • Web

Description

const data = await Filesystem.readFile({
  path,
})
const { size } = await Filesystem.stat({
  path,
})

No issues with Filesystem.readFile

With Filesystem.stat the app crashed and I got the following error in the Android Studio console

2020-04-29 17:06:28.150 6188-6388/com.boomerang.app V/Capacitor/Plugin: To native (Capacitor plugin): callbackId: 77806689, pluginId: Filesystem, methodName: stat
2020-04-29 17:06:28.150 6188-6388/com.boomerang.app V/Capacitor: callback: 77806689, pluginId: Filesystem, methodName: stat, methodData: {"path":"content:\/\/com.android.providers.media.documents\/document\/image%3A24"}
2020-04-29 17:06:28.152 6188-6340/com.boomerang.app E/Capacitor: Serious error executing plugin
    java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Method.invoke(Native Method)
        at com.getcapacitor.PluginHandle.invoke(PluginHandle.java:99)
        at com.getcapacitor.Bridge$1.run(Bridge.java:520)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:214)
        at android.os.HandlerThread.run(HandlerThread.java:67)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.hashCode()' on a null object reference
        at com.getcapacitor.plugin.Filesystem.getDirectory(Filesystem.java:67)
        at com.getcapacitor.plugin.Filesystem.getFileObject(Filesystem.java:90)
        at com.getcapacitor.plugin.Filesystem.stat(Filesystem.java:440)
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.getcapacitor.PluginHandle.invoke(PluginHandle.java:99) 
        at com.getcapacitor.Bridge$1.run(Bridge.java:520) 
        at android.os.Handler.handleCallback(Handler.java:883) 
        at android.os.Handler.dispatchMessage(Handler.java:100) 
        at android.os.Looper.loop(Looper.java:214) 
        at android.os.HandlerThread.run(HandlerThread.java:67) 
2020-04-29 17:06:28.153 6188-6340/com.boomerang.app E/AndroidRuntime: FATAL EXCEPTION: CapacitorPlugins
    Process: com.boomerang.app, PID: 6188
    java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
        at com.getcapacitor.Bridge$1.run(Bridge.java:529)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:214)
        at android.os.HandlerThread.run(HandlerThread.java:67)
     Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Method.invoke(Native Method)
        at com.getcapacitor.PluginHandle.invoke(PluginHandle.java:99)
        at com.getcapacitor.Bridge$1.run(Bridge.java:520)
        at android.os.Handler.handleCallback(Handler.java:883) 
        at android.os.Handler.dispatchMessage(Handler.java:100) 
        at android.os.Looper.loop(Looper.java:214) 
        at android.os.HandlerThread.run(HandlerThread.java:67) 
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.hashCode()' on a null object reference
        at com.getcapacitor.plugin.Filesystem.getDirectory(Filesystem.java:67)
        at com.getcapacitor.plugin.Filesystem.getFileObject(Filesystem.java:90)
        at com.getcapacitor.plugin.Filesystem.stat(Filesystem.java:440)
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.getcapacitor.PluginHandle.invoke(PluginHandle.java:99) 
        at com.getcapacitor.Bridge$1.run(Bridge.java:520) 
        at android.os.Handler.handleCallback(Handler.java:883) 
        at android.os.Handler.dispatchMessage(Handler.java:100) 
        at android.os.Looper.loop(Looper.java:214) 
        at android.os.HandlerThread.run(HandlerThread.java:67) 
@jcesarmobile
Copy link
Member

can you provide a sample app?

@ThomasKientz
Copy link
Author

@jcesarmobile I made further tests. Crash only occurs with paths starting content://. I got those paths from an intent (https://github.com/darryncampbell/darryncampbell-cordova-plugin-intent#intentshimonintent)

Here is a sample app :
https://github.com/ThomasKientz/capacitor-fs-issue-repro

@jcesarmobile
Copy link
Member

jcesarmobile commented Apr 30, 2020

Yeah, content urls are only supported by readFile at the moment because they are not regular filesystem url, they belong to other app and you can't do Filesystem tasks on another app file, other than reading it if it was shared, and maybe stat could be implemented with a lot of content resolver code.
But should definitely not crash.

@jcesarmobile jcesarmobile changed the title bug: Filesystem.stat() crashes app bug: Filesystem.stat() crashes app with content urls Apr 30, 2020
@ThomasKientz
Copy link
Author

ThomasKientz commented Apr 30, 2020

I have created a plugin to read a file's name and size from a content uri : https://github.com/ThomasKientz/capacitor-plugin-file-infos

Would be nice to implement it inside FS plugin imo !

@tobiasmuecksch
Copy link

tobiasmuecksch commented Jul 2, 2020

Same issue with the copyFile method. Works perfectly on iOS but not on Android....

@jcesarmobile
Copy link
Member

This issue is about content urls, that's an android thing, so can't work on iOS.
If you mean copyFile doesn't work on Android, report a new issue and provide more information.

@tobiasmuecksch
Copy link

tobiasmuecksch commented Jul 2, 2020

What I mean is, that Filesystem.copy()doesn't work with content:// urls too. This issue doesn't only effect the Filesystem.stat() method.
My iOS comment is about my expectation, that I can use the same Ionic-App-code for android and iOS. That means passing a Filesystem URI (which I got by some plugin) to any of the FileSystem plugin methods and the Filesystem plugin just does it's magic as it is supposed too. But as often, I have to provide some extra code for Android.... As far as I can tell, in order to copy a file from a content:// URI I'd have to read the file as base64 and then write it to the data-directory for example. That is tremendous overhead which I'd feel very uncomfortable with. Is there any other way?

@tobiasmuecksch
Copy link

tobiasmuecksch commented Jul 2, 2020

I think important information like that, should be displayed way more prominent in the docs. The current hint is not sufficiently clear at all.

Additionally, the Filesystem API supports using full file:// paths, or reading content:// files on Android. Simply leave out the directory param to use a full file path.
Source: https://capacitorjs.com/docs/apis/filesystem#understanding-directories-and-files

@tobiasmuecksch
Copy link

I found a solution / workaround.

I'm now converting content:// URLs to file:// with the following plugin:

https://ionicframework.com/docs/native/file-path

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