kotlin发送带附件的电子邮件失败,带有URI

时间:2018-03-22 11:44:44

标签: android kotlin kotlin-android-extensions

我有以下kotlin代码来发送带附件的电子邮件:

val file = File(directory, filename)
file.createNewFile()
file.writeText("My Text", Charsets.UTF_8)
// ---- file is written succesfully, now let us
// try to get the URI and pass it for the intent

val fileURI = FileProvider.getUriForFile(this, "com.mydomain.myapp", file!!)

val emailIntent = Intent(Intent.ACTION_SEND).apply {
        putExtra(Intent.EXTRA_SUBJECT, "My subject"))
        putExtra(Intent.EXTRA_TEXT, "My message")
        putExtra(Intent.EXTRA_STREAM, fileURI)
    }
emailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
emailIntent.type = "text/plain"
startActivity(emailIntent)

现在,当我运行上面的代码时,我收到一个错误:

java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.ProviderInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference

用于fileURI分配行。如果我使用:

而不是FileProvider
putExtra(Intent.EXTRA_STREAM, file!!.toURI())

作为额外的intent参数,然后我收到一个错误:

W/Bundle: Key android.intent.extra.STREAM expected Parcelable but value was a java.net.URI.  The default value <null> was returned.

03-22 11:39:06.625 9620-9620 / com.secretsapp.secretsapp W / Bundle:尝试转换生成的内部异常:

W/Bundle: Key android.intent.extra.STREAM expected Parcelable but value was a java.net.URI.  The default value <null> was returned.
   W/Bundle: Attempt to cast generated internal exception:
   java.lang.ClassCastException: java.net.URI cannot be cast to android.os.Parcelable
   at android.os.Bundle.getParcelable(Bundle.java:945)

该文件是在全局Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)目录下的子目录下创建的,该应用程序也具有Manifest.permission.WRITE_EXTERNAL_STORAGE权限。有关如何获取文件的URI并将其附加到电子邮件意图的任何指示?

3 个答案:

答案 0 :(得分:1)

对于您的第一次尝试 - 这是正确的方法 - 您的<provider>没有权限值com.mydomain.myapp。清单中<provider>元素中的权限字符串必须与传递给getUriForFile()的第二个参数匹配。这包含在the documentation for FileProvider

对于第二次尝试,toURI()会返回URI,而不是Uri。虽然您可以将其切换为Uri.fromFile(),但一旦targetSdkVersion攀升至24或更高,您就会在Android 7.0+上崩溃。使用FileProvider方法。

答案 1 :(得分:0)

使用以下代码在Kotlin中发送电子邮件:

UILabel

答案 2 :(得分:0)

CommonsWare's answer的实现

清单:

<application> 
...
<provider
            android:name="android.support.v4.content.FileProvider" <- or use your provider implementation
            android:authorities="com.your.package.fileprovider" <- must end with .fileprovider
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths" />
        </provider>
...
</application

res / xml / provider_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path path="Android/data/" name="files_root" />
    <external-path path="." name="external_storage_root" />
</paths>

使用Sankar'实现,但是要获取文件uri,权限必须等于清单中声明的​​权限:

val fileURI = FileProvider.getUriForFile(context, "$packageName.fileprovider", yourFile)