离子文件下载无法正常工作

时间:2017-10-05 12:18:29

标签: android ios cordova-plugins ionic3 ionic-native

我正在为壁纸构建离子应用程序。

在应用程序中,显示了存储在www / assets / img中的图像。我在下面构建了2个按钮,用于下载和检索显示的图像到移动设备内存。

当我点击下载按钮时,会出现一个对话框,说“下载成功!Pug.jpg已成功下载到:filepath”。但是当我检查手机内存时没有这样的文件。当我点击“检索”时按钮显示对话框“文件检索成功!Pug.jpg已成功检索:filepath”“即使手机内存中没有文件。

这是home.ts代码

import {Component} from '@angular/core';
import {NavController, Platform, AlertController} from 'ionic-angular';
import {Transfer, TransferObject} from '@ionic-native/transfer';
import {File} from '@ionic-native/file';

declare var cordova: any;

@Component({
  selector: 'page-home',
  templateUrl: 'home.html',
  providers: [Transfer, TransferObject, File]
})

export class HomePage {

  storageDirectory: string = '';

  constructor(public navCtrl: NavController, public platform: Platform, private transfer: Transfer, private file: File, public alertCtrl: AlertController) {
    this.platform.ready().then(() => {
      // make sure this is on a device, not an emulation (e.g. chrome tools device mode)
      if(!this.platform.is('cordova')) {
        return false;
      }

      if (this.platform.is('ios')) {
        this.storageDirectory = cordova.file.documentsDirectory;
      }
      else if(this.platform.is('android')) {
        this.storageDirectory = cordova.file.dataDirectory;
      }
      else {
        // exit otherwise, but you could add further types here e.g. Windows
        return false;
      }
    });
  }

  downloadImage(image) {

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

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

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

      fileTransfer.download(imageLocation, this.storageDirectory + 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();

      });

    });

  }

  retrieveImage(image) {

    this.file.checkFile(this.storageDirectory, image)
      .then(() => {

        const alertSuccess = this.alertCtrl.create({
          title: `File retrieval Succeeded!`,
          subTitle: `${image} was successfully retrieved from: ${this.storageDirectory}`,
          buttons: ['Ok']
        });

        return alertSuccess.present();

      })
      .catch((err) => {

        const alertFailure = this.alertCtrl.create({
          title: `File retrieval Failed!`,
          subTitle: `${image} was not successfully retrieved. Error Code: ${err.code}`,
          buttons: ['Ok']
        });

        return alertFailure.present();

      });
  }

}

这是home.html代码

<ion-header>
  <ion-navbar>
    <ion-title>
      File Transfer Example
    </ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>
  <ion-card>
    <ion-card-header>
      Ionic 3 File Transfer Example
    </ion-card-header>
    <ion-card-content>
      <img src="assets/img/pug.jpg" alt="Cute Pug">
      <button ion-button (click)="downloadImage('pug.jpg')" color="secondary">Download image</button>
      <button ion-button (click)="retrieveImage('pug.jpg')" color="secondary">Retrieve downloaded image</button>
    </ion-card-content>
  </ion-card>
</ion-content>

我根据此Github code example

构建了这个离子应用

我实际上希望离子应用程序首先在内部存储器中创建一个文件夹(应用程序名为文件夹)并将所有图像放在那里。所以用户可以访问该文件夹中的文件。例如,如果应用程序名称是“Appsample”,那么所有图像应该在内部存储器的Appsample文件夹中。

我如何为上述目的而发展?

感谢。

2 个答案:

答案 0 :(得分:5)

我刚刚回答了几乎相同的问题,请参阅:

Download not working using filetransfer plugin

这里的主要问题是您使用以下目录来保存文件:

 else if(this.platform.is('android')) {
        this.storageDirectory = cordova.file.dataDirectory;
 }

如cordova docs(https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-file/#where-to-store-files)中所述,&#34; cordova.file.dataDirectory&#34;是使用内部存储器的应用程序沙箱中的持久和私有数据存储。

使用cordova.file.externalDataDirectory符合您的目的。然后该文件应该放在这里:&#34; file:///storage/emulated/0/Android/data/subdomain.domainname.toplevdomain/files/..."。

在Android上,外部存储目录始终存在。如果设备没有物理卡,Android会模拟它。

答案 1 :(得分:-1)

当我编写下载代码时,我遇到了同样的问题,它可以正常工作,但是我在手机上看不到文件

   1. Write download method
   2.  Write Permission method, Call Permission method
   3.  Call download method inside Permission, the phone will pop up and ask for permission for file read if it has not been set.
   4.  After download you might not be able to see where the file is on phone, you will now use photoViewer to view it on phone if it is 
image or use document viewer if it is pdf or other document related.

所需的插件

private transfer: FileTransfer,
private fileTransfer: FileTransferObject,
private file: File,
private androidPermissions: AndroidPermissions,
private photoViewer: PhotoViewer,

getPermission() {
    // get permission from device to save 
    this.androidPermissions.checkPermission(this.androidPermissions.PERMISSION.READ_EXTERNAL_STORAGE).then(
        result =>//,
            err => this.androidPermissions.requestPermission(this.androidPermissions.PERMISSION.READ_EXTERNAL_STORAGE)
    );

    // get permission from device to save 
    this.androidPermissions.hasPermission(this.androidPermissions.PERMISSION.WRITE_EXTERNAL_STORAGE)
        .then(status => {
            if (status.hasPermission) {
                this.download('k');
            }
            else {
                this.androidPermissions.requestPermission(this.androidPermissions.PERMISSION.WRITE_EXTERNAL_STORAGE)
                    .then(status => {
                        if (status.hasPermission) {
                            this.download('');
                        }
                    });
            }
        });
}
public download() {
    let url = encodeURI(this.imgUrl);
    var imagePath = this.file.dataDirectory + "myDP.png";
    const fileTransfer = this.transfer.create();
    fileTransfer.download(url, imagePath).then((entry) => {
        this.generalProvider.showToast('download completed: ' + imagePath);
        this.photoViewer.show(entry.toURL());
    }, (error) => {
    });
}