Android 将资产中的文件附加到电子邮件

Android attaching file from assets to email

我的应用程序在资产文件夹中包含一个 PDF 文件。我的目标是创建一个电子邮件意图,打开一封附有此 PDF 的电子邮件。它正在运行,电子邮件打开并显示附加了正确名称和大小的 PDF。但是发送电子邮件时,未收到 PDF。发送邮件后 logcat 中唯一显示的是:

E/Gmail: gti:Cannot find size of file.

这很奇怪,因为我肯定能在电子邮件草稿中看到大小正确的附件。

这是我的代码:

android-manfiest.xml:

    <provider
        android:name="[my.package.name].core.helpers.utils.AssetsProvider"
        android:authorities="[my.package.name].fileprovider2"
        android:exported="true"
        android:grantUriPermissions="true" />

AssetsProvider.kt

class AssetsProvider : ContentProvider() {

    override fun openAssetFile(uri: Uri, mode: String): AssetFileDescriptor? {
        val am = context!!.assets
        val fileName = uri.lastPathSegment!!
        var afd: AssetFileDescriptor? = null
        try {
            afd = am.openFd(fileName)
        } catch (e: IOException) {
            e.printStackTrace()
        }

        // Confirms non null result
        Log.v("debug", "afd=" + (afd?.toString() ?: "null"))

        return afd
    }

    override fun onCreate(): Boolean {
        return true
    }

    override fun insert(uri: Uri, values: ContentValues?): Uri? {
        return null
    }

    override fun query(
        uri: Uri,
        projection: Array<String>?,
        selection: String?,
        selectionArgs: Array<String>?,
        sortOrder: String?
    ): Cursor? {
        return null
    }

    override fun update(
        uri: Uri,
        values: ContentValues?,
        selection: String?,
        selectionArgs: Array<String>?
    ): Int {
        return 0
    }

    override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int {
        return 0
    }

    override fun getType(uri: Uri): String? {
        return null
        //return "application/pdf"
    }
}

并创建 Intent(java 代码):

    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.setType("application/pdf");
    Uri assetUri = Uri.parse("content://[my.package.name].fileprovider2/[pdf_filename].pdf");
    intent.putExtra(Intent.EXTRA_STREAM, assetUri);
    activity.startActivityForResult(Intent.createChooser(intent, "Sending PDF..."), requestCode);

所以就像我说的,它打开 gmail 来撰写一封新电子邮件,PDF 附件在那里,正确的文件名和大小,但是当按下发送时,电子邮件没有任何附件就通过了,我得到 E/Gmail: gti:Cannot find size of file. 在 logcat 按发送时。

为什么附件发送不出去?

您的提供商的某些客户会想要使用 getName() and length() on DocumentFile 之类的东西。在这种情况下,客户端似乎正在尝试获取长度

反过来,这些函数将使用 ContentResolverquery() 您的供应商 the OpenableColumns。你的任务——如果你选择接受它——将在你的提供者中拥有你的query()功能return一个Cursor具有DISPLAY_NAMEand/orSIZE 列。 MatrixCursor 是实现此简单(如果笨重)API.

的简单(如果笨重)解决方案

固定供应商,如 FileProvider,为您处理。由于您正在推出自己的提供商,因此您需要自己处理。