Cordova/PhoneGap 打开下载的文件 (InAppBrowser)
Posted
技术标签:
【中文标题】Cordova/PhoneGap 打开下载的文件 (InAppBrowser)【英文标题】:Cordova/PhoneGap Open Downloaded File (InAppBrowser) 【发布时间】:2014-03-23 09:33:56 【问题描述】:使用 Cordova/PhoneGap 3.3.0,我正在使用 FileTransfer 插件下载文件,然后尝试使用 InAppBrowser 插件打开它。 我可以成功下载文件,并将其放在临时目录中。由于 File 插件现在使用 URL 模式,我无法弄清楚如何将正确的 url/路径传递给 InAppBrowser 插件的 window.open
方法。我也找不到任何相关文件。我能找到的所有“下载和打开”文档都已过时并且是 URL 前架构。
相关链接:
Cordova Release info on New Plugin Versions The readme for the FileTransfer plugin The readme for the InAppBrowser plugin How to open local file with InAppBrowser with recent changes to URL scheme in File plugin - 类似问题我发现的过时示例:
File-transfer download file issue on Cordova 3.1 - 这个用户因为想不通而降级到较早的版本 https://gist.github.com/devgeeks/4982983 - 此示例使用entry.fullPath
,现在已弃用 toURL()
这是我的代码:
var uri = encodeURI("http://some.url/file.pdf");
window.requestFileSystem(LocalFileSystem.TEMPORARY, 0,
function (fileSystem)
var fileTransfer = new FileTransfer();
var filename = fileSystem.root.toURL() + uri.substr(uri.lastIndexOf("/") + 1);
fileTransfer.download(uri, filename,
function(entry) // download success
var path = entry.toURL(); //**THIS IS WHAT I NEED**
window.open(path, "_system");
,
function(error) // irrelevant download error
);
,
function(error) // irrelevant request fileSystem error
);
我目前正在 android 上的 Nexus 7 和 Nexus 5 上进行测试。InAppBrowser 正确打开了默认的 pdf 启动器(在我的情况下为 Adobe Reader),但随后我收到“文档路径无效”错误。
[更新:显示返回值]
我已经为文件路径尝试了以下所有组合:
var path = entry.toURL(); // "cdvfile://localhost/temporary/file.pdf"
var path = entry.fullPath; // "file.pdf"
var path = fileSystem.root.toURL() + filename; // "cdvfile://localhost/temporary/file.pdf"
var path = fileSystem.root.fullPath + filename; // "/file.pdf"
【问题讨论】:
如果您最近更新了插件,也许您必须处理新的 URL 方案cdvfile://
? cordova.apache.org/news/2014/02/10/plugins-release.html
感谢您的评论。我正在使用您提供的链接中引用的这些最新插件。我读了这个,但不记得我发帖的 URL。我将其添加到相关链接部分。当我打电话给entry.toURL()
时,我得到了带有cdvfile://
前缀的链接
愚蠢的问题:为什么不用window.open直接使用原始url而不是先下载呢?
这不是一个愚蠢的问题。我以前这样做过,但某些 Android 设备显示“无法打开文件”。错误。这是最奇怪的事情。使用该方法,文件下载正确,我可以通过文件资源管理器在 Adobe 中打开,但是通过下载应用程序打开时,会显示错误。我认为这是一个 MIME 类型问题,但我确认使用了正确的 MIME 类型。此外,通过应用程序打开它为用户节省了一个额外的步骤,即必须单击下载的文件才能打开它(假设它无论如何都可以正常工作)。
也许可以尝试使用 webintent 插件而不是 inappbrowser 来打开 pdf:github.com/Initsogar/cordova-webintent
【参考方案1】:
自 Cordova 3.4 以来,文件协议发生了变化,现在他们提供了 toURL(),而不是使用 fullPath,它返回 cdvfile://path/to/your/file.ext 路径。
因此,当您使用文件系统对象的回调(使用 entry 参数)下载文件时,只需调用 entry.toURL() 并使用以下语句打开它 - 假设您安装了 InApBrowser 并且 _blank 将打开InAppBrowser 的窗口:
window.open(entry.toURL(), '_blank', 'location=no,closebuttoncaption=Close,enableViewportScale=yes');
我在我的博客上的this post 中写过它(如果你想要所有的参考资料和背景信息)。
【讨论】:
【参考方案2】:我认为我有一个解决方案,但这有点令人讨厌。
我浏览了cordova JAVA并寻找它构建文件条目JSON对象的地方。特别是通过寻找将fullPath
添加到对象的位置。
我为“fullAbsolutePath”添加了一个附加条目,其值为[file].getAbsolutePath()
,其中[file]
是附近的java.io.file 实例。为了安全起见,我在所有我能找到的地方都这样做了,因为它似乎不会伤害任何东西。
然后我修改了 plugins\file 文件夹中的 FileEntry.js 和 File.js 以将该值填充到文件条目对象中。
仍在努力解决问题,但我相信我走在正确的轨道上......
我认为更好的解决方案是修改 inAppBrowser 插件以识别和解析 cordovaFile:// 协议,并且我确定他们故意掩盖了绝对文件系统路径 - 但这可能有点超出我的能力。
编辑 - 是的!这行得通!我现在可以获取一个文件条目,调用 file 方法,然后从 fileObject 中读取 fullSystemPath。值就像我的 android 上的“/storage/emulated/0/whatever/”。只需在前面加上“file://”,window.open 就会接受它。
【讨论】:
感谢您所做的一切。我还查看了cordova.java,看看你可能把所有这些引用放在哪里fullAbsolutePath
。您可能希望将其提交给 cordova 团队以获取 fileentry 或 inappbrowser 插件。不敢相信他们没有将其包含在更新的版本中。不过我同意,编辑 inappbrowser 以正确识别 url 可能更有意义。很高兴你让它工作了!
嘿,不用担心。我实际上是在尝试为自己解决同样的问题,并想我会分享。
@nihlton 您如何获取文件以保存到您的应用文件夹?【参考方案3】:
在the latest cordova docs 他们说
如果您要升级到 File 的新版本(1.0.0 或更高版本),并且 您以前一直使用 entry.fullPath 作为参数 下载()或上传(),那么你需要改变你的代码来使用 文件系统 URL。
FileEntry.toURL() 和 DirectoryEntry.toURL() 返回文件系统 URL 形式
cdvfile://localhost/persistent/path/to/file 可以就地使用 download() 和 upload() 方法中的绝对文件路径。
您可以尝试删除cdvfile://localhost/persistent
以获得一个可以与您的window.open 一起使用的网址。 (也许从您使用entry.toURL()
获得的警报或控制台日志开始)
【讨论】:
谢谢。我也找到了这个文档,但是丢失了它的 URL。我尝试过使用toURL()
,它也不会返回有效的网址。我刚刚编辑了上面的帖子以显示返回值。删除“cdvfile://localhost/temporary”给了我与entry.fullPath
相同的结果,这也不起作用。
也许可以试试 'file:///sdcard/'+entry.fullPath;
我也尝试使用绝对路径,但使用 inappbrowser 失败。但是,使用您之前建议中的插件我成功了!【参考方案4】:
在当前的插件开发分支中有一个解决方案:
Entry.toNativeURL() - 返回设备 FileSystem 中文件的完整路径。
https://github.com/apache/cordova-plugin-file/tree/dev
【讨论】:
【参考方案5】:我知道这个问题已经得到解答,但我最成功的是entry.toInternalURL()
。
【讨论】:
【参考方案6】:“cdvfile://localhost/persistent”后面的路径类似于根应用程序(www 文件夹)路径。换句话说,我的意思是您可以使用“cdvfile://localhost/persistent”之后的路径访问图像或下载的文件。
例子
下载目标路径:“cdvfile://localhost/persistent/MyImages/thebestimageever.jpg”
在 HTML 图像标签中我可以这样做:<img src="/MyImages/thebestimageever.jpg" />
而且效果很好。
【讨论】:
此解决方案似乎不适用于 mp3 和 mp4 文件。只有图片。【参考方案7】:只需要在下载方法中写window.open,或者如果要单独制作,在打开之前再次要求文件系统和入口
function downloadFile(fileURL, destination, fileName)
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fileSystem)
fileSystem.root.getDirectory(destination,
create: true
, function (dirEntry)
var ft = new FileTransfer();
ft.download(fileURL, dirEntry.toURL() + "/fileName", function (entry)
alert(fileName + " downloaded successfully at:" + dirEntry.fullPath);
window.open(dirEntry.toURL() + "fileName", "_blank", "location=yes");
, function (error)
alert("download failed: " + JSON.stringify(error));
);
, function (error)
alert("dir creation failed: " + JSON.stringify(error));
);
, function (error)
alert("requesting file system failed: " + JSON.stringify(error));
);
如果您的目的地不止一个文件夹级别,那么您必须逐个递归地请求 getDirectory(如果您的文件夹已经创建,则调用该方法就足够了)
PS: - 在 ios 上,文件下载到“Documents”文件夹而不是“www”,因此 app.js 内容的位置与某些人所说的不同 - 如果您从下载的解压缩文件夹中打开带有 js 和 css 的 html 页面,那么您必须在 InAppBrowser.m 上进行一些更改以使其正确加载
【讨论】:
以上是关于Cordova/PhoneGap 打开下载的文件 (InAppBrowser)的主要内容,如果未能解决你的问题,请参考以下文章
通过 Cordova/Phonegap 应用程序创建一个可以由另一个应用程序 (ios) 打开的文件?
Cordova/Phonegap 无法识别 FileTransfer
缺少 WWW 文件夹 Cordova/PhoneGap iOS
如何使用手机的本机应用程序打开图像 - Cordova / phonegap