web-dev-qa-db-fra.com

Fichier téléchargé dans Cordova/PhoneGap Open (InAppBrowser)

À l'aide de Cordova/PhoneGap 3.3.0, je télécharge un fichier à l'aide du plug-in FileTransfer, puis j'essaie de l'ouvrir à l'aide du plug-in InAppBrowser. Je peux télécharger le fichier avec succès et le placer dans le répertoire temporaire. Étant donné que le plug-in de fichier utilise maintenant le schéma d'URL, je ne vois pas comment passer l'url/chemin correct à la méthode window.open du plug-in InAppBrowser. Je ne trouve pas non plus de documentation pertinente. Toute la documentation "télécharger et ouvrir" que je peux trouver est obsolète et contient un schéma pré-URL.

Liens pertinents:

Exemples obsolètes que j'ai trouvés:

Voici mon code:

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

Je teste actuellement sous Android sur un Nexus 7 et un Nexus 5. L'InAppBrowser ouvre correctement le programme de lancement de PDF par défaut (dans mon cas, Adobe Reader), mais le message d'erreur "Le chemin du document n'est pas valide" s'affiche.

[Mise à jour: affichage des valeurs de retour]

J'ai essayé toutes les combinaisons suivantes pour le chemin du fichier:

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"
10
chadiusvt

Je pense que j'ai une solution à cela, mais c'est un peu méchant. 

J'ai fouillé dans Java cordova et cherché des endroits où il a construit un objet JSON d'entrée de fichier. Spécifiquement en recherchant des endroits où il ajoute fullPath à l'objet.

J'ai ajouté une entrée supplémentaire pour "fullAbsolutePath" avec la valeur [file].getAbsolutePath(), où [file] correspond à l'instance Java.io.file à proximité. J'ai fait cela dans tous les endroits que je pouvais trouver juste pour être en sécurité et parce que ça ne semblait pas faire de mal.

Ensuite, j'ai modifié FileEntry.js et File.js dans le dossier plugins\file afin de renseigner également cette valeur dans l'objet d'entrée de fichier.

J'essaie toujours de régler les problèmes, mais je crois que je suis sur la bonne voie ...

Je pense qu'une meilleure solution serait de modifier le plug-in inAppBrowser afin de reconnaître et de résoudre le protocole cordovaFile: // et de s'assurer qu'il a délibérément masqué le chemin d'accès absolu au système de fichiers - mais cela pourrait bien me dépasser.

EDIT - Yup! cela marche! Je peux maintenant prendre une entrée de fichier, appeler la méthode file, puis lire fullSystemPath dans fileObject. La valeur est comme "/ stockage/émulé/0/quel que soit /" sur mon Android. Il suffit de faire précéder "fichier: //" et window.open l'acceptera.

4
nihlton

Depuis Cordova 3.4, le protocole de fichier a changé et au lieu d’utiliser fullPath, ils fournissent désormais la fonction toURL () qui renvoie un chemin cdvfile: //path/to/your/file.ext.

Ainsi, lorsque vous téléchargez un fichier à l'aide du rappel de l'objet système de fichiers (avec l'argument entry), appelez simplement entry.toURL () et ouvrez-le à l'aide de l'instruction suivante pour l'ouvrir (en supposant qu'InApBrowser soit installé et que _blank ouvre la fenêtre InAppBrowser:

window.open(entry.toURL(), '_blank', 'location=no,closebuttoncaption=Close,enableViewportScale=yes');  

J'ai écrit à ce sujet dans ce post sur mon blog (si vous voulez toutes les références et informations de base).

5
EeKay

Dans les derniers documents Cordova dit-on

Si vous effectuez une mise à niveau vers une nouvelle version (1.0.0 ou plus récente) de File et que vous avez déjà utilisé entry.fullPath comme argument pour Download () ou upload (), devrez modifier votre code pour utiliser plutôt les URL du système de fichiers.

FileEntry.toURL () et DirectoryEntry.toURL () renvoient une URL de système de fichiers Du formulaire.

cdvfile: // localhost/persistent/chemin/vers/fichier pouvant être utilisé à la place du chemin de fichier absolu dans les méthodes download () et upload ().

Ce que vous pouvez essayer est de supprimer cdvfile://localhost/persistent pour avoir une URL qui fonctionnerait avec votre window.open. (peut-être commencer par une alerte ou console.log de ce que vous obtenez avec entry.toURL())

2
QuickFix

Je sais que c'est déjà répondu, mais j'ai eu le plus de succès avec entry.toInternalURL().

1
keldar

Dans la branche de plugin dev actuelle, il existe une solution:

Entry.toNativeURL () - Renvoie le chemin complet du fichier dans le système de fichiers du périphérique.

https://github.com/Apache/cordova-plugin-file/tree/dev

1
xudre

Il suffit d'écrire le fichier window.open dans la méthode de téléchargement ou de demander à nouveau le système de fichiers et de le saisir à nouveau avant de l'ouvrir si vous souhaitez le créer séparément.

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

}

si votre destination est composée de plusieurs niveaux de dossier, vous devez demander récursivement getDirectory un par un (si vos dossiers sont déjà créés, un seul appel de la méthode suffit)

PS: - Sur iOS, les fichiers sont téléchargés dans le dossier "Documents" et non sur "www". Ce n'est donc pas le même emplacement de votre contenu app.js que certaines personnes disent - si vous ouvrez une page html avec js et css depuis un dossier non compressé téléchargé, vous devez apporter quelques modifications à InAppBrowser.m pour le charger correctement

0
Chepaki

Le chemin qui suit "cdvfile: // localhost/persistent" ressemble à un chemin d’application racine (dossier www). En d'autres termes, je veux dire que vous avez accès aux images ou aux fichiers téléchargés en utilisant le chemin qui suit "cdvfile: // localhost/persistent".

Exemple

Chemin cible de téléchargement: "cdvfile: //localhost/persistent/MyImages/thebestimageever.jpg"

Dans une balise d'image HTML, je pourrais faire ceci: <img src="/MyImages/thebestimageever.jpg" />

Et ça marche bien.

0
Rahnzo