Android Question How to get FileProvider working without entire RuntimePermission lib or entire com.android.support:support-v4 ?

JohnC

Expert
Licensed User
Longtime User
I need my app to be able to update itself, but also be as small as possible.

I also don't want my app to require permission to the user's storage/files, so I am using FileProvider.

The FileProvider class uses the function "GetSafeDirDefaultExternal" to get a directory that the shared file can be placed. This function is included in the RuntimePermission lib but including that lib adds 500k to my app. So, I found an alternative way to get that the same directory value using javaobject in this thread: https://www.b4x.com/android/forum/t...-value-without-runtimepermissions-lib.144955/

But it appears that in order to use the FileProvider class in needs some extra support class(es) that are also linked into the app when the RuntimePermission lib is an included lib, which again adds 500k to the app.

I was then able to eliminate the need for the RuntimePermission lib by including the below line:

B4X:
#AdditionalJar: com.android.support:support-v4

But this also adds like 500k to the app.

Then I found out that it seems the only class I really need to get fileprovider working is "android.support.v4.content.FileProvider".

So, is there a way that I can just include that single class without having to include the entire "com.android.support:support-v4" ?
 
Last edited:

JohnC

Expert
Licensed User
Longtime User
I tried but the app crashes as soon as it runs because the starter service tries to initialize the FileProvider:

B4X:
FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to get provider android.support.v4.content.FileProvider: java.lang.ClassNotFoundException: Didn't find class "android.support.v4.content.FileProvider" on path: DexPathList[[zip file "/data/app/com.omnisoft.vpndot-9oJauvaJ5BkLPB51S-hXAw==/base.apk"],nativeLibraryDirectories=[/data/app/com.omnisoft.vpndot-9oJauvaJ5BkLPB51S-hXAw==/lib/arm64, /system/lib64, /product/lib64]]
 
Upvote 0

Ivica Golubovic

Active Member
Licensed User
I tried but the app crashes as soon as it runs because the starter service tries to initialize the FileProvider:

B4X:
FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to get provider android.support.v4.content.FileProvider: java.lang.ClassNotFoundException: Didn't find class "android.support.v4.content.FileProvider" on path: DexPathList[[zip file "/data/app/com.omnisoft.vpndot-9oJauvaJ5BkLPB51S-hXAw==/base.apk"],nativeLibraryDirectories=[/data/app/com.omnisoft.vpndot-9oJauvaJ5BkLPB51S-hXAw==/lib/arm64, /system/lib64, /product/lib64]]
Ok, file provider uses android.support.v4.content.FileProvider. I will try to find solution for you to extract file provider only
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
not sure if any of this will help, but
your android.support.v4.content.FileProvider seems to have been replaced by androidx.core.content.FileProvider
an .aar is available from maven

the FileProvider class is in there and is looking for a lot of things. am attaching the full source for the fileprovider class only. if it can be built alone, you'll have your class.
i'm working on another project which is looking for many of the same imports. you have to find them first, and even then they depend on even more stuff.
 

Attachments

  • fileprovider.txt
    41.1 KB · Views: 209
Upvote 0

JohnC

Expert
Licensed User
Longtime User
"building a class" is getting beyond my lower-level knowledge of android.

So, please don't spend a lot of time for a solution just for me.

But if your work on your other project allows for an easy solution for my issue, then that would be great :)
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
actually, i was trying to save ivica golubovic a step by pointing to the .aar and the source for the class. he may have more patience than i do
 
Upvote 0

Ivica Golubovic

Active Member
Licensed User
Solution library TinyFileProvider

Copy to manifest:
Manifest text:
AddApplicationText(
  <provider
  android:name="b4a.tinyfileprovider.igolub.B4AFileProvider"
  android:authorities="$PACKAGE$.provider"
  android:exported="false"
  android:grantUriPermissions="true">
  <meta-data
  android:name="android.support.FILE_PROVIDER_PATHS"
  android:resource="@xml/provider_paths"/>
  </provider>
)
CreateResource(xml, provider_paths,
   <files-path name="name" path="shared" />
)

Extract lib to Additional Library folder.

This is standalone lib, you dont need FileProvider lib or any other lib or package.
 

Attachments

  • TinyFileProvider.zip
    9.4 KB · Views: 199
Last edited:
Upvote 1

JohnC

Expert
Licensed User
Longtime User
Got these errors:

(I see "lib64" in the error, so in case is means anything, I am using 32-bit B4A version 9.01)

B4X:
FATAL EXCEPTION: main
Process: com.mycompany.myapp, PID: 11631
java.lang.RuntimeException: Unable to get provider b4a.tinyfileprovider.igolub.B4AFileProvider: java.lang.ClassNotFoundException: Didn't find class "b4a.tinyfileprovider.igolub.B4AFileProvider" on path: DexPathList[[zip file "/data/app/com.mycompany.myapp-S_hdK65qQLVXHYzPxhY2MA==/base.apk"],nativeLibraryDirectories=[/data/app/com.mycompany.myapp-S_hdK65qQLVXHYzPxhY2MA==/lib/arm64, /system/lib64, /product/lib64]]
    at android.app.ActivityThread.installProvider(ActivityThread.java:6988)
    at android.app.ActivityThread.installContentProviders(ActivityThread.java:6528)
    at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6445)
    at EdHooker_42b8453bf7df105343083f1377c32094be493c49.hook(Unknown Source:120)
    at android.app.ActivityThread.access$1300(ActivityThread.java:219)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1859)
    at android.os.Handler.dispatchMessage(Handler.java:107)
    at android.os.Looper.loop(Looper.java:214)
    at android.app.ActivityThread.main(ActivityThread.java:7356)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: java.lang.ClassNotFoundException: Didn't find class "b4a.tinyfileprovider.igolub.B4AFileProvider" on path: DexPathList[[zip file "/data/app/com.mycompany.myapp-S_hdK65qQLVXHYzPxhY2MA==/base.apk"],nativeLibraryDirectories=[/data/app/com.mycompany.myapp-S_hdK65qQLVXHYzPxhY2MA==/lib/arm64, /system/lib64, /product/lib64]]
    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:196)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
    at android.app.AppComponentFactory.instantiateProvider(AppComponentFactory.java:147)
    at android.app.ActivityThread.installProvider(ActivityThread.java:6972)
    ... 11 more
 
Upvote 0

Ivica Golubovic

Active Member
Licensed User
Got these errors:

(I see "lib64" in the error, so in case is means anything, I am using 32-bit B4A version 9.01)

B4X:
FATAL EXCEPTION: main
Process: com.mycompany.myapp, PID: 11631
java.lang.RuntimeException: Unable to get provider b4a.tinyfileprovider.igolub.B4AFileProvider: java.lang.ClassNotFoundException: Didn't find class "b4a.tinyfileprovider.igolub.B4AFileProvider" on path: DexPathList[[zip file "/data/app/com.mycompany.myapp-S_hdK65qQLVXHYzPxhY2MA==/base.apk"],nativeLibraryDirectories=[/data/app/com.mycompany.myapp-S_hdK65qQLVXHYzPxhY2MA==/lib/arm64, /system/lib64, /product/lib64]]
    at android.app.ActivityThread.installProvider(ActivityThread.java:6988)
    at android.app.ActivityThread.installContentProviders(ActivityThread.java:6528)
    at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6445)
    at EdHooker_42b8453bf7df105343083f1377c32094be493c49.hook(Unknown Source:120)
    at android.app.ActivityThread.access$1300(ActivityThread.java:219)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1859)
    at android.os.Handler.dispatchMessage(Handler.java:107)
    at android.os.Looper.loop(Looper.java:214)
    at android.app.ActivityThread.main(ActivityThread.java:7356)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: java.lang.ClassNotFoundException: Didn't find class "b4a.tinyfileprovider.igolub.B4AFileProvider" on path: DexPathList[[zip file "/data/app/com.mycompany.myapp-S_hdK65qQLVXHYzPxhY2MA==/base.apk"],nativeLibraryDirectories=[/data/app/com.mycompany.myapp-S_hdK65qQLVXHYzPxhY2MA==/lib/arm64, /system/lib64, /product/lib64]]
    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:196)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
    at android.app.AppComponentFactory.instantiateProvider(AppComponentFactory.java:147)
    at android.app.ActivityThread.installProvider(ActivityThread.java:6972)
    ... 11 more
Yes, version of B4A can be a problem. On 12 works normaly.
 
Upvote 0

JohnC

Expert
Licensed User
Longtime User
My Bad, I forgot to include your new lib in the project (normally I would get a compile error reminding me to do that).

So, it compiled OK now - I will test it now....
 
Upvote 0

JohnC

Expert
Licensed User
Longtime User
OK, the app started, so hump #1 good.

Then when I tried to pass the file to the installer and it gave this error:

B4X:
java.lang.ClassNotFoundException: android.support$v4$content$FileProvider

Which was the name of the original class, so I changed the name to your new class in the GetFileUri sub:
B4X:
'Returns the file uri.

Public Sub GetFileUri (FileName As String) As Object
 
    If UseFileProvider = False Then
        Dim uri As JavaObject
        Return uri.InitializeStatic("android.net.Uri").RunMethod("parse", Array("file://" & File.Combine(SharedFolder, FileName)))
    Else
        Dim f As JavaObject
        f.InitializeNewInstance("java.io.File", Array(SharedFolder, FileName))
        Dim fp As JavaObject
        Dim context As JavaObject
        context.InitializeContext

        'fp.InitializeStatic("android.support.v4.content.FileProvider")
        fp.InitializeStatic("b4a.tinyfileprovider.igolub.B4AFileProvider")    '<-------- changed to new class name

        Return fp.RunMethod("getUriForFile", Array(context, Application.PackageName & ".provider", f))
    End If

End Sub

And now it works!

And now my APK is 500k smaller !!!

Thank you very much!
 
Last edited:
Upvote 0

Ivica Golubovic

Active Member
Licensed User
OK, the app started, so hump #1 good.

Then when I tried to pass the file to the installer and it gave this error:

B4X:
java.lang.ClassNotFoundException: android.support$v4$content$FileProvider

Which was the name of the original class, so I changed the name to your new class in the GetFileUri sub:
B4X:
'Returns the file uri.

Public Sub GetFileUri (FileName As String) As Object
 
    If UseFileProvider = False Then
        Dim uri As JavaObject
        Return uri.InitializeStatic("android.net.Uri").RunMethod("parse", Array("file://" & File.Combine(SharedFolder, FileName)))
    Else
        Dim f As JavaObject
        f.InitializeNewInstance("java.io.File", Array(SharedFolder, FileName))
        Dim fp As JavaObject
        Dim context As JavaObject
        context.InitializeContext

        'fp.InitializeStatic("android.support.v4.content.FileProvider")
        fp.InitializeStatic("b4a.tinyfileprovider.igolub.B4AFileProvider")    '<-------- changed to new class name

        Return fp.RunMethod("getUriForFile", Array(context, Application.PackageName & ".provider", f))
    End If

End Sub

And now it works!

And now my APK is 500k smaller !!!

Thank you very much!
You didn't fully read my post. You don't need an additional file provider. Delete the file provider class and just use TinyFileProvider. It contains all the methods from the FileProvider class...

Dim tp As TinyFileProvider
tp.GetFileUri(.....)
 
Upvote 0

JohnC

Expert
Licensed User
Longtime User
Ah, gotcha.

OK, switched over all references to just your lib and it's working great!

Thanks again.
 
Last edited:
Upvote 0
Top