B4A Library [class] FileProvider - share files

Status
Not open for further replies.
Edit: FileProvider is included as an internal library now.
After investigating several issues with the current FileProvider code that you can find in the forum, I decided to make some improvements and implement it in a class.

Starting from Android 7 (API 24) you cannot directly share file uris with other applications. You need to use FileProvider.

The FileProvider class should work on all Android versions (4+).

Instructions:

1. Add a reference to FileProvider library.

2. Add to the manifest editor:
B4X:
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,
   <files-path name="name" path="shared" />
)
files-path = File.DirInternal

SS-2018-10-03_15.03.31.png


Current version: 1.00
 

Attachments

  • FileProviderExample.zip
    24.6 KB · Views: 3,088
Last edited:

incendio

Well-Known Member
Licensed User
Longtime User
Thanks, but there is still an issue with sending mail with attachement.

I make an email body to the code
B4X:
Sub btnSendEmail_Click
   Dim FileName As String = "b4a.png"
   'copy the shared file to the shared folder
   File.Copy(File.DirAssets, FileName, Starter.Provider.SharedFolder, FileName)
   Dim email As Email
   email.To.Add("[email protected]")
   email.Subject = "subject"
   email.Body = "This is a test" 'This is the added code
   email.Attachments.Add(Starter.Provider.GetFileUri(FileName))
   email.Attachments.Add(Starter.Provider.GetFileUri(FileName)) 'second attachment
   Dim in As Intent = email.GetIntent
   in.Flags = 1 'FLAG_GRANT_READ_URI_PERMISSION
   StartActivity(in)
End Sub

On my email (gmail), an error message pop up, Unable to attach file.
 
Last edited:

scsjc

Well-Known Member
Licensed User
Longtime User
I test all, and work fine... really work great.
Thanks !!!
 

incendio

Well-Known Member
Licensed User
Longtime User
There is something strange here.

Here are the steps
1. First clicked on Send Mail -> failed to load attachment
2. Second clicked, without quit application -> worked fine
3. Quit application then clicked again Send mail -> still worked fine
4. Uninstall app, then install again, first clicked -> failed to load attachment, second clicked and so on -> worked fine

I can reproduce the behavior by install and uninstall app.

Any idea, why this is happen ?

Another thing, on Lolipop, there is a shared folder created under DirInternal (i think), but on oreo, there wasn't such folder, where is shared folder created under Oreo?
 
Last edited:

KMatle

Expert
Licensed User
Longtime User

Erel

B4X founder
Staff member
Licensed User
Longtime User
@incendio please start a new thread for further discussion. It doesn't look relevant to FileProvider.

My apps are ok so far because I copy (file.copy...) the needed files to a folder my app has access to before I share anything or similar. So if the copy works, everything else works. Am I wrong here?
You must use FileProvider if you want to share any of these files with an intent.
 

GuyBooth

Active Member
Licensed User
Longtime User
After investigating several issues with the current FileProvider code that you can find in the forum, I decided to make some improvements and implement it in a class.
Current version: 1.00
How does this relate to the ExternalStorage Class (which contains considerably more code)?

Is its purpose completely different?
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
How does this relate to the ExternalStorage Class (which contains considerably more code)?
They are not related.

FileProvider allows you to share files with other applications using an intent.
ExternalStorage allows your app to access sd cards and usb devices.
 

FrankDev

Active Member
Licensed User
Longtime User
Hello,

I have a problem with the test program.
Image and text sharing are working fine.
With 'Mail' there is a problem
Android 8.1

Dim in As Intent = email.GetIntent

B4X:
--------- beginning of main
Copying updated assets files (2)
*** Service (starter) Create ***
Using FileProvider? true
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
Error occurred on line: 58 (Main)
java.lang.ClassCastException: android.net.Uri$HierarchicalUri cannot be cast to java.lang.String
 at anywheresoftware.b4a.phone.Phone$Email.getIntent(Phone.java:677)
 at anywheresoftware.b4a.phone.Phone$Email.GetIntent(Phone.java:694)
 at b4a.examplewewe.main._btnsendemail_click(main.java:430)
 at java.lang.reflect.Method.invoke(Native Method)
 at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:710)
 at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:339)
 at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:249)
 at java.lang.reflect.Method.invoke(Native Method)
 at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:139)
 at anywheresoftware.b4a.BA.raiseEvent2(BA.java:170)
 at anywheresoftware.b4a.BA.raiseEvent(BA.java:166)
 at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:80)
 at android.view.View.performClick(View.java:6304)
 at android.view.View$PerformClick.run(View.java:24803)
 at android.os.Handler.handleCallback(Handler.java:790)
 at android.os.Handler.dispatchMessage(Handler.java:99)
 at android.os.Looper.loop(Looper.java:171)
 at android.app.ActivityThread.main(ActivityThread.java:6633)
 at java.lang.reflect.Method.invoke(Native Method)
 at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
 
Status
Not open for further replies.
Top