简体   繁体   English

如何在 android 中将 pdf 附加到意图发送(到 email、保管箱等)

[英]How to attach a pdf to intent to send (to email, dropbox, etc) in android

Hey so I save my pdf in external data storage.嘿,所以我将我的 pdf 保存在外部数据存储中。 Eg:例如:

Environment.getExternalStorageDirectory().getPath() + "/file.pdf"

Then, I try to attach it to intent to send:然后,我尝试将其附加到发送意图:

        File attachment = this.getFileStreamPath(fileDirectory + "/" + fileName);


        Uri uri = Uri.fromFile(attachment);

        Intent emailIntent = new Intent(Intent.ACTION_SEND);
        emailIntent.setDataAndType(Uri.parse("mailto:"), "text/plain"); // I have also tried "application/pdf"

        emailIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

        emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Calc PDF Report");
        emailIntent.putExtra(Intent.EXTRA_TEXT, " PDF Report");

        emailIntent.putExtra(Intent.EXTRA_STREAM, uri);
        startActivity(Intent.createChooser(emailIntent, "Send mail..."));
        finish();

and im getting the error:我得到了错误:

 Caused by: java.lang.IllegalArgumentException: File /storage/emulated/0/file.pdf contains a path separator

I am thinking it is something wrong with were I am saving my file, but can't find any examples that are up-to-date.我认为这是我保存文件的问题,但找不到任何最新的示例。

To share a file as an email attachment using intent, you need to use a FileProvider.要使用 Intent 将文件共享为 email 附件,您需要使用 FileProvider。

/**
 * Generate file content and returns uri file
 */
public static Uri generateFile(Context context) {
  File pdfDirPath = new File(context.getFilesDir(), "pdfs");
  pdfDirPath.mkdirs();

  File file = new File(pdfDirPath, "attachment.pdf");
  file.deleteOnExit();

  Uri uri = FileProvider.getUriForFile(context, context.getPackageName() + ".file.provider", file);
  FileOutputStream os = null;
  try {
    Logger.info("Generate file " + file.getAbsolutePath());
    os = new FileOutputStream(file);
    document.writeTo(os);
    document.close();
    os.close();
  } catch (IOException e) {
    e.printStackTrace();
  }
  return uri;
}

private void share(Context context) {
  Uri uri = generateFile(context);

  final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
  emailIntent.setType("text/plain");

  emailIntent.putExtra(Intent.EXTRA_STREAM, uri);
  emailIntent.putExtra(EXTRA_SUBJECT, "Send something");
  emailIntent.putExtra(Intent.EXTRA_TEXT, "You receive attachment");
  emailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

  startActivity(emailIntent);
}

In your app add the file provider definition:在您的应用中添加文件提供程序定义:

AndroidManifest.xml

<application
  android:name=".DemaApplication"
  android:allowBackup="false"
  android:icon="@mipmap/ic_launcher"
  android:label="@string/app_name"
  android:roundIcon="@mipmap/ic_launcher_round"
  android:supportsRtl="true"
  android:theme="@style/AppTheme">

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

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

At last but not least, you need to specify the file provider path (where are your files).最后但并非最不重要的一点是,您需要指定文件提供程序路径(您的文件在哪里)。 I hope this helps.我希望这有帮助。 Here , the official documentation about how to send email and attachment with intent.在这里,关于如何发送 email 和附件的官方文档。

Problem #1: getFileStreamPath() does not support subdirectories and is not related to external storage , where your file resides.问题 #1: getFileStreamPath()不支持子目录,并且与文件所在的外部存储无关。

Problem #2: Uri.fromFile() will not work on Android 7.0, as your app will crash with a FileUriExposedException .问题 #2: Uri.fromFile()在 Android 7.0 上不起作用,因为您的应用程序将因FileUriExposedException而崩溃。 To fix this and Problem #1, use FileProvider to set up a content Uri that you can use for EXTRA_STREAM .要解决此问题和问题 #1,请使用FileProvider设置可用于EXTRA_STREAMcontent Uri

Problem #3: ACTION_SEND does not use a "data" Uri (ie, your "mailto:" should not be there).问题#3: ACTION_SEND不使用“数据” Uri (即,您的"mailto:"不应该在那里)。

Problem #4: The MIME type of a PDF is not text/plain — as your comment notes, use application/pdf .问题 4:PDF 的 MIME 类型不是text/plain — 正如您的评论所指出的,使用application/pdf

Problem #5: getExternalStorageDirectory() is deprecated on Android 10 and higher, and you will not be able to write files there.问题 #5: getExternalStorageDirectory()在 Android 10 及更高版本上已弃用,您将无法在那里写入文件。 Consider using getExternaFilesDir(null) (called on a Context ) for a better location that works without permissions and on more Android OS versions.考虑使用getExternaFilesDir(null) (在Context上调用)以获得无需权限和更多 Android 操作系统版本的更好位置。

can't find any examples that are up-to-date找不到任何最新的示例

The documentation covers the use of ACTION_SEND .该文档涵盖ACTION_SEND的使用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM