I'm having a frustrating issue getting cordova to write files to Android devices.
According to the log, everything is firing correctly and the plugin methods are responding with successes etc, but when I go searching for the files they're no where to be found.
Currently I'm just using a fresh phonegap test application and I followed the following guide and used their example code verbatim. The plugins are installed according to the logs are executing.
http://docs.phonegap.com/en/edge/cordova_file_file.md.html
I'm expecting the file to show up in /android/data/com.testapp.myapp/files
This is my test code:
var app = {
// Application Constructor
initialize: function() {
this.bindEvents();
},
// Bind Event Listeners
//
// Bind any events that are required on startup. Common events are:
// 'load', 'deviceready', 'offline', and 'online'.
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
},
// deviceready Event Handler
//
// The scope of 'this' is the event. In order to call the 'receivedEvent'
// function, we must explicitly call 'app.receivedEvent(...);'
onDeviceReady: function() {
app.receivedEvent('deviceready');
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, app.gotFS, app.fail);
},
// Update DOM on a Received Event
receivedEvent: function(id) {
var parentElement = document.getElementById(id);
var listeningElement = parentElement.querySelector('.listening');
var receivedElement = parentElement.querySelector('.received');
listeningElement.setAttribute('style', 'display:none;');
receivedElement.setAttribute('style', 'display:block;');
console.log('Received Event: ' + id);
},
gotFS: function(fileSystem) {
fileSystem.root.getFile("testFile.txt", {create: true, exclusive: false}, app.gotFileEntry, app.fail);
},
gotFileEntry: function(fileEntry) {
fileEntry.createWriter(app.gotFileWriter, app.fail);
},
gotFileWriter: function(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");
},
fail: function() {
alert("failed");
}
};
And here are the log entries from the logCat showing it firing off:
09-26 07:24:37.991 I/chromium( 2027): [INFO:CONSOLE(49)] "Received
Event: deviceready", source: file:///android_asset/www/js/index.js (49)
09-26 07:24:38.591 D/TEST ( 2027): cdvfile://localhost/persistent/testFile.txt: 16
09-26 07:24:39.063 I/chromium( 2027): [INFO:CONSOLE(62)] "contents of file now 'some sample text'", source: file:///android_asset/www/js/index.js (62)
09-26 07:24:39.075 D/TEST ( 2027): cdvfile://localhost/persistent/testFile.txt: 15
09-26 07:24:39.155 I/chromium( 2027): [INFO:CONSOLE(65)] "contents of file now 'some sample'", source: file:///android_asset/www/js/index.js (65)
09-26 07:24:39.363 I/chromium( 2027): [INFO:CONSOLE(69)] "contents of file now 'some different text'", source: file:///android_asset/www/js/index.js (69)
Any insight to why this maybe happening would be great.
Thanks!
Don't make it so complex dude , it's a code snipest to write data to file . data which stored in 'decdata' variable . Don't forget to change 'somefolder' for folder in root directory and 'datafilename' the file which data is stored.
Also you should add file plugin .
function start(){
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, writedata, fail);
}
var decdata;
function writedata(fileSystem) {
fileSystem.root.getDirectory("<<somefolder>>", { create: true }, gotDir);
}
function gotDir(dirEntry) {
dirEntry.getFile(<<datafilename>>, { create: true, exclusive: false }, gotFile);
}
function gotFile(fileEntry) {
fileEntry.createWriter(gotFileWriter, fail);
}
function gotFileWriter(writer) {
writer.onwriteend = function (evt) {
writer.truncate(1);
writer.onwriteend = function (evt) {
writer.seek(0);
writer.write(decdata);
writer.onwriteend = function (evt) {
}
};
};
writer.write("some sample text");
}
function fail(error) {
alert('error' + error.code);
}
Related
I have an issue with Odoo V12 Javascript Framework.
I don't know whather the javascript is loaded or there is another issue:
odoo.define('titi.Home',['web.core','web.Dialog','web.Class'], function(require) {
"use strict";
var core = require('web.core'),
Dialog = require('web.Dialog'),
Class = require('web.Class');
var TitiHouse = Dialog.extend({
template: 'titi.her_house_name',
events: {
'click a#titi_s_house_name a': '_onClick',
},
init: function(parent, params) {
var self = this;
var options = _.extend({
size: 'large',
buttons: [{
text: params.titi_s_house_name,
click: self._onClick,
classes: 'btn-secondary',
}],
}, params || {});
self._super(parent, options);
},
_onClick: function(event) {},
willStart: function() {
console.log('Will start .....');
},
start: function() {
console.log('Start !!!');
},
});
return TitiHouse;
});
When can I execute this javascript file in template?
Or how to execute that script in template?
There are a couple of things that could be contributing to the problem:
1 - You are not calling the super methods of the Dialog widget in willStart or start. Try making these:
...
willStart: function() {
console.log('Will start .....');
return this._super.apply(this, arguments);
},
start: function() {
console.log('Start !!!');
return this._super.apply(this, arguments);
},
...
2 - You are not extending the events, you are overridding them. You need to make your events param:
events: _.extend({}, Dialog.prototype.events, {
'click a#titi_s_house_name a': '_onClick',
}),
Try changing these and see if it helps.
We got file, it lies in cache, and i see it in Console
But when i tried to save it and send, i got this mistakes from cordova.js
Wrong type for parameter "newName" of Entry.copyTo: Expected String, but got Number.
Uncaught TypeError: Wrong type for parameter "newName" of Entry.copyTo: Expected String, but got Number.
Error in Success callbackId: File1917405046 : TypeError: Wrong type for parameter "newName" of Entry.copyTo: Expected String, but got Number.
ngCordova installed and injected
Cordova is updated
and i can't send my file, please help me
that's my code in controller
$scope.attachPhoto = function() {
$ionicActionSheet.show({
buttons: [
{ text: '<i class="icon ion-android-image"></i>Перейти в галерею' },
{ text: '<i class="icon ion-android-camera"></i> Сделать фото' }
],
cancelText: 'Cancel',
cancel: function() {
},
buttonClicked: function(index) {
var options = {
destinationType : Camera.DestinationType.FILE_URI,
sourceType : Camera.PictureSourceType.CAMERA,
allowEdit : false,
encodingType: Camera.EncodingType.JPEG,
popoverOptions: CameraPopoverOptions
};
$cordovaCamera.getPicture(options).then(function(imageData) {
onImageSuccess(imageData);
console.log(imageData);
function onImageSuccess(fileURI) {
createFileEntry(fileURI);
console.log(fileURI);
}
function createFileEntry(fileURI) {
window.resolveLocalFileSystemURL(fileURI, copyFile, fail);
console.log(fileURI);
}
function copyFile(fileEntry) {
fileEntry.file(function(file) {
var reader = new FileReader();
reader.onloadend = function(e) {
var imgBlob = new Blob([ this.result ], { type: "image/jpeg" } );
$scope.attach = true;
$scope.file = imgBlob;
};
reader.readAsArrayBuffer(file);
});
window.resolveLocalFileSystemURL(cordova.file.dataDirectory, function(fileSystem2) {
fileEntry.copyTo(
fileSystem2,
12345,
onCopySuccess,
fail
);
}, fail);
}
function onCopySuccess(entry) {
$scope.$apply(function () {
$scope.images.push(entry.nativeURL);
$scope.attach = true;
$scope.sendPhoto();
});
}
function fail(error) {
console.log("fail: " + error.code);
}
}, function(err) {
console.log(err);
});
console.log(options);
return true;
}
})
};
$scope.sendPhoto = function() {
var data = {
file: $scope.file
}
console.log(data);
var fd = new FormData(data);
xhr = new XMLHttpRequest();
xhr.open("POST", "http://eatmeet.ru/serv.php");
xhr.setRequestHeader('Content-Type', 'application/upload');
xhr.send(fd);
}
Try to parse a string as fileName, not a number. Please check the file documentation.
The correct syntax is:
fileEntry.copyTo(parent [DirectoryEntry], newName [DOMString], successCallback [Function], errorCallback [Function]);
window.resolveLocalFileSystemURL(cordova.file.dataDirectory, function(fileSystem2) {
fileEntry.copyTo(
fileSystem2,
"12345",
onCopySuccess,
fail
);
}, fail);
I´m trying to save a pdf (generated with jspdf) and then open, just 2 buttons, but nothing happens on device and on console no error is shown.
This is the code to save:
window.resolveLocalFileSystemURL(cordova.file.externalDataDirectory, function(dir) {
dir.getFile("cotizacion.pdf", {create: true, exclusive: false}, function (fileEntry) {
fileEntry.createWriter(function (writer) {
writer.onwrite = function(evt) {
console.log("Escritura exitosa");
};
console.log("Escribiendo...");
writer.write(window.cotizacion);
})
},function () {
console.log("Error al guardar");
});
});
And this is to open:
window.resolveLocalFileSystemURL(cordova.file.externalDataDirectory, function(dir) {
dir.getFile(filename, {create:false}, function(fileEntry) { //EXISTS
var url = "file:/" + cordova.file.externalDataDirectory + "/cotizacion.pdf";
window.open(url, '_system');
}, function() {
//NOT EXISTS
alert('Hubo un problema al recuperar la cotización');
});
});
What can I do to make it work?
Thank you all.
PS: I have all the plugins File, FileTransfer, InAppBrowser
Firstly why in gods name is there no tutorial for this even Cordova's guides don't tell you how to save a flaming file to a location on the phone.
(function(w){
function FileServices(FileName, callb){
var self = this;
var isFileOpen = false;
var fileHandler;
// open file handle
function OpenFile(callb){
window.requestFileSystem(LocalFileSystem.PERSISTENT, 5*1024, function (fs) {
fs.root.getFile(cordova.file.externalDataDirectory+FileName, { create: true, exclusive: false }, function (fileEntry) {
fileHandler = fileEntry;
isFileOpen = true;
callb(self, fileHandler);
});
}, function(e,c){console.log(e,c);});
}
// write to file
function WriteFile(fileEntry, dataObj, isAppend, callback) {
// Create a FileWriter object for our FileEntry (log.txt).
fileEntry.createWriter(function (fileWriter) {
fileWriter.onerror = function (e) {
};
// If we are appending data to file, go to the end of the file.
if (isAppend) {
try {
fileWriter.seek(fileWriter.length);
}
catch (e) { }
}
fileWriter.write(dataObj);
callback(self, fileWriter);
});
}
this.writeLine = function(txt, append, callback){
if(isFileOpen){
WriteFile(fileHandler, new Blob([txt], { data:'plain/text' }), append, callback);
}
}
OpenFile(callb);
};
// add to the navigator when device ready
document.addEventListener("deviceready", function(){
navigator.FileServices = function GetFileServices(FileName, callback){
return new FileServices(FileName, callback);
}
});
})(window);
All i get is "Error Code 5 = FileError.ENCODING_ERR";
I can't work it out....
I created an Asp.Net MVC and used nuget to add HotTowel (V2.0.1 of 9/11/2013). I created a couple of ViewModel, Models. However, I got the following error.
"Failed to load routed module (viewmodels/myVM). Details: Load timeout for modules: durandal/plugins/router\nhttp://requirejs.org/docs/errors.html#timeout"
Is it the problem of durandal/plugins/router? Or it can be caused by some code I added?
The error occurred at Scripts/durandal/system.js.
var logError = function(error) {
if(error instanceof Error){
throw error;
}
throw new Error(error);
};
The following is the VM code.
define(['services/datacontext', 'durandal/plugins/router', 'services/logger'],
// Remove the durandal/plugins/router and the functions will get rid of the error.
function (datacontext, router, logger) {
var title = 'Event';
var vm = {
activate: activate,
deactivate: deactivate,
refresh: refresh,
events: events,
title: title
};
return vm;
//#region Internal Methods
var events = ko.observableArray();
function activate() {
logger.log(title + ' View Activated', null, title, true);
return datacontext.getEventPartials(events);
}
var deactivate = function () {
events([]);
};
var refresh = function () {
return datacontext.getEventPartials(events, true);
};
//#endregion
});
The following is the call stack
logError [system.js] Line 92 Script
Anonymous function [router.js] Line 359 Script
[External Code]
Anonymous function [system.js] Line 260 Script
[External Code]
[Async Call]
....
Code at router.js,
isProcessing(true);
router.activeInstruction(instruction);
if (canReuseCurrentActivation(instruction)) {
ensureActivation(activator.create(), currentActivation, instruction);
} else {
system.acquire(instruction.config.moduleId).then(function(module) {
var instance = system.resolveObject(module);
ensureActivation(activeItem, instance, instruction);
}).fail(function(err){
system.error('Failed to load routed module (' + instruction.config.moduleId + '). Details: ' + err.message);
});
}
}
And previous one in system.js.
acquire: function() {
var modules,
first = arguments[0],
arrayRequest = false;
if(system.isArray(first)){
modules = first;
arrayRequest = true;
}else{
modules = slice.call(arguments, 0);
}
return this.defer(function(dfd) {
require(modules, function() {
var args = arguments;
setTimeout(function() {
if(args.length > 1 || arrayRequest){
dfd.resolve(slice.call(args, 0));
}else{
dfd.resolve(args[0]);
}
}, 1);
}, function(err){
dfd.reject(err);
});
}).promise();
},
Based on the comments I'd recommend to modify the vm code slightly, so that all variables that are returned via vm are defined before use. In addition 'plugins/router' is used instead of 'durandal/plugins/router'.
define(['services/datacontext', 'plugins/router', 'services/logger'],
// Remove the durandal/plugins/router and the functions will get rid of the error.
function (datacontext, router, logger) {
var title = 'Event';
var events = ko.observableArray();
var deactivate = function () {
events([]);
};
var refresh = function () {
return datacontext.getEventPartials(events, true);
};
var vm = {
activate: activate,
deactivate: deactivate,
refresh: refresh,
events: events,
title: title
};
return vm;
//#region Internal Methods
function activate() {
logger.log(title + ' View Activated', null, title, true);
return datacontext.getEventPartials(events);
}
//#endregion
});
BTW the name Internals methods is misleading as everything in that region is returned via vm. I prefer to work with named function instead, which get created before the return statement if they are returned and place them below the return statement in a Internal methods region if they are not returned.
define(['services/datacontext', 'plugins/router', 'services/logger'],
function( datacontext, router, logger ) {
var title = 'Event';
var events = ko.observableArray();
function deactivate () {
events([]);
}
function refresh () {
return datacontext.getEventPartials(events, true);
}
function activate () {
logger.log(title + ' View Activated', null, title, true);
return datacontext.getEventPartials(events);
}
return {
activate: activate,
deactivate: deactivate,
refresh: refresh,
events: events,
title: title
};
//#region Internal Methods
//#endregion
});