ACTION_VIEW无法在外部存储上存档

时间:2014-10-23 22:37:47

标签: android android-intent android-external-storage

我的Android手机的外部存储空间中有一个文件(在这种情况下是模拟的)。知道它的路径和/或有一个File对象代表它,我如何使用Intent在相应的应用程序中打开它?

我尝试的第一件事是:

startActivity(new Intent(Intent.ACTION_VIEW, Uri.fromFile(file)));

我确定这在某一点上有效,因为我测试了它并转移到应用程序的另一部分。现在它总是抛出ActivityNotFoundException。该文件肯定存在,因为file.exists()返回true并且我知道它是正确的文件,但没有应用程序自愿打开它。

我仍然可以通过这种方式打开的唯一类型的文件是.pdf,其中选择了Adobe Reader,尽管它不是我设备上安装的唯一PDF阅读器,并且没有设置为默认值。我注意到Adobe Reader还提供了打开在线的pdf文件(它似乎是用Chrome下载pdf的替代方案)。这告诉我,只有Adobe Reader被认为是Intent的匹配项,因为该位置被认为是远程的(虽然不在线,因为Chrome和其他文件下载应用程序不作为替代品列出)

我还尝试明确说明MIME类型:

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "application/msword");
startActivity(intent);

这会导致Intent与正确的应用匹配,但它们都无法实际打开文件。我已经使用MIME类型的硬编码字符串和使用MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension)测试了这一点,并传递了文件扩展名。对于各种文件类型,建议使用正确的应用程序,但它们都无法打开文件。

修改

显式设置MIME类型会有效,但我犯了一个非常愚蠢的错误,我应该在答案中解释。

我尝试打开的文件来自互联网,借助DownloadManager在我的应用中下载。我使用它的功能在完成下载后显示通知。单击其中一个通知可以完美打开文件。我已经尝试在点击Intent完成通知时找到DownloadManager触发的源代码,但没有运气。

此外,ES文件浏览器等应用程序可以导航到我的文件下载到的位置并打开它们没有问题。我做错了什么?

是否只是ACTION_VIEW不再可能在外部存储上的文件?我的应用程序还暂时将文件下载到内部存储器,这些仍然可以打开,没有类似的问题:

//This works for files on internal storage:
Uri uri = FileProvider.getUriForFile(context, AUTHORITY, file);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);

至于它过去的工作,可以更新Eclipse,SDK Tools插件和Android SDK本身已经停止了我的原始解决方案吗?

1 个答案:

答案 0 :(得分:3)

当我尝试setDataAndType时,出于懒惰,我必须离开:

Intent intent = new Intent(Intent.ACTION_VIEW, Uri.fromFile(file));

并添加了另一行:

Intent intent = new Intent(Intent.ACTION_VIEW, Uri.fromFile(file));
intent.setType(theMimeType);

...假设它与:

相同
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), theMimeType);

我必须忘记我实际上没有尝试setDataAndType并继续写下这个问题。单独使用setType似乎删除了Uri我作为参数传递给构造函数。使用LogCat查看记录的意图详细信息,我看到保留了要推断的MIME类型导致没有类型,在设置setType之后使用Uri导致没有Uri由于某种原因而指定,并且使用setDataAndType意味着它们都被指定,导致Intent正常工作。

所以我错误的是分别设置类型和数据,而不是使用setDataAndType