I'm try to create a config file to keep some configurations of my app. I'm using SAPUI5 and cordova file.
The intention is create a conf.txt to keep the URL, PORT and LDAP data to access my system. However, these information can change, so I need to update the file.
In my app, I've made the function deviceready when the application starts, and created the conf.txt:
function onLoad() {
document.addEventListener("deviceready", onDeviceReady, false);
}
function onDeviceReady() {
/*jQuery.sap.require("model.Config");
var conf = new Configuration();
conf.init();*/
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail);
}
function gotFS(fileSystem) {
fileSystem.root.getFile("conf.txt", {create : true,exclusive : false},gotFileEntry, fail);
}
function gotFileEntry(fileEntry) {
//alert(fileEntry.fullPath);
fileEntry.createWriter(gotFileWriter, fail);
}
function gotFileWriter(writer) {
writer.onwriteend = function(evt) {
alert("OK");
};
var conf = "URL=\r\nPORT=80\r\nLDAP=false";
writer.seek(writer.length);
writer.write(conf);
}
function fail(error) {
alert(error.code);
}
I didn't do nothing different of other examples. But, as I've commented in onDeviceReady function, I tried to create a class to use to create the file, read and update it.
All examples that I found reference the deviceready event. Can I just use the methods of FileWriter and FileReader on this event?
It's my Configuration Class:
function Configuration() {
this.fileName = "conf.txt";
this.init = function() {**How to use the cordova API here**};
this.read = function(){**How to use the cordova API here**};
this.update= function(){**How to use the cordova API here**};
}
Thanks for help!
As suggested by Njtman, I got to save the informations in file without cordova file plugin just using localstorage.
I'd like to share the solution found.
index.html on deviceready event:
jQuery.sap.require("model.Config");
var conf = new Configuration();
sap.ui.getCore().setModel(conf, "Config");
conf.init();
Configuration class:
sap.ui.model.json.JSONModel.extend("Configuration", {
url: "",
port: "80",
defaultport: true,
ldap: false,
init : function() {
var deferred = $.Deferred();
console.log("INITIALIZING...");
var config = JSON.parse(window.localStorage.getItem("config"));
if(config == null){
console.log("CONFIG IS NULL");
window.localStorage.setItem("config", JSON.stringify(
{"URL": this.url, "PORT": this.port, "DEFAULTPORT": this.defaultport, "LDAP": this.ldap}
));
}
deferred.resolve();
this.setData(JSON.parse(window.localStorage.getItem("config")));
this.setVars();
console.log(this.getJSON());
return deferred.promise();
},
save: function(url, port, defaultport, ldap){
var deferred = $.Deferred();
console.log("SAVING...");
window.localStorage.setItem("config", JSON.stringify(
{"URL": url, "PORT": port, "DEFAULTPORT": defaultport, "LDAP": ldap}
));
deferred.resolve();
this.setData(JSON.parse(window.localStorage.getItem("config")));
this.setVars();
return deferred.promise();
},
setVars: function(){
this.url = this.getProperty("/URL");
this.port = this.getProperty("/PORT");
this.defaultport = this.getProperty("/DEFAULTPORT");
this.ldap = this.getProperty("/LDAP");
}
});
Now I can read and update my json file.
Related
I'm using Cordova media plugin for playing audio sound in my mobile application
I tried many codes but I didn't figure out what I'm doing wrong at the bottom I put two piece of code that I tried them
the first code (js code in a separate file)
var app = {
initialize: function() {
this.bindEvents();
},
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
},
onDeviceReady: function() {
var myMedia = new Media("../sounds/clapping.mp3");
myMedia.play();
}
};
app.initialize();
the second code (js code in a script tag) :
document.addEventListener("deviceready", function(){
var myMedia = null;
function playAudio() {
var src = "sounds/clapping.mp3";
if(myMedia === null) {
myMedia = new Media(src, onSuccess, onError);
function onSuccess() {
console.log("playAudio Success");
}
function onError(error) {
console.log("playAudio Error: " + error.code);
}
}
myMedia.play();
}
document.getElementById("playAudio").addEventListener("click", playAudio);
});
with a button :
<button id ="playAudio">PLAY</button>
How can I solve this problem ?
Wasted 2 hours on this, sharing it here:
This should not be this difficult. No full example at: https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-media/
Simple step by step details:
Put my file in www:
Example at: www/audio/button-1.mp3
Install plugin:
cordova plugin add cordova-plugin-media
Copy paste code below:
`
function getFullMediaURL(s) {
return cordova.file.applicationDirectory + 'www/audio/button-1.mp3'
}
function playMP3() {
let src = getFullMediaURL();
var myMedia =
new Media(src,
function () { },
function (e) { alert('Media Error: ' + JSON.stringify(e)); }
);
myMedia.play();
myMedia.setVolume('1.0');
}
`
Step 4: Call below where you need play sound:
playMP3();
To answer your question, you can find the working sample of cordova app using Media Plugin in the following github page.
As mentioned in the sample project's README, you gotta install cordova device plugin as well to check the device platform.
Also to clarify the doubt you mentioned in the comment, android_asset refers to the project's root folder.
I have downloaded a PDF file as Base64 String in my phone as described in this SO Thread but I am not getting how can I render it to actual PDF so that end user can see it? I have written following code to write on the file:
var tempResponse = null;
function downloadFileOK(response){
var invocationResult = response['invocationResult'];
tempResponse = invocationResult;
var size = parseInt(invocationResult["responseHeaders"]["Content-Length"]);
window.requestFileSystem(LocalFileSystem.PERSISTENT, size, onSuccessFileHandler, onErrorFileHandler);
}
//Success
function onSuccessFileHandler(fileSystem) {
alert("inside onSuccessFileHandler START");
fileSystem.root.getFile("test2.pdf", {create: true, exclusive: false}, fileWriter, fail);
alert("inside onSuccessHandler END");
}
// Failure
function onErrorFileHandler(error) {
alert("inside onErrorFileHandler");
}
function fileWriter(entry){
alert("inside fileWriter START");
entry.createWriter(function(writer){
writer.onwriteend = function(evt) {
console.log("done written pdf :: test1.pdf");
alert("Inside onwriteend : START");
};
var temp = atob(tempResponse["text"]);
alert(temp);
writer.write(temp);
},fail);
alert("inside fileWriter END");
}
function fail(error) {
alert("inside fail");
console.log(error.code);
}
Am I doing it wrong? How can I open the PDF from my app in iOS/Android OS using javascript/jquery/cordova ?
Once you have download the base64 encoded file, you should decode it and save it to the file system so that it can be viewed later. You should not save the base in it's base64 encoded form.
You can use the utility function below to accomplish that. BTW you should take a look a the previous answer on Download PDF file from through MobileFirst Adapter since I made an update to it, it wasn't encoding the PDF properly.
var AppUtils = (function(){
// get the application directory. in this case only checking for Android and iOS
function localFilePath(filename) {
if(device.platform.toLowerCase() === 'android') {
return cordova.file.externalDataDirectory + filename;
} else if(device.platform.toLowerCase() == 'ios') {
return cordova.file.dataDirectory + filename;
}
}
// FileWritter class
function FileWritter(filename) {
this.fileName = filename;
this.filePath = localFilePath(filename);
}
// decode base64 encoded data and save it to file
FileWritter.prototype.saveBase64ToBinary = function(data, ok, fail) {
var byteData = atob(data);
var byteArray = new Array(byteData.length);
for (var i = 0; i < byteData.length; i++) {
byteArray[i] = byteData.charCodeAt(i);
}
var binaryData = (new Uint8Array(byteArray)).buffer;
this.saveFile(binaryData, ok, fail);
}
// save file to storage using cordova
FileWritter.prototype.saveFile = function(data, ok, fail) {
this.fileData = data;
var path = this.filePath.substring(0, this.filePath.lastIndexOf('/'));
var that = this;
// Write file on local system
window.resolveLocalFileSystemURL(path, function(directoryEntry) {
var options = {create: true, exclusive: false};
directoryEntry.getFile(that.fileName, options, function(file) {
file.createWriter(function(writer) {
writer.onwriteend = function(event) {
if(typeof ok === 'function') {
ok(event);
}
};
writer.write(that.fileData);
}, fail);
}, fail);
}, fail);
};
// open InApp Browser to view file
function viewFile(filename) {
var path = localFilePath(filename);
window.open(path, "_blank", "location=yes,hidden=no,closebuttoncaption=Close");
}
return {
FileWritter: FileWritter,
localFilePath: localFilePath,
viewFile: viewFile
}
})();
Your downloadFileOK should look as follow:
function downloadFileOK(response){
var pdfData = response['invocationResult']['text'];
var fileWritter = new AppUtils.FileWritter('YOUR-PDF-NAME.pdf');
fileWritter.saveBase64ToBinary(pdfData, function(r){
// file was saved
}, function(e){
// error file was not saved
});
}
If you want to open the file then you can use AppUtils.viewFile('YOUR-FILE-NAME.pdf')
so I am trying to use the phonegap file API to save and later load a file in the app. The save seems to be working, but reading the file throws this error:
processMessage failed: Stack: TypeError: Object #<an Object> has no method 'readAsText'
at [object Object].readAsText (file:///android_asset/www/plugins/org.apache.cordova.file/www/FileReader.js:130:33)
at file:///android_asset/www/index.html:3843:15
at file:///android_asset/www/plugins/org.apache.cordova.file/www/DirectoryEntry.js:100:9
at Object.callbackFromNative (file:///android_asset/www/phonegap.js:292:54)
at processMessage (file:///android_asset/www/phonegap.js:1029:21)
at Function.processMessages (file:///android_asset/www/phonegap.js:1063:13)
at pollOnce (file:///android_asset/www/phonegap.js:933:17)
at pollOnceFromOnlineEvent (file:///android_asset/www/phonegap.js:928:5)
No matter what I do, it always seems to throw this error. I printed out the fileReader object to the console and inspected it using weinre. It had the prototype with the readAsText() function on it, so I'm really at a loss why it's not working...
This is how I am saving the file:
var request = window.requestFileSystem;
if(typeof request != 'undefined') {
var fileSystem;
var writer;
request(LocalFileSystem.PERSISTENT, 0, function (FS) {
fileSystem = FS;
fileSystem.root.getFile("offlineData.txt", {create: true, exclusive: false}, function(fileEntry) {
fileEntry.createWriter(function(w) {
writer = w;
writer.write('This is some text yo');
}, function(e) {console.log(e);});},
function(e) {console.log(e); console.log('There was an error getting the file to write')});} ,
function(e) {\console.log('There was an error getting the file system');});}
Later in the flow, I will do something like this:
request(LocalFileSystem.PERSISTENT, 0, function(FS) {
fileSystem = FS;
fileSystem.root.getFile("offlineData.txt", null, function(_file) {
var reader = new FileReader();
reader.onloadend = function (evt) {
console.log("read success");
console.log(evt.target.result);
};
reader.onerror = function(evt) {
console.log("Error read text");
console.log("Error"+evt.error.code);
};
reader.onabort = function(evt) {
console.log("aborted read text");
console.log(evt.target.result);
};
reader.onloadstart = function(evt) {
console.log("started reading");
};
console.log(reader);
reader.readAsText(_file);
});
}, function(e) {console.log(e); console.log('There was an error getting the file.')});
In your sample, _file is a fileEntry and not file content. Can you try this :
fileSystem.root.getFile("offlineData.txt", null,
function (fileEntry) {
fileEntry.file(function (_file) {
var reader = new FileReader();
reader.onloadend = function () {
console.log("read success");
console.log(evt.target.result);
};
reader.readAsText(_file);
});
}
);
I am working on a worklight application which needs file IO in it. I have written that code in an android project separately. Can anyone tell me how I can combine the both of them into one?
Like Idan said, there's no way to port your existing native application to a Worklight Hybrid Application. However, you can take advantage of the File API that works out of the box with Worklight Hybrid Applications in different environments, such as Android and iOS. If you create a Cordova Plugin you will need to create a plugin for all the environments you wish to support.
Here's a quick example of the File I/O API for Writing a file:
// Wait for Cordova to load
//
document.addEventListener("deviceready", onDeviceReady, false);
// Cordova is ready
//
function onDeviceReady() {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail);
}
function gotFS(fileSystem) {
fileSystem.root.getFile("readme.txt", {create: true, exclusive: false}, gotFileEntry, fail);
}
function gotFileEntry(fileEntry) {
fileEntry.createWriter(gotFileWriter, fail);
}
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 fail(error) {
console.log(error.code);
}
Here's an example of Reading a file:
// Wait for Cordova to load
//
function onLoad() {
document.addEventListener("deviceready", onDeviceReady, false);
}
// Cordova is ready
//
function onDeviceReady() {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail);
}
function gotFS(fileSystem) {
fileSystem.root.getFile("readme.txt", null, gotFileEntry, fail);
}
function gotFileEntry(fileEntry) {
fileEntry.file(gotFile, fail);
}
function gotFile(file){
readDataUrl(file);
readAsText(file);
}
function readDataUrl(file) {
var reader = new FileReader();
reader.onloadend = function(evt) {
console.log("Read as data URL");
console.log(evt.target.result);
};
reader.readAsDataURL(file);
}
function readAsText(file) {
var reader = new FileReader();
reader.onloadend = function(evt) {
console.log("Read as text");
console.log(evt.target.result);
};
reader.readAsText(file);
}
function fail(evt) {
console.log(evt.target.error.code);
}
There is no way to combine an existing Worklight Hybrid application with an existing Native application. The correct approach for a Worklight application would be to write a Cordova plug-in to do what you want on the native side of things.
Please see these training modules which explain how to do just that: http://www.ibm.com/developerworks/mobile/worklight/getting-started.html#cordova
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>