Как прикрепить pdf к намерению отправить (на электронную почту, dropbox и т. Д. c) в android - PullRequest
0 голосов
/ 05 апреля 2020

Эй, я сохраняю свой pdf во внешнем хранилище данных. Например:

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

Затем я пытаюсь прикрепить его к намерению отправить:

        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();

и я получаю сообщение об ошибке:

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

Я думаю что-то не так, где я сохраняю свой файл, но не могу найти ни одного актуального примера.

Ответы [ 2 ]

1 голос
/ 08 апреля 2020

Чтобы поделиться файлом как вложением электронной почты с помощью намерения, вам необходимо использовать 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);
}

В своем приложении добавить определение поставщика файлов:

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>

Наконец, что не менее важно, вам нужно указать путь к файлу провайдера (где находятся ваши файлы). Надеюсь, это поможет. Здесь , официальная документация о том, как отправить электронное письмо и вложение с намерением.

1 голос
/ 05 апреля 2020

Проблема № 1: getFileStreamPath() не поддерживает подкаталоги и не связана с внешним хранилищем , в котором находится ваш файл.

Проблема № 2: Uri.fromFile() работать не будет Android 7.0, поскольку ваше приложение обработает sh с FileUriExposedException. Чтобы устранить эту проблему и проблему № 1, используйте FileProvider, чтобы установить content Uri, который можно использовать для EXTRA_STREAM.

Проблема № 3: ACTION_SEND не использует «данные» "Uri (т. Е. Ваш "mailto:" не должен быть там).

Проблема № 4: MIME-тип PDF не text/plain - в качестве примечаний к комментарию используйте application/pdf.

Проблема № 5: getExternalStorageDirectory() устарела для Android 10 и выше, и вы не сможете записывать туда файлы. Попробуйте использовать getExternaFilesDir(null) (вызывается на Context) для улучшения местоположения, которое работает без разрешений, и для более Android версий ОС.

не может найти примеры, которые соответствуют -дата

Документация охватывает использование ACTION_SEND.

...