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

时间:2016-05-30 20:28:49

标签: android android-intent file-permissions email-attachments outputstream

如果我授予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" />

2 个答案:

答案 0 :(得分:1)

FLAG_GRANT_*_URI_PERMISSION(对于READWRITE)确实适用于Uri来自您自己ContentProvider的地方。如果您想避免需要WRITE_EXTERNAL_STORAGE(和多余的READ_EXTERNAL_STORAGE)权限:

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

步骤2:使用FileProvider

从内部存储中提供该文件

第3步:使用现有的ACTION_SEND逻辑代替Uri

获得的FileProvider

您将在this sample project中看到该模式。我的示例适用于ACTION_VIEW,而非ACTION_SEND,但不是紧密匹配。

但是,如果您的minSdkVersion低于21,那么一个关键区别在于您授予权限的方式。在Android 4.4及更低版本中,Uri会忽略其他内容的FLAG_GRANT_*_URI_PERMISSION值。对于这些版本,我所知道的唯一解决方案是手动为每个可能的应用程序授予权限(在您的情况下,每个PDF查看器)。

this sample app中,我使用ACTION_IMAGE_CAPTURE来拍照,我使用了FileProvider Uri(因为file Uri值为going away)。就像您将EXTRA_STREAMUri一起使用一样,我正在使用EXTRA_OUTPUT,因此我遇到了同样的Uri - 额外的权限问题。所以,我经历了所有这些混乱:

  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_CAPTURE Intent the rights to work with this Uri`。

答案 1 :(得分:0)

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

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

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