【问题标题】:Android attaching file from assets to emailAndroid将文件从资产附加到电子邮件
【发布时间】:2019-10-26 06:19:57
【问题描述】:

我的应用在 assets 文件夹中包含一个 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 附件在那里,正确的文件名和大小,但是当按下发送时,电子邮件没有任何附件,我在 logcat 中得到E/Gmail: gti:Cannot find size of file.按发送。

为什么附件没有发送?

【问题讨论】:

  • 有您的query() 支持查询OpenableColumns。例如,请参阅this
  • @CommonsWare 谢谢你!只需要为该列返回正确的文件长度。

标签: android android-intent android-fileprovider


【解决方案1】:

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

反过来,这些函数将使用ContentResolverquery() 你的提供者the OpenableColumns。你的任务——如果你选择接受它——将是让你的提供程序中的query() 函数返回一个Cursor,其中包含DISPLAY_NAME 和/或SIZE 列的值。 MatrixCursor 是实现这个简单(如果笨拙)API 的简单(如果笨拙)解决方案。

FileProvider 这样的预制提供商会为您处理这个问题。由于您正在滚动自己的提供程序,因此您需要自己处理。

【讨论】:

  • 确认这回答了我的问题,谢谢。如果文件在资产中,FileProvider 应该工作吗?我假设我需要为资产滚动自己的ContentProvider
  • @jefferson:FileProvider 不处理资产。 FWIW,@ 987654324@。你的应该没问题,虽然我会从getType() 返回一个真正的 MIME 类型,而!! 在应用于来自外部各方的输入时让我感到紧张。此外,您可能需要考虑是否真的要导出此提供程序——如果将FLAG_GRANT_READ_URI_PERMISSION 添加到您的Intent,则不需要导出提供程序,这会逐步提高安全性。
猜你喜欢
  • 1970-01-01
  • 2014-06-25
  • 2017-10-25
  • 1970-01-01
  • 1970-01-01
  • 2015-07-26
  • 2016-12-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多