Phonegap Build: download image in one of the folders of your app - android

I am able to download an image if I specify the path directly with
file:///storage/sdcard0/
How can I save an image to my one of the folders in my app ? I tried this approach to set app path but it doesn't work for me.
This is what I am using so far and it works if you want to save and image to sdcard:
var fileName = "myImage.png";
var fileTransfer = new FileTransfer();
var uri = encodeURI("http://my.url.to.image/myImage.png");
var filePath = "file:///storage/sdcard0/uploads/myImage.png";
fileTransfer.download(
uri,
filePath,
function(entry) {
alert("download complete: " + entry.fullPath);
console.log("download complete: " + entry.fullPath);
},
function(error) {
alert("download error source/target/code:\n" + error.source +" \n||| "+error.target+" \n||| "+error.code);
console.log("download error source/target/code " + error.source+" / "+error.target+" / "+error.code);
}
);
If I use this function:
function getPhoneGapPath() {
'use strict';
var path = window.location.pathname;
var phoneGapPath = path.substring(0, path.lastIndexOf('/') + 1);
return phoneGapPath;
}
I get /android_asset/www/. How would I get the correct path to my app?
The app is using AngularJS and is not bootstrapped in onDeviceReady (developer before me made it that way and now changing it to something like this is beyond me (tried but didn't work)).
Another question I can refer to was asked here.
I also tried this, this, this and this but none worked for me. I get "" for fullPath and recently I managed to get path printed with .toURL() and it was "cdvfile://localhost/persistent". The above download code now also works if I use
filePath = "cdvfile://localhost/persistent/MyAppID/uploads/myImage.png";
but this creates folder /MyAppID/uploads in /storage/sdcard0 which is bad again. My app needs to get to images with
<img src="uploads/myImage.png" alt="myimg"/>
Another useful link is here but it offers no help as to how to write to pre-created folder of your own app.
EDIT: As far as I've learned you cannot write within your own app(read only). That's why I tried to reference images from sdcard with
<img src="file:///storage/sdcard0/Android/data/com.app.my/cache/myImage.png" alt="myimg"/>
and this works! :) Unfortunately this is hardcoded and not good since other phones might have a different persistent location.
If I try
<img src="cdvfile://localhost/persistent/Android/data/com.app.my/cache/myImage.png" alt="myimg"/>
this does not reference the picture :/ (it does download it on storage/sdcard0/Android/data/com.app.my/cache/ though)

I would use the folder alias as defined in the plugin docs here (https://github.com/apache/cordova-plugin-file/blob/master/doc/index.md). Specifically cordova.file.dataDirectory. Note that this is not, afaik, under the www of your original project, but it seems to be the preferred place to store downloads. Once saved there you can resolve that to a URL that you could use to load via AJAX, or in an img tag if you are downloading graphics.

As far as I learned you cannot write to your own app (change items inside your app - /www folder on Android).
My solution was to save images to PERSISTENT storage (sdcard usually).
You can get the path of your app's persistent storage with these steps:
function onDeviceReady() {
console.log('Device Platform: ' + device.platform); // returns 'Android' or 'iOS' for instance
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail);
cacheFolderSubPath = "Android/data/com.id.myApp/cache/"; // this is app's cache folder that is removed when you delete your app! (I don't know what this path should be for iOS devices)
}
Then inside gotFS success callback
function gotFS(fileSystem) {
var nturl = fileSystem.root.toNativeURL(); // cdvfile://localhost/persistent/
window.resolveLocalFileSystemURL(nturl+cacheFolderSubPath, onResolveSuccess, onResolveFail);
}
and in onResolveSuccess
function onResolveSuccess(fileEntry){
appCachePath = fileEntry.toNativeURL()+"/"; // file:///storage/sdcard0/Android/data/com.id.myApp/cache/ in my case but some other Androids have storage/emulated/0 or something like that ...
continueCustomExecution();
}
and now in continueCustomExecution() you can run your program and do whatever it is you do ... and in this case download images into appCachePath that we got earlier. You can now successfully reference images in src tags with our appCachePath+yourImageName.
Unfortunately I still don't know how to download an image successfully on iOS. I get an error code 1 with FileTransfer plugin ... (saving to file:///var/mobile/Applications/my.app.id/Documents/). Probably should save somewhere else but this is the path I get when requesting PERSISTENT FileSystem.
Cheers

Related

Download file for offline use Cordova/PhoneGap build

I'm a novice when it comes to the development of apps. I made a simple audio player app for android and iOS and build it with phonegap build.
The app uses the <audio> html tag to load mp3 files that are located on a remote server like so:
<div class="mobileui-music-cover-controls">
<audio ontimeupdate="udpateProgress()" id="player">
<source src="http://www.myserver.com/audiofile.mp3" type="audio/mpeg">
</audio>
<a id="playKnop" href="JavaScript:playMusic()" class="play"><i class="ion-ios-play"></i></a>
<a id="pauseKnop" href="JavaScript:pauseMusic()" class="play"><i class="ion-ios-pause"></i></a>
</div>
obviously, I changed the scr for this example.
It works fine as long as you have a stable internet connection but a few people are experiencing connection drops etc.
I would like to make the files offline available on user request. So it has to be optional (by clicking a button or something like that).
The app should detect if the file is present on the device and if so choose the local file over the remote file.
In short, I have 2 questions.
How can I download a specific file on user request?
How can I check whether the file is there or not and play the right file?
I can't seem to figure out how to do this I'm working on it for the last couple of days but I honestly have no clue on how to achieve this. Any help would be greatly appreciated.
As you said you need to download the file to your device. Since your using cordova you could use fileTransfer to download the audio. This is very straight forward (this is the offical example code):
// !! Assumes variable fileURL contains a valid URL to a path on the device,
// for example, cdvfile://localhost/persistent/path/to/downloads/
var fileTransfer = new FileTransfer();
var uri = encodeURI("http://some.server.com/download.php");
fileTransfer.download(
uri,
fileURL,
function(entry) {
console.log("download complete: " + entry.toURL());
},
function(error) {
console.log("download error source " + error.source);
console.log("download error target " + error.target);
console.log("download error code" + error.code);
},
false,
{
headers: {
"Authorization": "Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA=="
}
}
);
The next time you want to play the audio you need to check if there is a local version. Either you check your device if that file exists (there are many ways, e.g. Cordova check if file in url exists) or you make use of something like localStorage which basically is a simple lil database.
// more or less pseudo code!!!
// callback from fileTransfer when your file was downloaded
function downloadSuccess(entry) {
// save it to localStorage
// key: the remote URL, value: the local URL
localStorage.setItem(remoteURL, entry.toURL());
}
...
...
// the check if there is a cached file
var remoteSrc = "http://www.myserver.com/audiofile.mp3";
var localSrc = localStorage.getItem(remoteSrc);
if(localSrc === null) {
// when there is NO cached version, use remote
audioElement.src = remoteSrc;
} else {
// when there IS a cached version, use local
audioElement.src = localSrc;
}
I hope this helps and gives you an idea how to accomplish simple caching yourself :)

PhoneGap - How to make a copy of image and save in application folder?

In my app the user can choose one image from gallery, this image will be used in user account and can't be accessible by gallery, so I need sabe a copy of this image into cordova.file.dataDirectory but I don't know how to get local file URI to make copy and save.
How to copy image file from local device to cordova.file.dataDirectory?
My app have a screen where user can give title and choose image using a input file.
I'm using cordova plugin file
Searching I found solution in old documentation of PhoneGap (recent docs no have this information). To copy files just use copyTo method.
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(entry){
var parent = document.getElementById('parent').value;
parentEntry = new DirectoryEntry({fullPath: parent});
// copy the file to a new directory and rename it
entry.copyTo(parentEntry, "file.copy", function(entry){
console.log("New Path: " + entry.fullPath);
}, function(error){
console.log(error.code);
});
}, null);

Crosswalk crashes with cordova-plugin-file when read file larger than 20MB

I'm using cordova-plugin-file to read my mp3 file with the readAsArrayBuffer method. It works perfect with a file less than 20mb, but with a larger file it causes the app to crash with this error. (I'm using crosswalk browser)
E/chromium( 3330): [ERROR:simple_index_file.cc(223)] Failed to write the temporary index file
E/chromium( 3330): [ERROR:runtime_javascript_dialog_manager.cc(69)] Not implemented reached in virtual void xwalk::RuntimeJavaScriptDialogManager::ResetDialogState(content::WebContents*)
I'm so confused with what the problem is. Does the problem come from xwalk or cordova-plugin-file?
Please help me because this plugin can only read file smaller than 20mb size.
I found a solution for this bug.
I think Cordova-plugin-file can't send large amount of data from native to javascript. So I try to research from Crosswalk Browser API and very happy to see that they support File API. It can get access directly to Android file system through virtual root like : EXTERNAL, CACHEDIR, DOWNLOADS, ...
Here is the trick to read any big file with Crosswalk:
function readFileAsArrayBuffer(storage, path, file) {
xwalk.experimental.native_file_system.requestNativeFileSystem(storage,
function (fs) {
fs.root.getFile(storage + "/" + path + file, {create: false}, function (entry) {
entry.file(function (file) {
reader = new FileReader();
reader.onloadend = function (data) {
//Data after read.
};
reader.readAsArrayBuffer(file);
},
},
function (e) {
console.error("2-" + JSON.stringify(e))
});
},
function (e) {
console.error("3-" + JSON.stringify(e));
});
}
//test
readFileAsArrayBuffer("EXTERNAL", "downloads/folder/", "file.mp3");

phonegap download and save images from a url to the application installation folder

I am developing an application in phonegap that is supposed to work in both ios and android.
For this application i need to download all images from the server.I was able to download the images to the external memory card using the following code.
function storeIntelligrapeLogo() {
alert('start of file download');
var url = "http://www.kannuronlineservices.com/images/logo.png"; // image url
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fs) {
alert('inside request file sysytem')
var imagePath = 'file:///storage/sdcard0'+fs.root.fullPath + "/logo.png"; // full file path
alert('inside request file sysytem path fs.root==' + fs.root);
alert('inside request file sysytem path fs.root.fullPath==' + fs.root.fullPath);
var fileTransfer = new FileTransfer();
fileTransfer.download(url, imagePath, function(entry) {
alert(entry.fullPath); // entry is fileEntry object
}, function(error) {
alert("Some error" + JSON.stringify(error));
});
}) }
Now i would like this to work in ios also.For that what is the file path i have to use
for 'file:///storage/sdcard0'.Then now the file is downloaded to the external memory card in android and i would like it to be downloaded to the application installation folder and so that when the application is uninstalled,the images also get deleted.Or please suggest me if there exist some other way of doing this,ie:downloading images from server folder and storing it locally with phonegap so that the application is expected to work in offline mode also.
Thanks.
You can use a phonegap plugin.
Look at http://plugins.cordova.io/#/package/de.fastr.phonegap.plugins.downloader
It downloads multiple files to persistant storage on android and ios.

Storing video for offline use in PhoneGap/Chrome Apps

I have simple video playing apps both set up by PhoneGap and Chrome Apps CLI's (Both use Cordova), they contain a bunch of short educational videos and are needed as both website and application on Android/iOS for offline usage.
I have found, so far, that the total size of the Chrome Apps bundled file can't exceed 10mb and the PhoneGap Build can't exceed 40mb - so both will need to download and store files locally for later use.
The videos will need to open and play from within the WebView browser - hotspots trigger JS that change the HTML5 video src. (AppCache and other HTML5 storage are out the question for mobile devices, they never seem to be able to reach triple digit storage space)
Has anyone had luck with a certain Cordova/PhoneGap/Chrome App API that can store files locally to achieve this spec?
Any advice/help/pointing in right direction appreciated!
You can do this in Cordova apps (and very soon in Chrome Cordova apps). You'll need the most recent versions of the File (1.0.1) and FileTransfer (0.4.2) plugins.
With those, you can use FileTransfer.download() to download the video, and you can use File to access the file and create a <video> tag to play the video.
You'll want to use the .toNativeURL() method on the file entries before you play them. Recent versions of the File plugin use a custom URL scheme for files, which is unfortunately not compatible with the HTML <video> tag.
This is the test code that I use to test the interaction of these methods:
var filename = "small.mp4";
var videoURL = "http://techslides.com/demos/sample-videos/small.mp4";
requestFileSystem(PERSISTENT, 0, function(fileSystem) {
var ft = new FileTransfer();
ft.download(videoURL, fileSystem.root.toURL() + "/" + filename, function(entry) {
var videoElement = document.createElement('video');
videoElement.controls = 'controls';
videoElement.src = entry.toNativeURL();
document.videoElementById("output").appendChild(imgElement);
});
});
Update
With the latest version of the File plugin (1.1.0), you no longer need to use .toNativeURL() to obtain a URL that you can use as a src attribute for a video. The standard .toURL() method will return such a URL.
Here is the code to download file using phonegap filetransfer
function downloadFile(){
window.requestFileSystem(
LocalFileSystem.PERSISTENT, 0,
function onFileSystemSuccess(fileSystem) {
fileSystem.root.getFile(
"test.html", {create: true, exclusive: false},
function gotFileEntry(fileEntry){
var Path = fileEntry.fullPath.replace("test.html","");
var fileTransfer = new FileTransfer();
fileEntry.remove();
fileTransfer.download(
yourserverurl,
Path + "yourfilename+extension",
function(theFile) {
window.localStorage.setItem("FilePath", theFile.toURL());
console.log(theFile.toURL());
},
function(error) {
console.log("upload error code: " + error.code);
}
);
},
fail);
},
fail);
}
function fail(error) {
console.log(error.target.error.code);
}
You can store the fileURL in localstorage for further usuage

Categories

Resources