Search code examples
androidandroid-intentgmailandroid-fileandroid-fileprovider

Android Intent to Gmail not attaching file by FileProvider "Unable to attach file"


When attaching file to Gmail I briefly see the file in attachments and then get Toast saying "Unable to attach file" and then it's gone. It works fine with Drive, Discord and other apps.. Also the file stays in attachments on emulator but when I send it, the mail is send without attachments. I have a simple .csv file and attach it via FileProvider.

Tried writing to internal storage, didn't help.

val fileLocation = File(requireContext().getExternalFilesDir("data"), "data.csv")

            // Saving the file into device
            val streamOut =
                FileOutputStream(fileLocation)
            streamOut.write(myString.toByteArray())
            streamOut.close()

            // Exporting

            val contentUri = FileProvider.getUriForFile(
                requireContext(),
                "mypackage.fileprovider",
                fileLocation
            )

            val fileIntent = Intent(Intent.ACTION_SEND)
                .setType("text/csv")
                .putExtra(Intent.EXTRA_SUBJECT, "Data")
                .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
                .putExtra(Intent.EXTRA_STREAM, contentUri)

            val chooser = Intent.createChooser(
                fileIntent,
                requireContext().resources.getText(R.string.send_to)
            )

            chooser.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)

            val resInfoList: List<ResolveInfo> = requireActivity().packageManager
                .queryIntentActivities(chooser, PackageManager.MATCH_DEFAULT_ONLY)

            for (resolveInfo in resInfoList) {
                val packageName = resolveInfo.activityInfo.packageName
                requireActivity().grantUriPermission(
                    packageName,
                    contentUri,
                    Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION
                )
            }

            requireActivity().startActivity(
                chooser
            )

provider_paths

<paths>
    <external-files-path
        name="data"
        path="." />
</paths>

Manifest

<provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="mypackage.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">

            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths" />
        </provider>

Solution

  • Solved it by changing file_paths.xml according to this template:

    <?xml version="1.0" encoding="utf-8"?>
    <paths>
      <external-path
        name="external"
        path="." />
      <external-files-path
        name="external_files"
        path="." />
      <cache-path
        name="cache"
        path="." />
      <external-cache-path
        name="external_cache"
        path="." />
    <files-path
        name="files"
        path="." />
    </paths>