无法ACTION_VIEW外部存储上的文件 [英] Can't ACTION_VIEW a file on external storage

查看:112
本文介绍了无法ACTION_VIEW外部存储上的文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a file in my Android phone's external storage (emulated, in this case). Knowing the path to it and / or having a File object representing it, how can I use an Intent to open it in the appropriate app?

我尝试的第一件事是:

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

我确定它在某一点上是可行的,因为我对其进行了测试并移至应用程序的另一部分.现在,它总是抛出ActivityNotFoundException.该文件确实存在,因为file.exists()返回true,而且我知道它是正确的文件,但是没有应用程序自愿打开它.

I'm sure this was working at one point, because I tested it and moved on to another part of the app. Now it always throws ActivityNotFoundException. The file definitely exists because file.exists() returns true and I know it's the right file, but no apps volunteer to open it.

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

The only type of file I can still open this way is .pdf, for which Adobe Reader is selected, despite not being the only PDF reader installed on my device and not having been set default. I've noticed that Adobe Reader also offers to open pdf files which are located online (it appears as an alternative to downloading the pdf with Chrome). This suggests to me that only Adobe Reader is being found as a match for the Intent because the location is thought to be remote (though not online, because Chrome and other file downloading apps aren't listed as alternatives).

我也尝试过明确说明MIME类型:

I've also tried explicitly stating the MIME type:

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

这会使Intent与正确的应用程序匹配,但是它们实际上都无法打开文件.我已经使用MIME类型的硬编码字符串以及使用MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension)(通过文件扩展名)对此进行了测试.对于各种文件类型,建议使用正确的应用程序,但它们均无法打开文件.

This causes the Intent to be matched to the right apps, however they all fail to actually open the file. I've tested this both with hardcoded strings for the MIME types and by using MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension), passing the file extension. For a variety of file types, the correct apps were suggested but they all failed to open the file.

显式设置MIME类型是可以的,但是我犯了一个非常愚蠢的错误,我可能应该在答案中加以解释.

Setting the MIME type explicitly would have worked, but I made a very stupid mistake, which I should probably explain in an answer.

我尝试打开的文件来自互联网,并借助DownloadManager在我的应用程序中下载.我使用它的功能来显示一个通知,当一个人完成下载.单击这些通知之一可以完美地打开文件.我试图找到单击DownloadManager完成通知但没有运气时触发的Intent的源代码.

The files I've tried to open are from the internet, downloaded in my app with the aid of DownloadManager. I use its feature to display a notification when one finishes downloading. Clicking one of these notifications opens the file perfectly. I've tried to find the source code for the Intent fired when a DownloadManager finished notification is clicked, but had no luck.

此外,ES File Explorer之类的应用程序也可以导航到我的文件下载到的位置,并且可以毫无问题地打开它们.我在做什么错了?

Also, apps such as ES File Explorer can navigate to where my files are downloaded to and open them with no problem. What am I doing wrong?

是否仅仅是无法再ACTION_VIEW外部存储上的文件?我的应用程序还可以将文件临时下载到内部存储中,并且仍然可以打开文件,而不会出现以下问题:

Is it simply that it's no longer possible to ACTION_VIEW a file on the external storage? My app also downloads files to the internal storage temporarily, and these can still be opened with no issues like so:

//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工具插件和Android SDK本身使我的原始解决方案无法正常工作?

And as for it working in the past, could updating Eclipse, the SDK Tools plugin and the Android SDK itself have stopped my original solution from working?

推荐答案

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

When I tried setDataAndType, out of laziness I must have left:

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

并添加了另一行内容:

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

...假设与以下相同:

...assuming that it would be the same as:

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

然后我一定已经忘记了我实际上并没有尝试过setDataAndType并继续写这个问题.单独使用setType似乎删除了我作为参数传递给构造函数的Uri.使用LogCat查看意图的日志详细信息,我看到保留要推断的MIME类型不会导致任何类型,在已经设置Uri之后使用setType会导致由于某种原因未指定Uri,并且使用setDataAndType表示它们均已指定,从而导致Intent正常工作.

I must have then forgotten that I hadn't actually tried setDataAndType and gone on to write this question. Using setType on its own seemed to remove the Uri I'd passed as an argument to the constructor. Using LogCat to view the logged details of the intents, I saw that leaving the MIME type to be inferred resulted in no type, using setType after already setting a Uri resulted in no Uri being specified for some reason, and using setDataAndType meant they were both specified, causing the Intent to work properly.

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

So what I was doing wrong was setting the type and data separately, instead of using setDataAndType.

这篇关于无法ACTION_VIEW外部存储上的文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆