【问题标题】:Download a file from a URL to a user accessible location将文件从 URL 下载到用户可访问的位置
【发布时间】:2017-04-28 18:36:51
【问题描述】:

我正在使用 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();

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

【问题讨论】:

    标签: http angular typescript nativescript angular2-nativescript


    【解决方案1】:

    经过一些不成功的尝试,我终于找到了如何将文件保存到用户“下载”文件夹(类似于 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 中的 cmets 时才发现它

    希望对你有所帮助。

    【讨论】:

      【解决方案2】:

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

      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!
        });
      }
      

      免责声明:我自己从未尝试过,只是阅读文档...

      【讨论】:

      • 我知道这一点,fs.knownFolders.documents() 方法获取用户或外部应用程序无法访问的当前应用程序的文档文件夹。
      • 无法指定文件位置和应用程序私有的位置对我来说似乎是两个不同的问题。在任何情况下,您只需要指定公共路径而不是使用fs.knownFolders.documents()。我觉得fs.knownFolders.ios.downloads()应该给你ios的下载文件夹,但是安卓或其他人没有对应的,所以你必须自己构建
      • 我也在ios上试过那个路径,不行。这就是我在堆栈溢出上发帖寻求帮助的原因。
      • 您可能必须分别处理每个平台 - 使用 {N} 相对容易。在 android 上,唯一可公开访问的文件夹是 SD 卡(内部和外部)存储文件夹。
      【解决方案3】:

      要让它在 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 文件夹是您应用程序目录中的一个私有文件夹,只有您可以看到。但是,当您启用上述两个权限时,它允许文件共享,以便您的用户可以访问文件夹及其内容。

      【讨论】:

        【解决方案4】:

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

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

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

        【讨论】:

          【解决方案5】:

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

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

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

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

          【讨论】:

            【解决方案6】:

            我知道这个帖子是 3 年前的,但如果你有同样的问题,我希望这个解决方案可以为你节省时间。

            我通过在 AndroidManifest.xml 文件中添加 android:requestLegacyExternalStorage="true" 解决了同样的问题 关注话题here

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2020-11-14
              • 2019-11-07
              • 1970-01-01
              • 1970-01-01
              • 2012-02-11
              • 1970-01-01
              • 2018-02-16
              • 1970-01-01
              相关资源
              最近更新 更多