将pdf附加到电子邮件,授予权限

Posted

技术标签:

【中文标题】将pdf附加到电子邮件,授予权限【英文标题】:Attach a pdf to email, grant permission 【发布时间】:2016-09-28 17:34:30 【问题描述】:

如果我授予READ_EXTERNAL_STORAGE 权限,一切正常,但我可以不问就让它工作吗?在我的模拟器上没有它它可以工作,但在真实设备上没有它就无法工作。

输出流

String fileName = "Körjorunal_" + lastUpdateTime + ".PDF";
String path = Environment.getExternalStorageDirectory().toString();

File file = new File(path, fileName)
pdfUri = Uri.fromFile(file);

OutputStream outputStream = new FileOutputStream(file);
document.writeTo(outputStream);
document.close();
outputStream.close();

意图

// Gets invoked on setup,
mShareIntent = new Intent();
mShareIntent.setAction(Intent.ACTION_SEND);
mShareIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
mShareIntent.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

// Creates document type.
mShareIntent.setType("application/pdf");

// Going via email:
mShareIntent.putExtra(Intent.EXTRA_SUBJECT, "Körjournal i bifogad PDF");

// Attach the PDf Uri.
mShareIntent.putExtra(Intent.EXTRA_STREAM, pdfUri);

mShareActionProvider.setShareIntent(mShareIntent);

清单

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

【问题讨论】:

【参考方案1】:

FLAG_GRANT_*_URI_PERMISSION(对于READWRITE)真的是因为Uri 来自您自己的ContentProvider。如果您想避免需要WRITE_EXTERNAL_STORAGE(以及多余的READ_EXTERNAL_STORAGE)权限:

步骤一:将文件写入internal storage,如getCacheDir()

第 2 步:使用 FileProvider 从内部存储中提供该文件

第 3 步:使用您现有的 ACTION_SEND 逻辑,替换您从 FileProvider 获得的 Uri

您将看到this sample project 中使用的模式。我的示例是针对ACTION_VIEW,而不是ACTION_SEND,否则它是非常接近的。

不过,如果您的minSdkVersion 低于 21,则一个关键区别在于您授予权限的方式。在 Android 4.4 及更低版本上,FLAG_GRANT_*_URI_PERMISSION 忽略了额外中的Uri 值。对于那些版本,我知道的唯一解决方案是手动授予每个可能的应用程序的权限(在您的情况下,每个 PDF 查看器)。

在this sample app 中,我使用ACTION_IMAGE_CAPTURE 拍照,然后使用FileProvider Uri 进行拍照(因为file Uri 的值是going away)。就像您使用EXTRA_STREAMUri 一样,我使用的是EXTRA_OUTPUT,所以我遇到了同样的Uri-in-an-extra 权限问题。所以,我经历了所有这些混乱:

  i.putExtra(MediaStore.EXTRA_OUTPUT, outputUri);

  if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP) 
    i.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
  
  else 
    List<ResolveInfo> resInfoList=
      getPackageManager()
        .queryIntentActivities(i, PackageManager.MATCH_DEFAULT_ONLY);

    for (ResolveInfo resolveInfo : resInfoList) 
      String packageName = resolveInfo.activityInfo.packageName;
      grantUriPermission(packageName, outputUri,
        Intent.FLAG_GRANT_WRITE_URI_PERMISSION |
          Intent.FLAG_GRANT_READ_URI_PERMISSION);
    
  

  startActivityForResult(i, CONTENT_REQUEST);

(这里,i 是我的ACTION_IMAGE_CAPTURE Intent

所以,我在 Android 4.4 及更早版本上授予任何ACTION_IMAGE_CAPTUREIntentthe rights to work with thisUri`。

【讨论】:

谢谢我正在寻找的东西,我必须通过这两个。【参考方案2】:

未经许可,您不能使用该功能。

如果您使用的是 Marshmallow 之前的 Android 版本,您只需将权限添加到 Manifest,它就不会再次请求。

但 Marshmallow 将权限分类为 Normal and Dangerous permissions。您必须在用户使用该功能之前请求危险权限。

【讨论】:

好的,谢谢,如果我在用户按下 mShareActionProvider.setOnShareTargetSelectedListener 时请求权限,将同时在 shareprovider 内部询问权限,我怎么能在没有请求权限的情况下停止此操作在 onCreate() 里面? 您首先请求许可,然后当且仅当许可被授予时,显示共享提供者。 我的意思是当用户按下 onCreateOptionsMenu() 而不是之前是否可以添加权限检查? 是的,您可以随时请求许可。检查我就此事发布的this question。您只需在您认为合适的地方申请the code。

以上是关于将pdf附加到电子邮件,授予权限的主要内容,如果未能解决你的问题,请参考以下文章

Node.js 和 Nodemailer:我们可以将 PDF 文档附加到电子邮件中吗?

Rails 3 - 从视图中渲染 PDF 并附加到电子邮件

如何在 Symfony2 中使用 Swiftmailer 将 PDF 附加到电子邮件

如何使用 barryvdh/laravel-dompdf 将 PDF 附加到 Laravel 的电子邮件中

如何在 PHP 中将特定 PDF 附加到电子邮件中?

如何在使用客户端凭据授予流程时在 JWT 令牌中附加或包含用户身份(用户名或电子邮件地址)