Android Question B4A FileProvider could not find meta-data error

jotajota52

Member
Hi!
While trying to send an e-mail using the FileProvider class, I'm getting the "Couldn't find meta-data for provider" error
in line 34 of the class:
B4X:
        Return fp.RunMethod("getUriForFile", Array(context, Application.PackageName & ".provider", f))

This is what I've added to the manifest file:

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"></meta-data>
</provider>
)
CreateResource(xml, provider_paths,
<files-path name="name" path="shared" />
)

and my code. I first create a list of files that the user marks as attachments to include in the message. The pl.tag is the filename in the custom list view:

B4X:
Dim filename As String
    checkedJobs.Initialize
    Dim i As Int=0
    rp.CheckAndRequest(rp.PERMISSION_WRITE_EXTERNAL_STORAGE)
    Wait For Activity_PermissionResult (Permission As String, result As Boolean)
    If result Then
        For i = 0 To clvFiles.GetSize - 1
            Dim p As B4XView = clvFiles.GetPanel(i)
            Dim pl As B4XView =p.GetView(1)
            Dim chk As B4XView = p.GetView(0)
            If chk.Checked Then
                filename=pl.tag
                File.Copy(JobDir,pl.Tag,Starter.Provider.SharedFolder,filename)
                checkedJobs.Add(filename)
            End If
        Next
    End If
   
    Dim msg As Email
    msg.Subject  ="Job files -" & DateTime.Date(DateTime.Now)
    msg.Body ="Database files from user: " & usuario & CRLF & "Date: " & DateTime.Date(DateTime.Now)
    For i=0 To checkedJobs.Size-1
        filename = checkedJobs.Get(i)
        msg.Attachments.Add(Starter.Provider.GetFileUri(filename))
    Next
   
   
    Dim intMsg As Intent = msg.GetIntent
    intMsg.Flags=1
   
    StartActivity(intMsg)

I have checked that the "shared" folder is created by the FileProvider class, and the selected files are passed correctly to the class GetFileUri sub.

Please help!!
 

Erel

Administrator
Staff member
Licensed User
Hi Erel, yes, the example runs fine. No error there
You will need to compare its code to your code.

I copied the class from the example
This is a mistake. You should use FileProvider library.

Why do you need the external storage permission?

Post the full error message from the logs.
 
Upvote 0

jotajota52

Member
You will need to compare its code to your code.


This is a mistake. You should use FileProvider library.

Why do you need the external storage permission?

Post the full error message from the logs.
Thank you Erel. The external storage permission was leftover from another sub which lets users copy the files elsewhere. I took it out
I loaded the FileProvider library and removed the class, but I'm still getting the same error.
B4X:
Dim filename As String
    File.MakeDir (File.DirInternal,"shared")
    provider.Initialize
    provider.UseFileProvider=True
    provider.SharedFolder =File.DirInternal & "/" & "shared"
    checkedJobs.Initialize
    Dim i As Int=0
    
    For i = 0 To clvFiles.GetSize - 1
        Dim p As B4XView = clvFiles.GetPanel(i)
        Dim pl As B4XView =p.GetView(1)
        Dim chk As B4XView = p.GetView(0)
        If chk.Checked Then
            filename=pl.tag
            File.Copy(JobDir,pl.Tag, provider.SharedFolder,filename)
            checkedJobs.Add(filename)
        End If
    Next
    
    Dim msg As Email
    msg.Subject  ="Job files -" & DateTime.Date(DateTime.Now)
    msg.Body ="Database files from user: " & usuario & CRLF & "Date: " & DateTime.Date(DateTime.Now)
    For i=0 To checkedJobs.Size-1
        filename = checkedJobs.Get(i)
        msg.Attachments.Add(provider.GetFileUri(filename))
    Next
        
    Dim intMsg As Intent = msg.GetIntent
    intMsg.Flags=1
    
    StartActivity(intMsg)

This is the error log:
Using FileProvider? true
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:132)
at SICAD.SAFO.fileprovider._getfileuri(fileprovider.java:122)
at SICAD.SAFO.main._cmdmail_click(main.java:5272)
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.BA.raiseEvent2(BA.java:197)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:193)
at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:80)
at android.view.View.performClick(View.java:6935)
at android.widget.TextView.performClick(TextView.java:12752)
at android.view.View$PerformClick.run(View.java:26214)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:7000)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:441)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)
Caused by: java.lang.IllegalArgumentException: Couldn't find meta-data for provider with authority SICAD.SAFO.provider
at androidx.core.content.FileProvider.parsePathStrategy(FileProvider.java:606)
at androidx.core.content.FileProvider.getPathStrategy(FileProvider.java:579)
at androidx.core.content.FileProvider.getUriForFile(FileProvider.java:417)
... 23 more
 
Upvote 0

jotajota52

Member
Where does this strange code come from:
B4X:
File.MakeDir (File.DirInternal,"shared")
    provider.Initialize
    provider.UseFileProvider=True
    provider.SharedFolder =File.DirInternal & "/" & "shared"
?

See the example.
I'm a bit confused. The example uses the class FileProvider and not the FileProvider Library.
I was using the class exactly as your example and you told me to use the library.
When I loaded the FileProvider Library, I had to remove the class and had to dim provider as FileProvider in Globals
and then I supposed I had to initialize the provider, set the use to true and define the shared folder, before using it.
 
Upvote 0

jotajota52

Member
No need to guess anything. See the example project.

The library and the class are exactly the same.
Thank you Erel. Deleted the strange code and left the Starter exactly as the example.
But I'm getting the exact same error on line 34(FileProvider)
 
Upvote 0

jotajota52

Member
Upload the project.
I'm afraid that's going to be a problem. The project is quite big (handles fiber optic networks - outside plant) and needs some databases with user login for it to work.
I would apreciate it if you could point me to some possible events that could make the java language to not accept the file path.
Could it be the package name (SICAD.SAFO) being in uppercase the problem ?
 
Upvote 0

Erel

Administrator
Staff member
Licensed User
Could it be the package name (SICAD.SAFO) being in uppercase the problem ?
It will take you exactly 2 minutes to test it with the example project. This is not the problem.

ould apreciate it if you could point me to some possible events that could make the java language to not accept the file path.
The code has nothing to do with Java.

It might be something in your manifest file.
 
Last edited:
Upvote 0

jotajota52

Member
Still no luck. As Erel said, it might be something wrong in my manifest file
This is what I have in my manifest file:
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
'android:authorities="$PACKAGE$.provider"
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" />
)

AddManifestText(
<uses-sdk android:minSdkVersion="5" android:targetSdkVersion="29"/>
<supports-screens android:largeScreens="true"
    android:normalScreens="true"
    android:smallScreens="true"
    android:anyDensity="true"/>
<uses-feature android:name="android.hardware.location.gps"/>
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="SICAD.SAFO.permission.MAPS_RECEIVE"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="SICAD.SAFO.permission.MAPS_RECEIVE"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
    <application
        android:icon="@drawable/icon"
        android:label="SAFODroid">
        android:theme="@style/LightTheme">
        <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
        <activity
            android:windowSoftInputMode="stateHidden"
            android:launchMode="singleTop"
            android:name=".main"
            android:label="SAFODroid"
            android:screenOrientation="unspecified">
            <intent-filter>
               <action android:name="android.intent.action.MAIN" />
               <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
           
        </activity>
        <activity android:name="com.google.android.gms.common.api.GoogleApiActivity"
          android:theme="@android:style/Theme.Translucent.NoTitleBar"
          android:exported="false"/>
            <meta-data
          android:name="com.google.android.gms.version"
          android:value="@integer/google_play_services_version" />
        <meta-data
          android:name="com.google.android.geo.API_KEY"
          android:value="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"/>
        <uses-library
              android:name="org.apache.http.legacy"
              android:required="false" />
        <activity
            android:windowSoftInputMode="stateHidden"
            android:launchMode="singleTop"
            android:name=".main"
            android:label="SAFODROID"
            android:screenOrientation="landscape">
            <intent-filter>
               <action android:name="android.intent.action.MAIN" />
               <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            </activity>
        <activity
            android:name="com.dropbox.core.android.AuthActivity"
            android:configChanges="orientation|keyboard"
            android:launchMode="singleTask" >
            <intent-filter>
                <data android:scheme="xxxxxxxxxxxxxx" />
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.BROWSABLE" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <service android:name=".starter">
        </service>
        <receiver android:name=".starter$starter_BR">
        </receiver>
    </application>
    )

   
'End of default text.
'********* TabStrip ***********************
CreateResource(drawable, background_tab.xml,
<selector xmlns:android="http://schemas.android.com/apk/res/android"
    android:exitFadeDuration="@android:integer/config_shortAnimTime">
    <item android:state_pressed="true" android:drawable="@color/background_tab_pressed" />
    <item android:state_focused="true" android:drawable="@color/background_tab_pressed"/>
    <item android:drawable="@android:color/transparent"/>
</selector>)
CreateResource(values, colors.xml,
<resources>
    <color name="background_tab_pressed">#6633B5E5</color>
</resources>)
'******************************************
 
Upvote 0
Top