androidandroid-intentandroid-fileproviderinternal-storageandroid-internal-storage

Fileprovider always throws IAE


I looked at all the answers on StackOverflow and there no answer for me.

Same error for real device and emulators.

Fileprovider always throws IllegalArgumentException

There is Manifest

<application
   ...

    <provider
        android:name="android.support.v4.content.FileProvider"
        android:grantUriPermissions="true"
        android:exported="false"
        android:authorities="${applicationId}">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/filepath"/>
    </provider>

</application>

There is filepath.xml

<paths>
<files-path
    name="logs"
    path="logs/" /></paths>

And there is code which always throw exception

        final Intent emailIntent = new Intent(Intent.ACTION_SEND);
        emailIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

        File file = new File(logger.getFileName());
        Uri uri = null;
        try {
            uri = FileProvider.getUriForFile(getContext(), BuildConfig.APPLICATION_ID, file);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        }

logger.getFileName() - returns real file name for example: "logs_22032019.txt"

What I already tried: Changes in Manifest such as: android:authorities="com.realname.of.package" Changes in filepath.xml

name="logs"

What I'm noted - there is really the path of files:

/data/user/0/com.app.realname/files/log.txt

But FileProvider in it goes to:

"log.txt" -> "/data/data/com.app.realname/files/log.txt"-->

NOTE: I need only INTERNAL storage.


Solution

  • logger.getFileName() - returns real file name for example: "logs_22032019.txt"

    That is not a valid filesystem path. It is a valid filename, but it does not say where that file is supposed to be on the device.

    This is your FileProvider configuration:

    <files-path
        name="logs"
        path="logs/" />
    

    For that, a File that would work is:

    File file = new File(getFilesDir(), "logs/"+logger.getFileName());
    

    there is really the path of files... But FileProvider in it goes to

    Those are the same filesystem location, for the primary device user.