I'm trying to get external storage path in Phonegap. I'm using this code but it never handles the correct SDCard path.
(function(){
window.appRootDirName = ".myapp";
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
alert(cordova.file.externalRootDirectory);
console.log("device is ready");
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail);
}
function fail() {
console.log("failed to get filesystem");
}
function gotFS(fileSystem) {
console.log("filesystem got");
fileSystem.root.getDirectory(window.appRootDirName, {
create : true,
exclusive : false
}, dirReady, fail);
}
function dirReady(entry) {
window.appRootDir = entry;
alert(JSON.stringify(window.appRootDir));
}
})();
also
<preference name="AndroidPersistentFileLocation" value="Internal" />
and
<preference name="AndroidPersistentFileLocation" value="Emulated" />
doesn't help.
Are there a way to get the correct SDCard path on Android 6 with phonegap?
This is how i made it work in android as well as in iOS,
function writeFile() {
if (sessionStorage.platform.toLowerCase() == "android") {
window.resolveLocalFileSystemURL(cordova.file.externalRootDirectory, onFileSystemSuccess, onError);
} else {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, onFileSystemSuccess, onError);
}
}
function onError(e) {
alert("onError");
};
function onFileSystemSuccess(fileSystem) {
var entry = "";
if (sessionStorage.platform.toLowerCase() == "android") {
entry = fileSystem;
} else {
entry = fileSystem.root;
}
entry.getDirectory("Folder_Name", {
create: true,
exclusive: false
}, onGetDirectorySuccess, onGetDirectoryFail);
};
function onGetDirectorySuccess(dir) {
dir.getFile(filename, {
create: true,
exclusive: false
}, gotFileEntry, errorHandler);
};
function gotFileEntry(fileEntry) {
// logic to write file in respective directory
};
function errorHandler(e) {
// handle error
}
Try out this one.
document.addEventListener("deviceready", onDeviceReady, false);
// device APIs are available
//
function onDeviceReady() {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, onFileSystemSuccess, fail);
}
function onFileSystemSuccess(fileSystem) {
fileSystem.root.getDirectory("App_files", {create: false, exclusive: false}, onGetDirectoryWin, onGetDirectoryFail);
}
function fail(evt) {
console.log(evt.target.error.code);
}
var onGetDirectoryWin = function(parent) {
}
var onGetDirectoryFail = function() {
console.log("error getting dir")
}
Related
I am creating an app in android using phonegap and ionic , to retrieve images from sdcard and display it.So i have been able to retrieve all the images but it takes more time to display these images.scrolling is also very slow and clicks take over a second for anything to happen. I am using collection -repeat for displaying these images.This is my code :
function onDeviceReady() {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail);
}
function gotFS(fileSystem) {
window.fileSystem = fileSystem;
fileSystem.root.getDirectory("", {
create: false,
exclusive: false
}, getsubdirectry, onError);
}
function getsubdirectry(dirEntry, onComplete) {
try {
var directoryReader = dirEntry.createReader();
} catch (e) {
alert(e);
}
directoryReader.readEntries(function(entries) {
for (i = 0; i < entries.length; i++) {
if (entries[i].name.indexOf(".jpg") == -1) {
if (entries[i].isDirectory) {
entries[i].getDirectory("", {
create: false,
exclusive: false
}, getsubdirectry, onError);
}
} else {
imagedetails.push({
id: i,
url: entries[i].toURI(),
tag: ""
});
}
}
onComplete();
}, function(error) {
alert("Error: = " + error.code);
});
}
In html
<a href="#/tab/photo/{{friend.id}}" class="gallery-item" collection-repeat="friend in outputphotos | myFilter:text track by $index" collection-item-width="'33%'"
collection-item-height="'33%'">
<img ng-src="{{friend.url}}" id="imageviewmainpage">
</a>
So what changes should i add to make the loading fast or is there any other way???
Why this works :
myFile1 = "myReadme.txt";
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail);
function gotFS(fileSystem) {
fileSystem.root.getFile(myFile1, {create: true, exclusive: false}, gotFileEntry, fail);
}
function gotFileEntry(fileEntry) {
alert("good");
}
function fail(error) {
alert("Error");
}
and that doesn't work ?
myFile2 = cordova.file.externalDataDirectory + "myReadme.txt";
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail);
function gotFS(fileSystem) {
fileSystem.root.getFile(myFile2, {create: true, exclusive: false}, gotFileEntry, fail);
}
function gotFileEntry(fileEntry) {
alert("good");
}
function fail(error) {
alert("Error");
}
Can we not use cordova.file.dataDirectory or cordova.file.externalRootDirectory or externalDataDirectory for Android ?
Thank you
I'm gonna try to answer with this issue (but I'm sure we can to do better ? )
First, when I plug my device to my computer the tree path is about like that :
MyFile1.txt
MyApplication
MyFiles
MyCache
Application
DCIM
media
Movies
Musics
Android
data
data (I think is not accessible when your are not rooted ???)
com.MyDomainName.MyAppName
cache
files
Then,
Following this official Cordova document : http://plugins.cordova.io/#/package/org.apache.cordova.file
, My first wish is to store my files and datas with "cordova.file.dataDirectory" or "cordova.file.externalDataDirectory" or another else ... ?
when you're doing console.log(cordova.file.dataDirectory) you obtain file:///data/data/com.MyDomainName.MyAppName/files/ => This, you cannot access when you are no rooted
and when you're doing console.log(cordova.file.externalDataDirectory) you obtain
file:///storage/emulated/0/
and when you're doing that
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail);
function gotFS(fileSystem) { console.log(fileSystem.root) ...
you can see in this object : nativeURL: "file:///storage/emulated/0/" ... so, it's the same like "externalDataDirectory" and I suppose we cannot use "dataDirectory" ...
Anyway, I don't know whether it's the best practice but here you are my solution :
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, onFSWin, getDirectoryFail);
function onFSWin(fileSystem) {
fileSystem.root.getDirectory("myFolder", {create: true, exclusive: false}, getDirectorySuccess, getDirectoryFail);
}
function getDirectorySuccess(parent) {
console.log("New Folder or Folder already exists: " + parent.fullPath);
}
function getDirectoryFail(error) {
console.log("Unable to create new directory: " + error.code);
}
// Second, we gonna check or create a new file in a specific folder
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, onFSWin2, onFSFail2);
function onFSWin2(fileSystem) {
fileSystem.root.getFile("myFolder/myFile1.txt", {create: true, exclusive: false}, gotFileEntry, onFSFail2);
}
function gotFileEntry(fileEntry) {
console.log("New file: " + fileEntry.fullPath);
fileEntry.createWriter(gotFileWriter, onFSFail2);
}
function gotFileWriter(writer) {
writer.onwriteend = function(evt) {
console.log("contents of file now 'some sample text'");
writer.truncate(11);
writer.onwriteend = function(evt) {
console.log("contents of file now 'some sample'");
writer.seek(4);
writer.write(" different text");
writer.onwriteend = function(evt){
console.log("contents of file now 'some different text'");
}
};
};
writer.write("some sample text");
}
function onFSFail2(error) {
console.log(error.code);
}
You can use resolveLocalFileSystemURL to use the cordova.file.* properties:
window.resolveLocalFileSystemURL(cordova.file.externalDataDirectory, function (dirEntry) {
dirEntry.getFile("myFile1.txt", {
create: true,
exclusive: false
}, function (fileEntry) {
// fileEntry.createWriter
}, onError);
});
Morning,
I am using the following to create a file on the local file system. This creates a file if it did not already exist.
function onDeviceReady() {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail);
}
function gotFS(fileSystem) {
fileSystem.root.getFile("test.txt", {create: true}, gotFileEntry, fail);
}
function gotFileEntry(fileEntry) {
fileEntry.createWriter(gotFileWriter, fail);
}
function gotFileWriter(writer) {
writer.onwrite = function(evt) {
alert("write success");
};
writer.write("We are testing")
}
function fail(error) {
if(error.code == 1){
alert('not found');
}
alert(error.code);
}
However, I need to write to the file ONLY if it did not already exist.
I tried using
function gotFS(fileSystem) {
fileSystem.root.getFile("test.txt", null, gotFileEntry, fail);
}
function gotFS2(fileSystem) {
alert('trying again');
fileSystem.root.getFile("test.txt", {create:true}, gotFileEntry, fail);
}
function fail(error) {
if(error.code == 1){
alert('not found');
gotFS2(fileSystem);
}
alert(error.code);
}
and then calling gotFS2 if error.code == 1
but that did nothing - it didn't even create the file when it didn't exist.
It seems that gotFS2 was not called, yet alert('not found'); in the function fail(error) works.
What's the easiest way to do what I am trying to do?
It seems that problem is in your not saving fileSystem variable (which is in local scope in "gotFS"), so my suggestion is:
var savedFS;
function gotFS(fileSystem) {
savedFS = fileSystem;
fileSystem.root.getFile("test.txt", null, gotFileEntry, fail);
}
function gotFS2(fileSystem) {
alert('trying again');
fileSystem.root.getFile("test.txt", { create: true }, gotFileEntry, function() {});
}
function fail(error) {
if (error.code == 1) {
alert('not found');
gotFS2(savedFS);
}
alert(error.code);
}
How can I create a nested directory in Phonegap with this API?
fileSystem.root.getDirectory("Android/data/com.phonegap.myapp/dir_one/dir_two/", {create:true}, gotDir, onError);
I am using Phonegap 1.8.0 in Android 2.2.
This function will help you create nested dirs.
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
console.log("device is ready");
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail);
}
function fail() {
console.log("failed to get filesystem");
}
function gotFS(fileSystem) {
window.FS = fileSystem;
var printDirPath = function(entry){
console.log("Dir path - " + entry.fullPath);
}
createDirectory("dhaval/android/apps", printDirPath);
createDirectory("this/is/nested/dir", printDirPath);
createDirectory("simple_dir", printDirPath);
}
function createDirectory(path, success){
var dirs = path.split("/").reverse();
var root = window.FS.root;
var createDir = function(dir){
console.log("create dir " + dir);
root.getDirectory(dir, {
create : true,
exclusive : false
}, successCB, failCB);
};
var successCB = function(entry){
console.log("dir created " + entry.fullPath);
root = entry;
if(dirs.length > 0){
createDir(dirs.pop());
}else{
console.log("all dir created");
success(entry);
}
};
var failCB = function(){
console.log("failed to create dir " + dir);
};
createDir(dirs.pop());
}
For full example check this gist
Just to add something to dhaval's function: it's not bullet proof for any browser compliant with Javascript Filesystem. If you use it with Chrome and your path is an empty string, it will fail, because apparently, with Chrome, using split() on an empty string returns a one element array, the one element being an epmty string itself, which then causes the directory creation to fail. I modified it in order to correct the problem (there also some other not related changes, for my own purposes):
function createPath(fs, path, callback) {
var dirs = path.split("/").reverse();
var root = fs.root;
var createDir = function(dir) {
if (dir.trim()!="") {
root.getDirectory(dir, {
create: true,
exclusive: false
}, success, function(dir) {
error("failed to create dir " + dir);
});
} else {
callback();
}
};
var success = function(entry) {
root = entry;
if (dirs.length > 0) {
createDir(dirs.pop());
} else {
callback();
}
};
createDir(dirs.pop());
}
This code should do what you want:
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(filesys) {
filesys.root.getDirectory("story_repository", {create: true, exclusive: false}, function(dirEntry) {
dirEntry.getDirectory("dir_name", {create: true, exclusive: false}, function(dirName) {
dirName.getDirectory("img", {create: true, exclusive: false}, function(imgDir) {
console.log("img creation worked");
}, function(error) {
console.log("create img failed");
});
dirName.getDirectory("res", {create: true, exclusive: false}, function(imgDir) {
console.log("res creation worked");
}, function(error) {
console.log("create res failed");
});
}, function(error) {
console.log("create dir_name failed");
})
}, function(error) {
console.log("create story repository failed");
});
}, function(error) {
console.log("request file system failed");
});
I'm using this:
function recursiveGetFile(root, path, opts, success, fail) {
function dir(entry) {
var name = path.shift();
if (path.length > 0)
entry.getDirectory(name, opts, dir, fail);
else
entry.getFile(name, opts, success, fail);
}
path = path.split('/');
dir(root);
}, fail);
There is a simple file manager for cordova-phoengap, with with you can do this and much more:
https://github.com/torrmal/cordova-simplefilemanagement
You can recursively create directories:
//CREATE A DIRECTORY RECURSIVELY as simple as:
new DirManager().create_r('folder_a/folder_b',Log('created successfully'));
Let me know if it helps
I tried writing/reading a file in phonegap+android, here is the set up:
$(document).ready(function() {
document.addEventListener("deviceready", deviceready, true);
$(document).bind("deviceready", function(){
//writeFile();
//readFile();
});
});
function deviceready() {
writeFile();
readFile();
}
// This is just to do this.
function readFile() {
var d = navigator.file.read('/sdcard/foo.xml', success(), fail());
console.warn(d);
}
function writeFile() {
navigator.file.write('/sdcard/foo.xml', "This is a test of writing to a file",
success(), fail());
}
But on the emulator for Android 2.2, I got the following error message:
08-06 14:21:29.428: INFO/Web Console(936): Error in success callback: Network Status1 = TypeError: Result of expression 'navigator.file' [undefined] is not an object. at file:///android_asset/www/phonegap.0.9.6.js:649
What could be missing and what could be tried?
This also works in Android 2.2. You call the load(); function from body's onLoad, and writeFileFromSDCard(string) from some button's onClick, passing as parameter the string you want to write in the file.
<script type="text/javascript" charset="utf-8">
// Event listener
function load() {
document.addEventListener('deviceready', init, false);
}
// Called when device is ready - Do nothing
function init() {
}
// Called to write file to card
function writeFileFromSDCard(param) {
var writer = new FileWriter("/sdcard/write.txt");
writer.write(param + "\n", false);
alert("file Written to SD Card");
}
</script>
I would try using the FileReady and FileWriter APIs.
http://docs.phonegap.com/phonegap_file_file.md.html#FileReader
Here is what I came up with based on several links. I had been searching to do this as well. I used this site as a reference http://www.digitalnoiz.com/mobile-development/mobile-file-explorer-with-phonegapcordova-and-jquery-mobile-part-1/ as well as the Phonegap document api references
function displayMessage(msg)
{
navigator.notification.alert(msg);
}
function loadDirectories(fileSystem)
{
directoryEntry = fileSystem.root;
var directoryReader = directoryEntry.createReader();
directoryReader.readEntries(function(entries){
var sOutput = "";
for(var i=0; i < entries.length; i++)
{
if(!entries[i].isDirectory)
{
fileSystem.root.getFile(entries[i].name,null,gotFileEntry,fail);
}
}
//displayMessage(sOutput);
},fail);
}
function gotFileEntry(fileEntry)
{
fileEntry.file(function(file){
var reader = new FileReader();
reader.onloadend = function(evt){
displayMessage(evt.target.result);
};
reader.readAsText(file);
},fail);
}
function failFile(evt)
{
displayMessage(evt.target.error.code);
}
function fail(error)
{
displayMessage("Failed to list directory contents: " + error.code);
}
function onBodyLoad()
{
document.addEventListener("deviceready", onDeviceReady, false);
}
function onDeviceReady()
{
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, loadDirectories, fail);
}
The following works for me on Android with phonegap-1.0.0:
<script type="text/javascript" charset="utf-8" src="css-js/phonegap-1.0.0.js"></script>
<script type="text/javascript" charset="utf-8">
// Wait for PhoneGap to load
//
document.addEventListener("deviceready", onDeviceReady, false);
// PhoneGap is ready
//
function onDeviceReady() {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail);
}
function gotFS(fileSystem) {
var path = "readme.txt";
fileSystem.root.getFile(path, {create: true, exclusive: false}, gotFileEntry, fail);
}
function gotFileEntry(fileEntry) {
fileEntry.createWriter(gotFileWriter, fail);
}
function gotFileWriter(writer) {
writer.onwrite = function(evt) {
console.log("write success");
};
writer.write("some sample text");
</script>