Android Question Issues using FileProvider

shhammer5634

Member
Licensed User
Longtime User
I'm trying to add FileProvider as described in this post:

To an existing app that I'm trying to bring up to date for newer phones. At a few places in the code, I allow the user to e-mail a file to anyone they wish. And of course if they are SDK 24 or higher, the old way of sharing a file doesn't work.

The phone this is being tested on is Android 8
Current version of b4a is 9.5

The demo, as provided in the post, works on this phone.

I have copied the FileProvider.bas file into my project and added as a module. I added the code into the manifest, added the code to the Starter module, and adjusted my app code based on the btnSendEmail_Click SUB in the sample app. The file being attached is a simple text file.
B4X:
    Dim msg As Email
    File.Copy(File.DirRootExternal & "/Inventory", strReportName, Starter.Provider.SharedFolder, strReportName)
    msg.Subject = "Inventory comparison file"
    msg.Attachments.Add(Starter.Provider.GetFileUri(strReportName))
    Dim in As Intent = msg.GetIntent
    in.Flags = 1
    StartActivity(msg.GetIntent)
When executing the code, it crashes in Starter.Provider.GetFileURI(strReportName) with the following message:
B4X:
*** Service (starter) Create ***
Using FileProvider? true
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
No wakelock.
Error occurred on line: 34 (FileProvider)
java.lang.reflect.InvocationTargetException
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4j.object.JavaObject.RunMethod(JavaObject.java:131)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:348)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
    at anywheresoftware.b4a.debug.Debug.delegate(Debug.java:262)
    at BHCS.Inventory.fileprovider._getfileuri(fileprovider.java:47)
    at BHCS.Inventory.main$ResumableSub_bCExport_Click.resume(main.java:7240)
    at BHCS.Inventory.main._bcexport_click(main.java:7021)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:351)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:180)
    at de.donmanfred.IconButtonWrapper$1.onClick(IconButtonWrapper.java:73)
    at android.view.View.performClick(View.java:6274)
    at android.view.View$PerformClick.run(View.java:24859)
    at android.os.Handler.handleCallback(Handler.java:789)
    at android.os.Handler.dispatchMessage(Handler.java:98)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6710)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:770)
Caused by: java.lang.IllegalArgumentException: Failed to find configured root that contains /data/data/BHCS.Inventory/files/shared/Geraghty-Gary.Jewett-Comparison.csv
    at androidx.core.content.FileProvider$SimplePathStrategy.getUriForFile(FileProvider.java:744)
    at androidx.core.content.FileProvider.getUriForFile(FileProvider.java:418)
    ... 29 more

I'm stuck. If anyone has any ideas or pointers I would appreciate the help.

Thanks
 
Last edited:

JohnC

Expert
Licensed User
Longtime User
Upvote 0

shhammer5634

Member
Licensed User
Longtime User
Can you provide the code that contains line "34" in the FileProvider module?
B4X:
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")
        Return fp.RunMethod("getUriForFile", Array(context, Application.PackageName & ".provider", f))
    End If
End Sub

This line is line 34: Return fp.RunMethod("getUriForFile", Array(context, Application.PackageName & ".provider", f))
 
Upvote 0

JohnC

Expert
Licensed User
Longtime User
Are you sure you included all three parts of the manifest as shown in that FileProvider sample?
 
Upvote 0

shhammer5634

Member
Licensed User
Longtime User
Are you sure you included all three parts of the manifest as shown in that FileProvider sample?

My complete manifest:
B4X:
'This code will be applied to the manifest file during compilation.
'You do not need to modify it in most cases.
'See this link for for more information: https://www.b4x.com/forum/showthread.php?p=78136
AddManifestText(
<uses-sdk android:minSdkVersion="17" android:targetSdkVersion="30"/>
<supports-screens android:largeScreens="true" 
    android:normalScreens="true"
    android:smallScreens="true" 
    android:anyDensity="true"/>)
AddManifestText(<uses-feature android:name="android.hardware.telephony" android:required="false" />)
AddManifestText(<uses-feature android:name="android.hardware.camera" android:required="false" />)
AddManifestText(<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />)
AddManifestText(<uses-feature android:name="android.hardware.camera.flash" android:required="false" />)
AddPermission("android.permission.INTERNET")
AddPermission("android.permission.ACCESS_FINE_LOCATION")
AddPermission("android.permission.WAKE_LOCK")
AddPermission("android.permission.DEVICE_POWER")
AddPermission("android.permission.READ_PHONE_STATE")
AddPermission("android.permission.VIBRATE")
SetApplicationAttribute(android:icon, "@drawable/icon")
SetApplicationAttribute(android:label, "$LABEL$")
SetActivityAttribute(main, android:windowSoftInputMode, "stateHidden|adjustPan")

#Added for FileProvider
####################################################
AddManifestText(<uses-permission
   android:name="android.permission.WRITE_EXTERNAL_STORAGE"
   android:maxSdkVersion="18" />
)
AddApplicationText(
  <provider
  android:name="android.support.v4.content.FileProvider"
  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,
   <file-path name="name" path="shared" />
)
##################################
AddPermission(android.permission.REQUEST_INSTALL_PACKAGES)
 
Upvote 0

JohnC

Expert
Licensed User
Longtime User
OK, in your manifest file you have:
B4X:
<file-path name="name" path="shared" />

It should be "files-path" (add "s" to "file"):
B4X:
<files-path name="name" path="shared" />
 
Last edited:
Upvote 0

JohnC

Expert
Licensed User
Longtime User
I'm assuming you simply cut-and-pasted the manifest code, so if the above fixes your problem, then I'm real curious how the "s" went missing! :)
 
Upvote 0

JohnC

Expert
Licensed User
Longtime User
Upvote 0
Top