FileProvider.getUriForFile 与 Uri.fromFile - 除了权限之外还有其他区别吗

Jen*_*eni 5 android uri android-fileprovider

在我的 Andoroid 应用程序中,我想让用户使用用户喜欢的任何发送方法(例如电子邮件、Skype、Viber、蓝牙等)发送我的应用程序生成的文件,我正在使用 Intent.ACTION_SEND,如下所示:

File readF = new File(fullFileName);
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_SUBJECT, getResources().getString(R.string.some_subject));
intent.putExtra(Intent.EXTRA_TEXT, getResources().getString(R.string.some_message_body));
Uri uri = FileProvider.getUriForFile(this, "my.package.fileprovider", readF);
intent.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(Intent.createChooser(intent, getResources().getString(R.string.some_info_message));
Run Code Online (Sandbox Code Playgroud)

正如预期的那样,它成功地通过 Gmail 和蓝牙发送文件。

但是当用户选择Skype 时,文件被发送,但它的名字被改变了

当用户选择Viber 时,不会发送任何内容。

如果我只改变构建 Uri 的方式:

Uri uri = Uri.fromFile(new File("/some/publicly/available/file"));
Run Code Online (Sandbox Code Playgroud)

然后该文件通过 Skype 和 Viber 成功发送,并保留名称。

那么在 Intent 中使用 FileProvider 与直接使用公共文件有什么区别。

Com*_*are 4

我使用 Intent.ACTION_SEND 如下:

我建议您添加Intent.FLAG_GRANT_READ_URI_PERMISSION该内容Intent

然后,文件将通过 Skype 和 Viber 成功发送,并且名称将被保留。

直到您targetSdkVersion达到 24 或更高,并且您开始在 Android 7.0+ 上运行您的应用程序。然后,您的应用程序崩溃并显示FileUriExposedException.

然后,文件将通过 Skype 和 Viber 成功发送,并且名称将被保留。

就目前而言,也许吧。这些应用程序的作者以及任何其他人没有义务维护您的文件名。他们可以做任何他们想做的事情,因为这是他们的应用程序,而不是你的。

那么在 Intent 中使用 FileProvider 与直接使用公共文件有什么区别呢?

FileProvider大致类似于 Web 服务器。它允许应用程序与其他应用程序共享内容,而这些应用程序不一定能够直接访问底层文件。Google 正试图摆脱让外部存储成为随机垃圾倾倒场的情况ACTION_SEND,以支持诸如 Android 7.0+ 之类的东西,StrictMode设置为“开箱即用”,如果您尝试传递file Uri(例如, Uri.fromFile())。

  • @Jeni:“我认为这对他们来说应该是透明的”——理想情况下,确实如此。由于“FileProvider”使用文件名作为“content”“Uri”的“文件名”部分,并且由于“ContentResolver”上的“openInputStream()”同时处理“文件”和“内容”,因此理想情况下 Skype 和 Viber 会同时处理这两者“Uri”的形式相同。显然,他们没有。除了在这些公司找到一份工作并尝试从内部修复他们的代码之外,你对此无能为力。 (2认同)