【问题标题】:Cordova/PhoneGap Open Downloaded File (InAppBrowser)Cordova/PhoneGap 打开下载的文件 (InAppBrowser)
【发布时间】:2014-03-23 09:33:56
【问题描述】:

使用 Cordova/PhoneGap 3.3.0,我正在使用 FileTransfer 插件下载文件,然后尝试使用 InAppBrowser 插件打开它。 我可以成功下载文件,并将其放在临时目录中。由于 File 插件现在使用 URL 模式,我无法弄清楚如何将正确的 url/路径传递给 InAppBrowser 插件的 window.open 方法。我也找不到任何相关文件。我能找到的所有“下载和打开”文档都已过时并且是 URL 前架构。

相关链接:

我发现的过时示例:

这是我的代码:

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 启动器(在我的情况下为 Adob​​e 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 设备显示“无法打开文件”。错误。这是最奇怪的事情。使用该方法,文件下载正确,我可以通过文件资源管理器在 Adob​​e 中打开,但是通过下载应用程序打开时,会显示错误。我认为这是一个 MIME 类型问题,但我确认使用了正确的 MIME 类型。此外,通过应用程序打开它为用户节省了一个额外的步骤,即必须单击下载的文件才能打开它(假设它无论如何都可以正常工作)。
  • 也许可以尝试使用 webintent 插件而不是 inappbrowser 来打开 pdf:github.com/Initsogar/cordova-webintent

标签: cordova inappbrowser


【解决方案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 上,文件下载到“Doc​​uments”文件夹而不是“www”,因此 app.js 内容的位置与某些人所说的不同 - 如果您从下载的解压缩文件夹中打开带有 js 和 css 的 html 页面,那么您必须在 InAppBrowser.m 上进行一些更改以使其正确加载

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-05-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-09-06
          相关资源
          最近更新 更多