【问题标题】:Sharing video + text with FileProvider causes Permission Denial exception与 FileProvider 共享视频 + 文本导致 Permission Denial 异常
【发布时间】:2016-08-29 19:31:23
【问题描述】:

我在与文件提供商和 Intent.EXTRA_TEXT 共享视频 .mp4 文件时被拒绝。

如果我删除该行:

shareIntent.putExtra(Intent.EXTRA_TEXT, "#myappHashtag");

一切正常。但我需要视频文件 + 额外文本。

我认为问题是:分享 uri 中的 caption=%23myappHashtag 但我该如何解决?

非常感谢。

private void ShareItem(File fileToShare) {

    String package_name = "com.lucagrillo.myapp";
    Uri uri = FileProvider.getUriForFile(this, package_name + ".fileprovider", fileToShare);
    Intent shareIntent = new Intent();
    shareIntent.setAction(Intent.ACTION_SEND);
    shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
    shareIntent.putExtra(Intent.EXTRA_TEXT, "#myappHashtag");
    shareIntent.setType(intentFormatType);

    startActivity(Intent.createChooser(shareIntent, getResources().getText(R.string.share_with)));

}

例外:

Writing exception to parcel
    java.lang.SecurityException: Permission Denial: reading android.support.v4.content.FileProvider uri content://com.lucagrillo.myapp.fileprovider/images/shareFile.mp4?caption=%23myappHashtag from pid=9630, uid=10093 requires the provider be exported, or grantUriPermission()
    at android.content.ContentProvider.enforceReadPermissionInner(ContentProvider.java:608)
    at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:483)
    at android.content.ContentProvider$Transport.enforceFilePermission(ContentProvider.java:474)
    at android.content.ContentProvider$Transport.openTypedAssetFile(ContentProvider.java:419)
    at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:313)
    at android.os.Binder.execTransact(Binder.java:565)

清单文件提供者:

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.lucagrillo.myapp.fileprovider"
    android:grantUriPermissions="true"
    android:exported="false">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/filepaths" />
</provider>

【问题讨论】:

  • 您在哪个版本的 Android 上进行测试?您能否也包含 FileProvider 的清单条目?
  • 我正在 android 7.0 上进行测试。刚刚注意到它可以与除 Whatsapp 之外的许多应用共享
  • 已添加清单文件提供程序
  • 共享的 URI 以 shareFile.mp4?caption=%23myappHashtag 结尾 - 这真的是您文件的名称吗?如果删除标题部分会怎样?
  • 删除 shareIntent.putExtra(Intent.EXTRA_TEXT... 结果 uri 没有 ?caption=%23myappHashtag,一切正常

标签: android securityexception android-fileprovider android-securityexception


【解决方案1】:

您错过了在您的Intent 上拨打addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) 的电话。如果您的 minSdkVersion 为 21 或更高,这将起作用,以便将对该 Uri 的权限授予处理 ACTION_SEND 请求的任何应用程序。

如果您的 minSdkVersion 低于 21,您将不得不为您的 Intent 授予所有可能的 ACTION_SEND 处理程序的权限。在那些较旧的设备上,addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) 仅授予您在 Intent 的“数据”方面(例如,new Intent(Intent.ACTION_VIEW, uri))中拥有的 Uri 的权限,而不是额外的 Uri 值。

你的代码看起来有点像这样:

  if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP) {
    i.addFlags(Intent.FLAG_GRANT_READ_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_READ_URI_PERMISSION);
    }
  }

(其中iIntentoutputUri 是您添加的Uri

另外,提醒一下:ACTION_SEND 实现没有义务同时支持EXTRA_TEXTEXTRA_STREAM

【讨论】:

  • 实际上,从Jelly Bean 开始的Android 会迁移您的流并自动将FLAG_GRANT_READ_URI_PERMISSION 添加到任何ACTION_SEND 意图中。
  • @ianhanniballake:这没有多大意义。 Uri extras 在 Android 5.0 之前不受 addFlags() 影响。它是否与您链接到的代码中的setClipData() 相关联?
  • 从链接的代码中可以看出,migrateExtraStreamToClipData 方法将 extras 转换为 ClipData,然后添加授权标志
  • @ianhanniballake:您是说将Uri 放在ClipData 中,然后添加标志,意味着Uri 是可读的,即使收件人没有使用@ 987654352@ 本身(例如,从EXTRA_STREAM 获取Uri)?如果是这样,这是一个很好的技术,我可以想到至少我需要更新的一本书的例子。
  • 对 URI 的访问以及如何从 Intent 中读取它是两个独立的事情。显然这只适用于 API 16+,但如果那是你的 minSdkVersion,事情就容易多了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多