将URL中的文件下载到用户可访问的位置

时间:2016-12-13 16:07:24

标签: http angular typescript nativescript angular2-nativescript

我正在使用Nativescript/Angular 2

构建应用

我希望能够从URL下载文件,并将其保存到普通用户无需查找的位置。我相信iOSAndroid下载量最适合这种情况。如果我错了,请纠正我。

文件可以是任何文件类型,而不仅仅是图像。所以主要是spreadsheetword documentpdfpngjpg等。

我在线搜索并通过文档搜索。该文档描述了一种名为getFile的方法,该方法获取文件并将其保存到您的设备。

我已在我的代码中实现了以下内容:

download (id) {
  console.log('Download Started');
  getFile("https://raw.githubusercontent.com/NativeScript/NativeScript/master/apps/tests/logo.png").then(function (r) {
    console.log(r.path);
  }, function (e) {
    //// Argument (e) is Error!
  });
}

问题在于它将其保存到非用户可访问的位置,例如:

/data/user/0/com.myapp.example/files/logo.png

更新:

我也尝试过直接指定路径:

fs.knownFolders.documents();

但是,此方法获取当前应用程序的文档文件夹,该文件夹无法由用户或外部应用程序访问

6 个答案:

答案 0 :(得分:2)

经过一些失败的尝试,我终于找到了如何将文件保存到用户“ Downloads”文件夹(类似于sdcard / Download之类的文件)。您可以使用android.os.Environment方法获取此文件夹。

将此添加到您的组件中

import { getFile } from 'tns-core-modules/http';
import * as fileSystem from "tns-core-modules/file-system";
import { isAndroid } from "tns-core-modules/platform";
import { alert } from "tns-core-modules/ui/dialogs";

declare var android;

<...>

public download (url, fileName) {
    if (isAndroid) {
        const permissions = require("nativescript-permissions");
        permissions.requestPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE, "I need these permissions because I'm cool")
            .then(() => {
                let downloadedFilePath = fileSystem.path.join(android.os.Environment.getExternalStoragePublicDirectory(android.os.Environment.DIRECTORY_DOWNLOADS).getAbsolutePath(), fileName);
                getFile(url, downloadedFilePath).then(resultFile => {
                    alert({
                        title: 'Saved!',
                        okButtonText: 'OK',
                        message: `File saved here:\n${resultFile.path}`
                    });
                }, error => {
                    alert({
                        title: 'Error',
                        okButtonText: 'OK',
                        message: `${error}`
                    });
                });
            });
    }
}

您还应该了解什么:

1)没有任何下载指示器,标准系统下载栏也没有出现,我也不知道该怎么解决。

2)对于iOS,您可以尝试使用

const filePath = fileSystem.path.join(fileSystem.knownFolders.ios.downloads().path, fileName);
getFile(url, filePath).then((resultFile) => {}, (error) => {});

我认为,NS文档不能直言不讳是一种遗憾,因为只有使用NS函数您才能将文件保存在用户可访问的位置。我只有在读取文件/node_modules/tns-core-modules/file-system/file-system.d.ts

中的注释时才弄清楚

希望这对您有所帮助。

答案 1 :(得分:1)

相同的文档说您可以像这样指定文件位置:

download (id) {
  console.log('Download Started');
  var folder = fs.knownFolders.documents();
  var file = fs.path.join(folder.path, "logo.png");
  var url = "https://raw.githubusercontent.com/NativeScript/NativeScript/master/apps/tests/logo.png"
  getFile(url, file).then(function (r) {
    console.log(r.path);
  }, function (e) {
    //// Argument (e) is Error!
  });
}
  免责声明:从未尝试过,只需阅读文档......

答案 2 :(得分:1)

要使其在 iPhone 上运行,您可以执行以下操作 (TypeScript):

import { knownFolders, path } from "tns-core-modules/file-system";

let destination = path.join(knownFolders.documents(), "file_name.txt");
// logic to save your file here ...
// the important thing is that you have to save your file in knownFolders.documents()

然后在Info.plist中,您必须添加以下权限:

<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
<key>UIFileSharingEnabled</key>
<true/>

现在,如果您转到 iPhone 的 Files 应用程序 > On My iPhone > Your App's Name,您应该会在那里看到该文件。

基本上,Documents 文件夹是您应用程序目录中只有您可以看到的私有文件夹。但是,当您启用上述两个权限时,它允许文件共享,以便您的用户可以访问该文件夹及其内容。

答案 3 :(得分:0)

我意识到这是一个较旧的线程,但这也许可以帮助某人:

如果使用currentApp()而不是documents(),则可以访问所需的文件夹。例如:

var directories = fs.knownFolders.currentApp();
var folder = directories.getFolder('./nameofaccessiblefolder');

答案 4 :(得分:0)

您可以直接指定文件系统路径,如下所示:

var folder = fs.Folder.fromPath('/sdcard/Download');

请注意,/sdcard/Download仅适用于Android;您可以将其替换为要将数据保存到的任何(可公共访问的)文件夹。

似乎还没有一种跨平台的方式来选择文件夹路径,因此您必须手动解决一些问题。有关更多信息,请参见this GitHub thread

答案 5 :(得分:0)

我知道此线程是3年前的,但是如果您遇到相同的问题,希望此解决方案可以为您节省时间。

我通过在AndroidManifest.xml文件中添加android:requestLegacyExternalStorage="true"解决了相同的问题 遵循线程here