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???
Related
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")
}
Let's say I have a API that stores some .mp3 music.
The sample link here:
https://118.69.201.34:8882/api/ApiMusic/Download?songId=2000
Now I want to write an API calling function in Angularjs to download the music to my Android devices with the song's Id number as in the link.
How can I do that? Please help :(
You can use the ngCordova FileTransfer library here: http://ngcordova.com/docs/plugins/fileTransfer/
Here's example code from that page, tweaked to your example URL:
document.addEventListener('deviceready', function () {
var fileid = "2000";
var url = "https://118.69.201.34:8882/api/ApiMusic/Download?songId=" + fileid;
var targetPath = cordova.file.documentsDirectory + fileid + ".mp3";
var trustHosts = true
var options = {};
$cordovaFileTransfer.download(url, targetPath, options, trustHosts)
.then(function(result) {
// Success!
}, function(err) {
// Error
}, function (progress) {
$timeout(function () {
$scope.downloadProgress = (progress.loaded / progress.total) * 100;
})
});
}, false);
I did it finally, here is my code. Just share for those who want to refer to this issue in the future. Thanks you guys for your answers
$scope.download = function(songId, songName) {
$ionicLoading.show({
template: 'Downloading...'
});
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fs) {
fs.root.getDirectory(
"fMusic",
{
create: true
},
function (dirEntry) {
dirEntry.getFile(
songName + ".mp3",
{
create: true,
exclusive: false
},
function gotFileEntry(fe) {
var p = fe.toURL();
fe.remove();
ft = new FileTransfer();
ft.download(
encodeURI(APIUrl + songId),
p,
function (entry) {
$ionicLoading.hide();
$scope.mp3File = entry.toURL();
},
function (error) {
$ionicLoading.hide();
alert("Download Error Source --> " + error.source);
},
false,
null
);
},
function () {
$ionicLoading.hide();
console.log("Get the file failed");
}
);
}
);
},
function () {
$ionicLoading.hide();
console.log("Request for filesystem failed");
});
}
I'm developing a cordova/phonegap app. Right now, I'm testing the app on Android.
If I include files (audio, video, ...) by default, I can access to that files indicating the "url" like audio/filesong.mp3 or video/filevideo.mp4.
But if I download files with the next code:
function downloadFile() {
var fileTransfer = new FileTransfer();
var uri = encodeURI("UrlOfTheFile");
var fileURL = "cdvfile://localhost/persistent/appcustomstorage/";
fileTransfer.download(
uri, fileURL + "file.extension", 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("upload error code" + error.code);
}, false, {
headers: {
"Authorization": "Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA=="
}
});
}
I download the file in StorageRoot/appcustomstorage/file.extension
It is possible to store the file in the app package, i.e., in, for example, Android/data/com.example.app??
Or a method to get the Android/data/com.example.app url and then add the necessary folder?
Solution:
In this case I find all mp3 in the device. It works on Nexus 4.
index.html
<ul data-role="listview" data-inset="true" id="ulsongs">
</ul>
index JavaScript:
document.addEventListener("deviceready", onDeviceReady, false);
// device APIs are available
function onDeviceReady() {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail);
}
function gotFS(fileSystem) {
FileSystem = fileSystem;
// Call to start to find all files
getFileSystem();
}
storageScript:
var FileSystem = null;
var AudioExtensions = [ '.mp3' ];// , '.wav', '.m4a' ];
var my_media = null;
function listDir(directoryEntry, level) {
if (level === undefined)
level = 0;
var directoryReader = directoryEntry.createReader();
directoryReader.readEntries(function(entries) { // success get files and
// folders
for ( var i = 0; i < entries.length; ++i) {
if (entries[i].name === '.')
continue;
if (entries[i].isDirectory) {
FileSystem.root.getDirectory(entries[i].fullPath.slice(1,
entries[i].fullPath.length), {
create : false
}, function(dirEntry) {
listDir(dirEntry, level + 1);
}, function(error) {
console.log('ERROR');
alert(error.code);
});
}
if (entries[i].isFile) {
var extension;
extension = entries[i].name.substr(entries[i].name
.lastIndexOf('.'));
if (entries[i].isFile === true
&& $.inArray(extension, AudioExtensions) >= 0) {
// Add a song to the list
$("#ulsongs").append(
"<li id='" + entries[i].fullPath + "'"
+ " data-icon=\"audio\"><a>"
+ entries[i].name + "</a></li>");
$('#ulsongs').listview('refresh');
}
}
}
}, function(error) { // error get files and folders
alert('Error. Code: ' + error.code);
});
// Action listener
$('#ulsongs li').click(function(e) {
pathsong = $(this).attr('id');
console.log('item clicked. Path: ' + pathsong);
if (typeof (pathsong) != 'undefined' && pathsong != null) {
// Stop previous song
if ((audio_status != null) && (audio_status == 2)) {
console.log('STOP AUDIO');
my_media.stop();
my_media.release();
}
// Play the audio file at url
my_media = new Media(pathsong,
// success callback
function() {
console.log("playAudio():Audio Success");
},
// error callback
function(err) {
console.log("playAudio():Audio Error: " + err);
}, status);
// Play audio
my_media.play();
}
});
}
var audio_status = null;
function status(stat) {
audio_status = stat;
}
/**
*
*/
function getFileSystem() {
console.log('entra getFileSystem');
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0,
function(fileSystem) { // success get file system
var sdcard = fileSystem.root;
sdcard.getDirectory('', {
create : false
}, function(dirEntry) {
listDir(dirEntry);
}, function(error) {
alert(error.code);
})
}, function(evt) { // error get file system
console
.log('ERROR GETTING FILE SYSTEM'
+ evt.target.error.code);
});
}
I create a list of mp3.
I use jQuery and jQueryMobile
Edit
The process may need a bit of time. It is recommended to show a loading popup.
I develop an app for Android with Sencha Touch and Phonegap (cordova-2.0.0).
I have an Ext.Panel with some HTML in it, For Instance:
<body>
MyPage
</body>
My Problem: When I run the app on device and tap the link, Android browser opens the URL and it quits the app.
My Aim: When I run the app on device and tap the link, the app should show the tapped link, For Instance:
navigator.notification.alert(MyPage.html);
My Phonegap code(shows the uniqueid.html in the HTMLPanel):
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, onRequestFileSystemSuccess, null);
function onRequestFileSystemSuccess(fileSystem) {
fileSystem.root.getDirectory(Ext.ComponentQuery.query('#bibliothekDataView')[0].getSelection()[0].get('directory'), null, SelectedItemSuccess, SelectedItemFail);
}
//shows the uniqueid.html in the HTMLPanel
function SelectedItemSuccess(dir) {
dir.getFile(record.get('id') + '.html', null, gotFileEntry, fail);
}
function SelectedItemFail() {
navigator.notification.alert("Failed to read file contents: " + error.code);
}
function gotFileEntry(file) {
file.file(gotFile, fail);
}
function gotFile(file) {
readAsText(file);
}
function readAsText(file) {
var reader = new FileReader();
reader.onload = function (evt) {
Ext.ComponentQuery.query('#mainHTMLPanel')[0].setHtml(evt.target.result);
};
reader.onerror = function () {
navigator.notification.alert("Failed to read file!");
};
reader.readAsText(file);
}
function fail(error) {
navigator.notification.alert("Failed to read file contents: " + error.code);
}
My HTMLPanel (View):
Ext.define('myApp.view.HTMLPanel', {
extend: 'Ext.Panel',
xtype: 'mainhtmlpanel',
config: {
id: 'mainHTMLPanel',
scrollable: 'vertical',
}
});
Do you have control over HTML content displayed in Ext.Panel? If yes, then change MyPage to MyPage.
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