8

i know this link: https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-file/#where-to-store-files

but i would like to save the file in Downloads directory. Is this possible to save the file in any path using Ionic? If so, please, share the example.

Here's the code:

downloadImage(image) {

this.platform.ready().then(() => {

  const fileTransfer: TransferObject = this.transfer.create();

  const imageLocation = `${cordova.file.applicationDirectory}www/assets/img/${image}`;

  fileTransfer.download(imageLocation, cordova.file.externalDataDirectory + image).then((entry) => {

    const alertSuccess = this.alertCtrl.create({
      title: `Download Succeeded!`,
      subTitle: `${image} was successfully downloaded to: ${entry.toURL()}`,
      buttons: ['Ok']
    });

    alertSuccess.present();

  }, (error) => {

    const alertFailure = this.alertCtrl.create({
      title: `Download Failed!`,
      subTitle: `${image} was not successfully downloaded. Error code: ${error.code}`,
      buttons: ['Ok']
    });

    alertFailure.present();

  });

});

}

Basically I want save the file in location that is visible to the user.

EKOlog
  • 410
  • 7
  • 19
bambaniasz
  • 311
  • 2
  • 8
  • 17

6 Answers6

7

the problem was lack of permission. Here is the working code that can download file to downloads directory:

async downloadFile() {
  await this.fileTransfer.download("https://cdn.pixabay.com/photo/2017/01/06/23/21/soap-bubble-1959327_960_720.jpg", this.file.externalRootDirectory + 
  '/Download/' + "soap-bubble-1959327_960_720.jpg");
}

getPermission() {
  this.androidPermissions.hasPermission(this.androidPermissions.PERMISSION.READ_EXTERNAL_STORAGE)
    .then(status => {
      if (status.hasPermission) {
        this.downloadFile();
      } 
      else {
        this.androidPermissions.requestPermission(this.androidPermissions.PERMISSION.READ_EXTERNAL_STORAGE)
          .then(status => {
            if(status.hasPermission) {
              this.downloadFile();
            }
          });
      }
    });
}
bambaniasz
  • 311
  • 2
  • 8
  • 17
5

To download the File to the Download directory you need to use Cordova File and FileTransfer Plugins.

import { File } from '@ionic-native/file';
import { FileTransfer } from '@ionic-native/file-transfer';

constructor(private transfer: FileTransfer) { }

fileTransfer: FileTransferObject = this.transfer.create();

//Use your File Url and name

downloadFile(file) {
  // Some Loading
  this.fileTransfer.download(url, this.file.externalRootDirectory + 
  '/Download/' + file).then(response => {
  console.log(response);
  this.dismissLoading();
  this.presentToast('File has been downloaded to the Downloads folder. View 
  it..')
  })
  .catch(err => {
    this.dismissLoading();
    console.log(err)
  });
}

Hope it helps.

fiza khan
  • 1,280
  • 13
  • 24
  • Does this code really works for You? It doesn't for me. I can't save files in this directory. I am only able to save files in file.dataDirectory. – bambaniasz Jul 23 '18 at 08:08
  • 1
    Yes it works and it saves the files in the Downloads directory. Have you installed ionic file plugin?? – fiza khan Jul 23 '18 at 09:09
  • Yes I did, this code works for me but not when I try to save a file in file.externalRootDirectory. Does this file appear for a user in Download folder on a device? – bambaniasz Jul 23 '18 at 09:40
  • 1
    Yes it appears in the Downloads directory i have tested this and implemented this code in my app. – fiza khan Jul 23 '18 at 09:50
  • I'm getting "Permission denied" exception. Have You ever experienced that? – bambaniasz Jul 23 '18 at 11:45
  • 1
    Yes you are right this issue appears in the android 6 or greater. For this you need to ask the permission from the user at run time. This can be solved using **Android Permissions** plugins. Try this code on android version less than 6 and your file will be saved successfully. – fiza khan Jul 24 '18 at 04:31
  • Could You show me how to ask for the permission, please? – bambaniasz Jul 25 '18 at 16:42
  • 1
    Please follow this link https://stackoverflow.com/questions/46143238/android-not-requesting-permission-in-ionic-app – fiza khan Jul 26 '18 at 05:00
  • Thank You for your help! – bambaniasz Jul 26 '18 at 05:13
  • File-Transfer plugin is now deprecated. Use XMLHttpRequest() instead. – Argo Feb 18 '19 at 09:16
4
import { File } from '@ionic-native/file';
import { FileTransfer } from '@ionic-native/file-transfer';
constructor(private file: File, private transfer: FileTransfer){}

let link = 'url_to_download_file';
let path = '';
let dir_name = 'Download'; // directory to download - you can also create new directory
let file_name = 'file.txt'; //any file name you like

const fileTransfer: FileTransferObject = this.transfer.create();
let result = this.file.createDir(this.file.externalRootDirectory, dir_name, true);
result.then((resp) => {
  path = resp.toURL();
  console.log(path);
  fileTransfer.download(link, path + file_name).then((entry) => {
    console.log('download complete: ' + entry.toURL());
  }, (error) => {
    console.log(error)
  });
}, (err) => {
  console.log('error on creating path : ' + err);
});
2

I know this is late, but I've always had issues with the FileTransfer plugin. Maybe it is just me. I've instead had success with the writeFile() method of the File plugin.

I'm still working on iOS, but for Android here is what I have:

import { File } from "@ionic-native/file";

constructor(private fileSystem: File) {}

Then, in whatever function you have the logic to save the file, we have:

let path = this.fileSystem.externalRootDirectory + '/Download/'; // for Android
let filename = 'myNewFile.pdf';
this.fileSystem.writeFile(path, filename, File, { replace: true }).then(() => {
        this.toastCtrl.showToast('File has been downloaded. Please check your downloads folder.');
    }, (err) => {
        alert("Sorry. An error occurred downloading the file: " + err);
    }
);

As I said, I'm still looking out for what path to use for iOS. And I'm still wondering how to pop up the notification that usually comes up when a download actually goes to the download folder. But at least I am able to save directly in the download folder of Android.

mateotherock
  • 235
  • 5
  • 16
1

This code - ionic 3 capacitor - from josh morony takes a photo from the tmp directory and writes to the Document directory in this section using the FileSystem API the retrieves and manipulates the path

        Filesystem.writeFile({
            data: result.data,
            path: fileName,
            directory: FilesystemDirectory.Data
        })



getFromPhotos() {

  let options = {
  resultType: CameraResultType.Uri
  };

  Camera.getPhoto(options).then(

(photo) => {

    Filesystem.readFile({
        path: photo.path
    }).then((result) => {

        // let date = new Date(),
        // time = date.getTime(),
        time = 'bilder',
            fileName = time + '.jpeg';

        Filesystem.writeFile({
            data: result.data,
            path: fileName,
            directory: FilesystemDirectory.Data
        }).then((result) => {
            Filesystem.getUri({
                directory: FilesystemDirectory.Data,
                path: fileName
            }).then((result) => {
                console.log(result);
              let path = result.uri.replace('file://', '_capacitor_');
              this.image = this.sanitizer.bypassSecurityTrustResourceUrl(path);
            }, (err) => {
                console.log(err);
            });

        }, (err) => {
            console.log(err);
        });

    }, (err) => {
        console.log(err);
    });

}, (err) => {
    console.log(err);
}

);

}

In ionic 3 you have to use the cordova File plugin - please google. It is pretty straight forward to understand: you define the original directory where the file is, the original name of the file, the target directory, and a new name for the file inside that function. The principle is the same.

Ed Die
  • 219
  • 3
  • 18
1

To download the File to the Download directory you need to use Cordova File Plugin:

import { File } from '@ionic-native/file/ngx';

constructor(
    private file: File,
  ) { }

this.file.writeFile(this.file.externalRootDirectory + '/Download/', user_log.xlsx, blob, { replace: true })
.then(() => {

              alert('File has been downloaded. Please check your downloads folder.')
    enter code here
            }, 
    (err) => {

              alert("Sorry. An error occurred downloading the file: " + err);
    enter code here
            });
          })

It works in Ionic 4 as well.

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
Naveen Patel
  • 111
  • 2