如何在安卓设备上分享PDF文件?

5
我尝试从android/data/mypackage/files/file.pdf分享一个pdf文件。我还在此应用程序中生成这些pdf文件,但当我尝试分享时,pdf文件不会出现在电子邮件附件的已附加文件中,或者谷歌云存储会显示类似于“无数据可共享”的消息。 下面是我的分享pdf代码:
            val aName = intent.getStringExtra("iName")
            val file = File(this.getExternalFilesDir(null)?.absolutePath.toString(), "$aName")
            val shareIntent = Intent(Intent.ACTION_SEND)
            shareIntent.putExtra(Intent.EXTRA_STREAM,  file)
            shareIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
            shareIntent.type = "application/pdf"
            startActivity(Intent.createChooser(shareIntent, "share.."))
            Toast.makeText(this,"$file",Toast.LENGTH_SHORT).show()

当我用toast查看时,pdf路径看起来正确: SS


你尝试过这个吗?https://dev59.com/H2Ml5IYBdhLWcg3w966L - Amit pandey
你应该会在 Android 7.0 及以上版本中遇到 FileUriExposedException 异常。请使用 FileProvider - CommonsWare
如果是针对 Android 7.0 及以下版本,应该怎么做呢?@CommonsWare - gumuruh
@gumuruh: FileProvider 应该能够在 Android 15 或更早的版本上正常工作。但是,对于可见于外部存储的文件,您也可以使用 Uri.forFile() 方法,这样也可能起作用。 - CommonsWare
2个回答

8
问题在于您没有使用URI,只发送了路径,需要几个步骤。
提供程序路径
您需要在res文件夹的xml文件夹下创建provider_paths.xml:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-files-path
        name="files_root"
        path="/" />
</paths>

应用程序下的清单中设置提供者:

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

获取URI

fun uriFromFile(context:Context, file:File):Uri {
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
  {
    return FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", file)
  }
  else
  {
    return Uri.fromFile(file)
  }
}

你的最终代码:

val aName = intent.getStringExtra("iName")
            val shareIntent = Intent(Intent.ACTION_SEND)
            shareIntent.putExtra(Intent.EXTRA_STREAM,  uriFromFile(context,File(this.getExternalFilesDir(null)?.absolutePath.toString(), "$aName")))
            shareIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
            shareIntent.type = "application/pdf"
            startActivity(Intent.createChooser(shareIntent, "share.."))

我没有测试这段代码,是凭记忆写的,请告诉我它是否适用于你。


1
我尝试使用应用程序时出现错误,停止工作并显示以下内容:java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Android/data/md.merit.strangatorul/files/2020-11-13_12:47:45.pdf,在以下行中:FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", file)。 - Andrei Meriacre
1
编辑了 Provider 路径文件,请现在检查。 - Bogdan Android
我从一月份开始一直在尝试解决这个问题,阅读了不同的答案,但每次都出现以下错误:Activity com.android.internal.app.ChooserActivity has leaked IntentReceiver com.android.internal.app.ChooserActivity$1@4afad61 that was originally registered here. Are you missing a call to unregisterReceiver()? - Raunit Verma
is that acceptable answer? - gumuruh
@gumuruh 这是可行的答案。 - Bogdan Android

0
在Kotlin中: 将res/xml文件夹添加provider_path.xml文件 编写代码:
   <?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path name="external_files" path="."/>
</paths>

然后在清单文件中添加代码: <application ..>

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

添加以下功能到活动文件中:
private fun sharePDF(file:File ) {
      //  val file = File(pdfFilePath)
        val uri = Uri.fromFile(file)
        val URI = FileProvider.getUriForFile(
            this@MainActivity,
            BuildConfig.APPLICATION_ID + ".provider",
            file
        )
        val intent = Intent(Intent.ACTION_SEND)
        intent.type = "application/pdf"
        intent.putExtra(Intent.EXTRA_STREAM, URI)
        intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
        startActivity(Intent.createChooser(intent, "Share PDF"))
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接