I am developing hybrid application (POC) using Cordova and Sencha Touch 2.4, Objective is to develop file explorer.
Actually i did it using Cordova File API and I can able to access all the folders and files in Android, But in iOS i can able to read only No Cloud Folder (Don't know what is that folder).
I want to access complete folder structure in iOS, Just like Android.
After number of search i got info that in IOS we can't access file system using Safari browser, Is it same for Hybrid App ?
Is there any other way to achieve this ?
This is what i am doing, Using File API i am requesting file system (ROOT Folder) and when the user tap any folder, i am reading files and folders in that folder. When the user tap file i am simply showing an alert that the user selected File.
Cordova [config.xml]
<preference name="iosExtraFilesystems"
value="library,library-nosync,documents,documents-nosync,cache,bundle,root" />
<preference name="AndroidExtraFilesystems"
value="files,files-external,documents,sdcard,cache,cache-external,root" />
Controller Code
browseFs : function(button, e, eOpts){
Ext.Viewport.add(this.getFileBrowserWindow());
this.getFileBrowserWindow().show();
this.getFileBrowserWindow().mask();
this.createFileSysList(MTDProduct.app.currentDir);
},
fileBack : function(button, e, eOpts){
this.getFileBrowserWindow().mask();
this.createFileSysList(MTDProduct.app.parentDir);
},
createFileSysList : function(currentDir){
console.log(currentDir);
var me = this;
if(!currentDir){
currentDir = MTDProduct.app.rootFolder;
}
MTDProduct.app.currentDir = currentDir;
var directoryReader = currentDir.createReader();
Ext.getStore('filesList').removeAll();
directoryReader.readEntries(function(entries){
var dirArr = new Array();
var fileArr = new Array();
for(var i=0; i<entries.length; ++i){
var entry = entries[i];
var data;
if( entry.isDirectory && entry.name[0] != '.' ) {
data = { name: entry.name, type: 'Directory'}
}
else if( entry.isFile && entry.name[0] != '.' ){
data = { name: entry.name, type: 'File'}
}
Ext.getStore('filesList').add(data);
Ext.getStore('filesList').sync();
}
currentDir.getParent(function(parent){
MTDProduct.app.parentDir = parent;
me.getFileBack().show();
},
function(error){
me.getFileBack().hide();
alert('Get parent error: '+error.code);
});
me.getFileBrowserWindow().unmask();
}, function(error){
me.getFileBrowserWindow().unmask();
alert('listDir readEntries error: '+error.code);
});
},
fileTap : function( list, index, target, record, e, eOpts ){
this.getFileBrowserWindow().mask();
var data = record.getData();
var currentDir = MTDProduct.app.currentDir;
var me = this;
if( data.type == 'Directory' && currentDir != null ){
console.log('Directory');
currentDir.getDirectory(data.name, {create:false},
function(dir){
me.createFileSysList(dir);
},
function(error){
alert('Unable to find directory: '+error.code);
}
);
}
else if(data.type == 'File' && currentDir != null){
alert('Selected a file');
me.getFileBrowserWindow().unmask();
me.getFileBrowserWindow().hide();
}
}
This is not possible, Apple has limited the file access to just the app itself's. So there is no other way of accessing it.
You can view files only in that your App's sandbox. Every App has got a Documents, Cache and temp folders. I think the first two are automatically backed up by iTunes when you connect your device, the latter is not backed up.
Example, to get files in Cache directory path -
NSError *err = nil;
NSArray *myPathList = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *myPath = [myPathList objectAtIndex:0];
NSArray *dirContent = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:myPath error:&err];
if(err) NSLog(#"ERROR: %#",[err localizedDescription]);
NSMutableArray *filePaths = nil;
int count = (int)[dirContent count];
for(int i=0; i<count; i++)
{
[filePaths addObject:[dirContent objectAtIndex:i]];
}
return filePaths;
Related
I am building a mobile app for body measurement through photo I capture. how I can use OpenCV for the same? How to integrate OpenCV with Ionic framework? Kindly help.
Essentially you can pull in a flavor of the opencv.js framework. The way I've done it is by pulling down some reference like https://docs.opencv.org/3.4.1/opencv.js, and then hosting it somewhere (in case opencv moves it on you). Then include that script in the Ionic project. Be careful how you do that though. It is a big file, so it could take the app longer to load. Some options I've used:
Local Asset
Store the js file in the local assets, and include it in the index.js. If the Ionic app is deployed as a native app, then this asset is already in the app and fairly fast to load.
<script src="assets/js/opencv.js" async></script>
Dynamically load the file (example below)
async ionViewDidLoad() {
let loadingScreen = this.loadingCtrl.create({ content: "Loading Scripts. Please Wait..." });
//Show loading screen & load scripts
try {
await loadingScreen.present();
await this.loadScript();
}
catch (error) {
this.errorMessage = "We had some trouble loading scripts...";
}
finally {
loadingScreen && loadingScreen.dismiss();
}
}
public loadScript(): Promise<any> {
return new Promise((resolve, reject) => {
var isFound = false;
var scripts = document.getElementsByTagName("script")
for (var i = 0; i < scripts.length; ++i) {
if (scripts[i].getAttribute('src') != null &&
scripts[i].getAttribute('src').includes("opencv")) {
isFound = true;
return resolve();
}
}
if (!isFound) {
var dynamicScripts = ["https://docs.opencv.org/3.4.1/opencv.js"];
for (var i = 0; i < dynamicScripts.length; i++) {
let scriptNode = document.createElement('script');
scriptNode.src = dynamicScripts[i];
scriptNode.type = 'text/javascript';
scriptNode.async = false;
scriptNode.charset = 'utf-8';
document.getElementsByTagName('head')[0].appendChild(scriptNode);
scriptNode.onload = resolve;
}
}
});
}
I'm making an app capable of take photos and upload them to a server. The phone will save the id generated.
I made a class abstractApp that creates an App object with a couple of helpers and variables. I'm using Framework7.
var App;
document.addEventListener("deviceready", function() {
App = new abstractApp();
var i;
App.f7Ref = new Framework7({init: false});
for (i = 0; i < App.constants.views.length; i++)
{
if (i==0)
App.mainView = App.f7Ref.addView (
App.constants.views[i].selector,
App.constants.views[i].settings );
else
App.f7Ref.addView (
App.constants.views[i].selector,
App.constants.views[i].settings );
}
// Checks if there exists register of remote photos
if ( App.local.get('remotephotos', false) == null || App.local.get('remotephotos', false) == '' )
{
App.remotephotos = [];
App.local.set('remotephotos', []);
}
else
{
App.remotephotos = App.local.get('remotephotos');
}
// Checks if there exists register of local photos
if ( App.local.get('localphotos', false) == null || App.local.get('localphotos', false) == '' )
{
App.localphotos = [];
App.local.set('localphotos', []);
}
else
{
App.localphotos = App.local.get('localphotos');
}
for (i = 0; i < appControllers.length; i++)
{
appControllers[i].apply(App);
}
console.log(App);
}, false);
In appControllers I'm saving functions related to each page (so it is a bit more organized). With only index and new-photo controllers I have no problem, I can attach events to elements and navigate between views. The problem is calling the camera object.
window.appControllers.push(function()
{
var $$ = Dom7;
var Ref = this.f7Ref;
var server = new serverInterface();
var photos = this.remotephotos;
var App = this;
Ref.onPageInit('new', function (page) {
Ref.alert('entra', 'entra');
$$('.capture').on('click', function () {
Ref.alert('Click', 'Click detected');
navigator.camera.getPicture(onSuccess, onFail,
{
quality: 20,
destinationType: destinationType.FILE_URI
});
function onSuccess(imageURI) {
Ref.alert('Photo captured.', 'Bien');
}
function onFail(message) {
Ref.alert('There was a problem.', 'Ups');
}
});
});
});
So, I enter the new page and I click the button with cass capture and the alert (click detected) appears, but it doesn't show the camera to take the photo.
I'm using Phonegap Build and an android phone, do you have any idea of what's happening?
Thank you very much in advance
The problem wasn't the javascript code I quoted.
I was loading the camera plugin in the config.xml like this
<gap:plugin name="org.apache.cordova.camera" />
But it should be loaded this way:
<plugin name="cordova-plugin-camera" />
If the plugin is not loaded correctly, in Phonegap Build appears: version n/a installed. In this case, when it is correctly loaded, appears: version 2.1.0 installed.
More information about this thread can be found here: http://phonegap.com/blog/2015/11/19/config_xml_changes_part_two/
Hope it helps someone else too
Regards
i have problem to sync local image folder to server, i using titanium. When i run my program using android emulator, it works well. But when i try to run it using actual device, the program can not find the image file.
Below is my code. Please help.
$.btnfiles.addEventListener('click',function(e)
{
var dirTest = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory);
var dirList = dirTest.getDirectoryListing();
Titanium.API.info('Start loop for files length:' + dirList.length);
for ( i = 0; i < dirList.length; ++i){
var f = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory, dirList[i]);
var data_to_send = {
"file": f.read(), "name1":Titanium.Filesystem.applicationDataDirectory
};
xhr = Titanium.Network.createHTTPClient({
// function called when an error occurs, including a timeout
onerror : function(e) {
//Ti.API.debug(e.error);
alert('error');
},
timeout : 5000 // in milliseconds
});
xhr.setRequestHeader("enctype", "multipart/form-data");
xhr.open("POST","upload.php");
xhr.send(data_to_send);
Titanium.API.info('Namef: ' + dirList[i]);
Titanium.API.info('Name: ' + i);
var file = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory,dirList[i]);
if (file.exists()) { file.deleteFile(); }
}
});
I am trying to generate a PDF using the jsPDF library (https://github.com/MrRio/jsPDF) from within a mobile Cordova app. I am currently testing the app on an Android 4.0.4 device but it also needs to run on Windows mobile 8. The text in the PDF document is shown correctly however any images are scrambled. See image below
I did find this page (https://coderwall.com/p/nc8hia) that seemed to indicate there is a problem with jsPDF displaying images in Cordova (see comments) but the author never posted the follow-up. Has anyone been able to use jsPDF with Cordova and properly add images to the generated PDF? My code is below, any assistance or advice would be greatly appreciated.
function demoReceipt() {
var img = new Image();
img.onError = function() {
alert('Cannot load image: "' + url + '"');
};
img.onload = function() {
createPdf2(img);
};
img.src = 'img/testlogo.png';
}
function createPdf2(myLogo) {
// var doc = new jsPDF('p', 'pt', 'jontype');
var doc = new jsPDF('p', 'pt', 'letter');
doc.setProperties({
title : 'Fueling Receipt',
author : 'Jon Hoffman',
creater : 'Jon Hoffman'
});
doc.addImage(myLogo, 'PNG', 5, 5, 140, 30);
doc.setFontSize(12);
doc.text(10, 40, 'Sample PDF receipt');
doc.setFontSize(8);
doc.text(10, 45, 'Smaller text - new');
var pdfOutput = doc.output();
//NEXT SAVE IT TO THE DEVICE'S LOCAL FILE SYSTEM
//Requires cordova plugin add org.apache.cordova.file
console.log("file system...");
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSystem) {
console.log(fileSystem.name);
console.log(fileSystem.root.name);
console.log(fileSystem.root.fullPath);
fileSystem.root.getDirectory("myPDFs", {
create : true,
exclusive : false
}, function(dir) {
fileSystem.root.getFile("myPDFs/test.pdf", {
create : true
}, function(entry) {
var fileEntry = entry;
console.log(entry);
entry.createWriter(function(writer) {
writer.onwrite = function(evt) {
console.log("write success");
};
console.log("writing to file");
writer.write(pdfOutput);
}, function(error) {
console.log(error);
});
}, function(error) {
console.log(error);
});
}, function(error) {
});
}, function(event) {
console.log(evt.target.error.code);
});
}
I solved the issue with help from this blog post: https://coderwall.com/p/nc8hia. There does seems to be significant differences between the 0.90 version used in that post and the version that I am using from https://github.com/MrRio/jsPDF however the solution is pretty much the same.
First off, in the version from MyRio, you can get the PDF generation working without fixing the Blob issue noted in Igor’s post. All you need is to generate the PDF output by calling “doc.ouput()” and then save it using the Cordova filesystem plugin. So I thought I did not have to create the Blob (this is where I was wrong).
Igor (from the coderwall post) responded back to my question with some additional code but when I searched the jspdf.js file from MyRio version, I saw that the code (more compact version) was already in the code on lines 734 – 738:
var data = buildDocument(), len = data.length,
ab = new ArrayBuffer(len), u8 = new Uint8Array(ab);
while(len--) u8[len] = data.charCodeAt(len);
return new Blob([ab], { type : "application/pdf" });
But I also notice that the blob creation code that Igor fixed in his initial post was at the end of this block of code. So I commented out the “return new Blob([ab], { type : “application/pdf”});” line and put in the following code from Igor’s post with minor variable name changes:
try
{
var blob = new Blob([ab], {type: "application/pdf"});
console.debug("case 1");
return blob;
}
catch (e)
{
window.BlobBuilder = window.BlobBuilder ||
window.WebKitBlobBuilder ||
window.MozBlobBuilder ||
window.MSBlobBuilder;
if (e.name == 'TypeError' && window.BlobBuilder)
{
var bb = new BlobBuilder();
bb.append(ab);
console.debug("case 2");
return bb.getBlob("application/pdf");
}
else if (e.name == "InvalidStateError")
{
// InvalidStateError (tested on FF13 WinXP)
console.debug("case 3");
return new Blob([ab], {type: "application/pdf"});
}
else
{
// We're screwed, blob constructor unsupported entirely
console.debug("Errore");
}
}
Then when I generate that pdfOutput, in my code, I changed
var pdfOutput = doc.output();
to
var pdfOutput = doc.output(“blob”);
and it worked.
I hope this post is able to help out others experiencing the same issues.
I have been struggling with Phonegap and Photoswipe. Here is what I have:
1) Currently I am requesting remote images via a php JSON call (working)
2) JSON images are returned and store locally to the Android device(working)
3) All images show up on Photswipe thumbnail gallery page (working)
problem is here
4) when I click on a thumbnail image, I'm not getting the Photoswipe gallery format, it just loads an the image to a blank page.
My guess is the photoswipe script is loading before I have completely passed all the images to the <#gallery
My question is how to re-initialize Photoswipe to read all the images or how to attached the Photoswipe function to the images that are appended to the
I'm trying to post the code I have working now, having trouble with the formatting here.
//Global instance of DirectoryEntry for our data
var DATADIR;
var knownfiles = [];
//Loaded my file system, now let's get a directory entry for where I'll store my crap
function onFSSuccess(fileSystem) {
fileSystem.root.getDirectory("Android/data/com.moto.photoloader",create:true,exclusive:false},gotDir,onError);
}
//The directory entry callback
function gotDir(d){
console.log("got dir");
DATADIR = d;
var reader = DATADIR.createReader();
reader.readEntries(function(d){
gotFiles(d);
appReady();
},onError);
}
//Result of reading my directory
function gotFiles(entries) {
console.log("The dir has "+entries.length+" entries.");
for (var i=0; i<entries.length; i++) {
console.log(entries[i].name+' dir? '+entries[i].isDirectory);
knownfiles.push(entries[i].name);
renderPicture(entries[i].fullPath);
}
}
function renderPicture(path){
$("#Gallery").append("<li><a href='"http://myurltofullimages"'><img src='"+path+"' alt=\"Image 018\"/></a></li>");
console.log("<li><a href='"/myurltofullimages"'><img src='"+path+"' alt=\"Image 018\"/></a></li>");
}
function onError(e){
console.log("ERROR");
console.log(JSON.stringify(e));
}
function onDeviceReady() {
//what do we have in cache already?
$("#status").html("Checking your local cache....");
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, onFSSuccess, null);
}
function appReady(){
$("#status").html("Ready to check remote files...");
$.get("http://myurltojsonphp/photo_upload/json.php", {}, function(res) {
if (res.length > 0) {
$("#status").html("Going to sync some images...");
for (var i = 0; i < res.length; i++) {
if (knownfiles.indexOf(res[i]) == -1) {
console.log("need to download " + res[i]);
var ft = new FileTransfer();
var dlPath = DATADIR.fullPath + "/" + res[i];
console.log("downloading crap to " + dlPath);
ft.download("http://myurl/photo_upload/am/woman/thumb/" + escape(res[i]), dlPath, function(){
renderPicture(e.fullPath);
console.log("Successful download of "+e.fullPath);
}, onError);
}
}
}
$("#status").html("");
}, "json");
}
{
document.addEventListener("deviceready", onDeviceReady, true);
}
</script>
<script type="text/javascript">
(function(window, PhotoSwipe){
document.addEventListener('DOMContentLoaded', function(){
var
options = {},
instance = PhotoSwipe.attach( window.document.querySelectorAll('#Gallery a'), options );
}, false);
}(window, window.Code.PhotoSwipe));
</script>
After receiving the photos by the GET call, you must initialize photoswipe gallery:
$("ul.gallery a").photoSwipe(
{
allowUserZoom: false,
jQueryMobile: true,
autoStartSlideshow: false,
backButtonHideEnabled: false,
captionAndToolbarAutoHideDelay: 0,
preventSlideshow: true
});