Blackberry Webworks/Phonegap file browser - javascript

I'm moving from Air/Actionscript to WebWorks and having some difficulty. I've tried several Phonegap file browser tutorials and samples I've found around the web but they're not working on the Playbook. I've added the access_shared permission to the config. I have an and when my app is launched it's supposed to load the directories and files into the .
My js is below:
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady(){
window.requestFileSystem(
LocalFileSystem.PERSISTENT,
0, onFileSystemSuccess, fail
);
}
function onFileSystemSuccess(fileSystem) {
// Create some test files
fileSystem.root.getDirectory("myDirectory",
{ create: true, exclusive: false },
null,fail);
fileSystem.root.getFile("readthis.txt",
{ create: true, exclusive: false },
null,fail);
var directoryReader = fileSystem.root.createReader();
// Get a list of all the entries in the directory
directoryReader.readEntries(success,fail);
}
function success(entries) {
var i;
var objectType;
for (i=0; i<entries.length; i++) {
if(entries[i].isDirectory == true) {
objectType = 'Directory';
} else {
objectType = 'File';
}
$('#directoryList').append('<li><h3>' + entries[i].name + '</
h3><p>' + entries[i].toURI() + '</p><p class="ui-li-aside">Type:
<strong>' + objectType + '</strong></p></li>');
}
$('#directoryList').listview("refresh");
}
function fail(error) {
alert("Failed to list directory contents: " + error.code);
}

I found the DIR example in KitchenSink showed me what I needed to know.

Related

Cannot set dataTransfer object in Safari Browser [duplicate]

Is it possible to simulate/fake the drop event using javascript only? How to test this type of event?
Take for example this dnd upload sample page , is it possible to trigger the "drop" event with a file without actually dropping a file there? Let's say clicking on a button?
I have started writing a Sukuli script that can control the mouse and do the trick but I was looking for a better solution.
EDIT
#kol answer is a good way to get rid of the drag and drop event but I still have to manually select a file from my computer. This is the bit I am interested in simulating. Is there a way to create a file variable programatically?
var fileInput = document.getElementById('fileInput'),
file = fileInput.files[0];
1. Dropping image selected by the user
I've made a jsfiddle. It's a stripped-down version of the html5demos.com page you've referred to, but:
I added an <input type="file"> tag which can be used to select an image file from the local computer, and
I also added an <input type="button"> tag with an onclick handler, which simulates the "drop file" event by directly calling the ondrop event handler of the DND-target div tag.
The ondrop handler looks like this:
holder.ondrop = function (e) {
this.className = '';
e.preventDefault();
readfiles(e.dataTransfer.files);
}
That is, we have to pass an argument to ondrop, which
has a dataTransfer field with a files array subfield, which contains the selected File, and
has a preventDefault method (a function with no body will do).
So the onclick handler of the "Simulate drop" button is the following:
function simulateDrop() {
var fileInput = document.getElementById('fileInput'),
file = fileInput.files[0];
holder.ondrop({
dataTransfer: { files: [ file ] },
preventDefault: function () {}
});
}
Test
Select an image file (png, jpeg, or gif)
Click on the "Simulate drop" button
Result
2. Dropping autogenerated test files without user interaction (GOOGLE CHROME ONLY!!!)
I've made another jsfiddle. When the page is loaded, a function gets called, which:
creates a text file into the temporary file system, and
loads and drops this text file into the target <div>; then
creates an image file into the temporary file system, and
loads and drops this image file into the target <div>.
The code of this drop-simulator function call is the following:
(function () {
var fileErrorHandler = function (e) {
var msg = "";
switch (e.code) {
case FileError.QUOTA_EXCEEDED_ERR:
msg = "QUOTA_EXCEEDED_ERR";
break;
case FileError.NOT_FOUND_ERR:
msg = "NOT_FOUND_ERR";
break;
case FileError.SECURITY_ERR:
msg = "SECURITY_ERR";
break;
case FileError.INVALID_MODIFICATION_ERR:
msg = "INVALID_MODIFICATION_ERR";
break;
case FileError.INVALID_STATE_ERR:
msg = "INVALID_STATE_ERR";
break;
default:
msg = "Unknown Error";
break;
};
console.log("Error: " + msg);
},
requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem,
dropFile = function (file) {
holder.ondrop({
dataTransfer: { files: [ file ] },
preventDefault: function () {}
});
};
if (!requestFileSystem) {
console.log("FileSystem API is not supported");
return;
}
requestFileSystem(
window.TEMPORARY,
1024 * 1024,
function (fileSystem) {
var textFile = {
name: "test.txt",
content: "hello, world",
contentType: "text/plain"
},
imageFile = {
name: "test.png",
content: "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==",
contentType: "image/png",
contentBytes: function () {
var byteCharacters = atob(this.content),
byteArrays = [], offset, sliceSize = 512, slice, byteNumbers, i, byteArray;
for (offset = 0; offset < byteCharacters.length; offset += sliceSize) {
slice = byteCharacters.slice(offset, offset + sliceSize);
byteNumbers = new Array(slice.length);
for (i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
return byteArrays;
}
};
// Create and drop text file
fileSystem.root.getFile(
textFile.name,
{ create: true },
function (fileEntry) {
fileEntry.createWriter(
function (fileWriter) {
fileWriter.onwriteend = function(e) {
console.log("Write completed (" + textFile.name + ")");
fileSystem.root.getFile(
textFile.name,
{},
function (fileEntry) {
fileEntry.file(
function (file) {
dropFile(file);
},
fileErrorHandler
);
},
fileErrorHandler
);
};
fileWriter.onerror = function(e) {
console.log("Write failed (" + textFile.name + "): " + e.toString());
};
fileWriter.write(new Blob([ textFile.content ], { type: textFile.contentType }));
},
fileErrorHandler
);
},
fileErrorHandler
);
// Create and drop image file
fileSystem.root.getFile(
imageFile.name,
{ create: true },
function (fileEntry) {
fileEntry.createWriter(
function (fileWriter) {
fileWriter.onwriteend = function(e) {
console.log("Write completed (" + imageFile.name + ")");
fileSystem.root.getFile(
imageFile.name,
{},
function (fileEntry) {
fileEntry.file(
function (file) {
dropFile(file);
},
fileErrorHandler
);
},
fileErrorHandler
);
};
fileWriter.onerror = function(e) {
console.log("Write failed (" + imageFile.name + "): " + e.toString());
};
fileWriter.write(new Blob(imageFile.contentBytes(), { type: imageFile.contentType }));
},
fileErrorHandler
);
},
fileErrorHandler
);
},
fileErrorHandler
);
})();
The content of the auto-generated text file is given as a string, and the content of the image file is given as a base64-encoded string. These are easy to change. For example, the test text file can contain not just plain text, but HTML too. In this case, don't forget to change the textFile.contentType field from text/plain to text/html, and to add this content type to the acceptedTypes array and to the previewfile function. The test image can also be changed easily, you just need an image-to-base64 converter.
I had to extend the drop handler code to handle text files in addition to images:
acceptedTypes = {
'text/plain': true, // <-- I added this
'image/png': true,
'image/jpeg': true,
'image/gif': true
},
...
function previewfile(file) {
if (tests.filereader === true && acceptedTypes[file.type] === true) {
var reader = new FileReader();
if (file.type === 'text/plain') { // <-- I added this branch
reader.onload = function (event) {
var p = document.createElement("p");
p.innerText = event.target.result;
holder.appendChild(p);
}
reader.readAsText(file);
} else {
reader.onload = function (event) {
var image = new Image();
image.src = event.target.result;
image.width = 250; // a fake resize
holder.appendChild(image);
};
reader.readAsDataURL(file);
}
} else {
holder.innerHTML += '<p>Uploaded ' + file.name + ', ' + file.size + ' B, ' + file.type;
console.log(file);
}
}
Note that after loading the jsfiddle, the autogenerated files can be listed for debugging purposes:
Result
The screenshot shows that the simulated drop inserted the content of the autogenerated text file before the autogenerated image. The HTML code of the DND-target <div> looks like this:
<div id="holder" class="">
<p>hello, world</p>
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggkFBTzlUWEwwWTRPSHdBQUFBQkpSVTVFcmtKZ2dnPT0=" width="250">
</div>
#kol answer is a good way to get rid of the drag and drop event but I
still have to manually select a file from my computer. This is the bit
I am interested in simulating. Is there a way to create a file
variable programatically? -caiocpricci2
Try this
function createFile() {
var create = ["<!doctype html><div>file</div>"];
var blob = new Blob([create], {"type" : "text/html"});
return ( blob.size > 0 ? blob : "file creation error" )
};
createFile()

cordova download plugin showing package name on notification bar

I am new to cordova and plugins..
I have created a webappp, in my app i need to download files from server..
so i have used cordova background download plugin.. and i m using intel xdk.. so i have impoted plugin there..
cordova plugin github
now.. when i download file, on notification bar its showing downloading file.. BUT ITS SHOWING PLUGIN PACKAGE NAME WHILE DOWNLOADING.... but file save as its original name.... here it is my code..
var app = {
fileName: "tera hone.mp3",
uriString: "https://api.soundcloud.com/tracks/133667943/stream?client_id=67739332564a7130c3a05f90f2d02d2e", // 38.3 MB
// Application Constructor
initialize: function() {
this.bindEvents();
},
downloadFile: function(uriString, targetFile) {
var lblProgress = document.getElementById('lblProgress');
var complete = function() {
lblProgress.innerHTML = 'Done';
};
var error = function (err) {
console.log('Error: ' + err);
lblProgress.innerHTML = 'Error: ' + err;
};
var progress = function(progress) {
lblProgress.innerHTML = (100 * progress.bytesReceived / progress.totalBytesToReceive) + '%';
};
try{
var downloader = new BackgroundTransfer.BackgroundDownloader();
// Create a new download operation.
var download = downloader.createDownload(uriString, targetFile);
// Start the download and persist the promise to be able to cancel the download.
app.downloadPromise = download.startAsync().then(complete, error, progress);
} catch(err) {
console.log('Error: ' + err);
}
},
// 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);
document.getElementById('btnStart').addEventListener('click', this.startDownload);
document.getElementById('btnStop').addEventListener('click', this.stopDownload);
document.getElementById('btnFileInfo').addEventListener('click', this.getFileInfo);
},
// deviceready Event Handler
//
// The scope of 'this' is the event. In order to call the 'receivedEvent'
// function, we must explicity call 'app.receivedEvent(...);'
onDeviceReady: function() {
app.receivedEvent('deviceready');
app.startDownload();
},
startDownload: function () {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSystem) {
fileSystem.root.getFile(app.fileName, { create: true }, function (newFile) {
app.downloadFile(app.uriString, newFile);
});
});
},
stopDownload: function () {
app.downloadPromise && app.downloadPromise.cancel();
},
getFileInfo: function () {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fileSystem) {
fileSystem.root.getFile(app.fileName, { create: true }, function (fileEntry) {
fileEntry.file(function (meta) {
document.getElementById('lblFileInfo').innerHTML =
"Modified: " + meta.lastModifiedDate + "<br/>" +
"size: " + meta.size;
});
}, function(error) {
document.getElementById('lblFileInfo').innerHTML = "error: " + error;
});
});
},
// 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);
}
};
this is my javascript file invoke from my html file.. from cordova plugin..
also when i stop downloading.. it stops but app suddenly crashed everytime....
sorry for my bad english..

cordova push + angular - implement logic on when notification recieved

I am using cordova push notification plugin un my angular application. I have created this service for the notifications:
define(["app"], function (app) {
'use strict';
var pushNotificationService = function ($q, localStorageService) {
var registrationDefered;
function registrationSuccess(result) {
}
function registrationError(error) {
}
function test(notificationData) {
localStorageService.set('notification_url', notificationData.url);
}
function isOnBrowser() {
var result = document.URL.indexOf( 'http://' ) === -1 && document.URL.indexOf( 'https://' ) === -1;
return !result;
}
//Android Amazon callback
app.onNotificationGCM = function(e) {
console.log(e);
switch(e.event) {
case 'registered':
if (e.regid.length > 0) {
// Your GCM push server needs to know the regID before it can push to this device
// here is where you might want to send it the regID for later use.
var data = {
registrationID: e.regid,
device: device.platform.toLocaleLowerCase()
};
registrationDefered.resolve(data);
}
break;
case 'message':
test(e.payload);
// if this flag is set, this notification happened while we were in the foreground.
// you might want to play a sound to get the user's attention, throw up a dialog, etc.
if (e.foreground) {
console.log(e);
// on Android soundname is outside the payload.
// On Amazon FireOS all custom attributes are contained within payload
var soundfile = e.soundname || e.payload.sound;
// if the notification contains a soundname, play it.
var my_media = new Media("/android_asset/www/"+ soundfile);
my_media.play();
} else {
// otherwise we were launched because the user touched a notification in the notification tray.
if (e.coldstart) {
//$("#app-status-ul").append('<li>--COLDSTART NOTIFICATION--' + '</li>');
} else {
//$("#app-status-ul").append('<li>--BACKGROUND NOTIFICATION--' + '</li>');
}
}
break;
case 'error':
break;
default:
break;
}
};
//public
var serviceApi = {
register: function() {
var pushNotification = window.plugins.pushNotification;
registrationDefered = $q.defer();
debugger;
if(device.platform.toLocaleLowerCase() == 'android' || device.platform == "amazon-fireos") {
pushNotification.register(
registrationSuccess,
registrationError,
{
"senderID": "238062858076",
"ecb":"angular.module('App').onNotificationGCM"
}
);
} else if(isOnBrowser()) {
var data = {
registrationId: "",
device: "browser"
};
registrationDefered.resolve(data);
}
/* else if (device.platform == 'blackberry10'){
pushNotification.register(
registrationSuccess,
registrationError,
{
invokeTargetId : "replace_with_invoke_target_id",
appId: "replace_with_app_id",
ppgUrl:"replace_with_ppg_url", //remove for BES pushes
ecb: "pushNotificationHandler",
simChangeCallback: replace_with_simChange_callback,
pushTransportReadyCallback: replace_with_pushTransportReady_callback,
launchApplicationOnPush: true
});
} else {
pushNotification.register(
tokenHandler,
errorHandler,
{
"badge":"true",
"sound":"true",
"alert":"true",
"ecb":"onNotificationAPN"
});
}*/
return registrationDefered.promise;
}
};
//public
return {
register: serviceApi.register
}
};
return pushNotificationService;
});
Now, I am able to register (I am getting the registration ID) but when the device receives a notification it seems that the application not running the js logic written in the callback function under the message case: test(e.payload).
Note that I'm am receiving the notification butlocalStorageService.set('notification_url', notificationData.url); is never being set to the provided value.
Can you please help me to understand why it is not running? is it even suppose to run (if the application is not running - installed but not running)
The thing is that I made the registration only on login. Now I have added this line to my module run callback:
app.run(function() {
pushNotificationService.register().then(function(result) {
console.log(result); //this just for debugging
});
});

How to make an object global in Javascript?

I made a little phonegap/cordova application, and I need to access an object inside my .js file. Turns out I have no idea on how to change the structure of my code to make this happen.
Here is my index.html code :
<!DOCTYPE html>
<html>
<head>
<title>NFC tag ID reader</title>
<script type="text/javascript" src="js/index.js"></script>
<script type="text/javascript" charset="utf-8">
// Wait for device API libraries to load
document.addEventListener("deviceready", onDeviceReady, false);
// device APIs are available
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");
//MAKE THIS OBJECT GLOBAL ?
}
function fail(error) {
console.log(error.code);
}
</script>
</head>
<body>
<div class="app">
<script type="text/javascript">
app.initialize();
</script>
</body>
</html>
And here is my index.js code :
var app = {
/* Application constructor */
initialize: function() {
this.bindEvents();
console.log("Starting NFC Reader app");
},
/* bind any events that are required on startup to listeners: */
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
},
/* this runs when the device is ready for user interaction: */
onDeviceReady: function() {
nfc.addTagDiscoveredListener(
app.onNfc, // tag successfully scanned
function (status) { // listener successfully initialized
app.displayCpt("<b>"+cpt+"</b>" + ' personnes restantes.');
app.displayBjr("\n");
app.displayBjr("Identifiez-vous:");
},
function (error) { // listener fails to initialize
app.display("NFC reader failed to initialize " +
JSON.stringify(error));
}
);
},
/* displays tag ID from #nfcEvent in message div: */
onNfc: function(nfcEvent) {
var tag = nfcEvent.tag;
var nfcUid = nfc.bytesToHexString(tag.id);
var myDb = {
"04c85ccab52880": {
"name": "name",
"firstname": "fname",
"societe": "work"
}
var mapped = Object.keys(myDb).map(function(uid){
return (myDb[uid].uid = uid) && myDb[uid];
});
for(var i = 0; i < mapped.length ; i++){
if(mapped[i]['uid'] != nfcUid){
mapped[i]['uid'] += 1;
} else {
mapped[i]['uid'] = nfcUid;
app.display(mapped[i]['name'] + ' ' + mapped[i]['firstname'] + ', ' + mapped[i]['societe']);
writer.write(mapped[i]['name'] + ' ' + mapped[i]['firstname'] + ', ' + mapped[i]['societe']);
//I WOULD NEED THIS WRITER USABLE IN ORDER TO WRITE MY ARRAY CONTENT INTO A FILE
}
}
},
}; // end of app
I think my writer object needs to be global in order to make the mapped array write into a file, but I can't find a way to do that.. Any ideas ?
Thanks
Have you tried putting var writer outside of everything and removing it from the arguments list of gotFileWriter(writer)? That should make it a global variable. Note that this isn't exactly the best of programming practices, one should avoid global variables where possible.

Phonegap:Image Gallery loads very slowly

I am reading images from an sd card and displaying it in the gallery in my phonegap application.
I have two folders from which I am reading the contents. One is a synched folder and an unsynched folder.
The code is as follows:
listGalleryContents(synchedsdcardfolder, function() {
listGalleryContents(unsynchedsdcardfolder, function() {
showGalleryPage();
});
});
function listGalleryContents(directoryEntry, onComplete) {
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.indexOf(".") > 0 && entries[i].isFile) {
imagesArray.push(entries[i].fullPath);
}
}
onComplete();
} , function(error){
alert("Error: = " + error.code);
});
}
The problem comes when I have too many images to read from the sd card.
When i click on gallery view, it takes a lot of time to load the images.
Is there any way to make it more responsive and improve the performance please?
Javascript is single threaded and hence callbacks will fire in the same main thread which blocks the UI. Try changing your code to this:
listGalleryContents(synchedsdcardfolder, loadUnSyncedFolder);
function loadUnSynchedFolder() {
setTimeout(function() {
listGalleryContents(unsynchedsdcardfolder, allFoldersLoaded);
}, 0);
}
function allFoldersLoaded() {
setTimeout(showGalleryPage, 0);
}
function listGalleryContents(directoryEntry, onComplete) {
var successCallback = onComplete;
var directoryReader = directoryEntry.createReader();
directoryReader.readEntries(
function(entries) { readSuccess(entries, successCallback); } ,
function(error){
alert("Error: = " + error.code);
});
}
function readSuccess(entries, onComplete) { // success get files and folders
var i = 0, length = entries.length;
for(; i < length ; ++i) { // why are you using ++i and not i++ ??
if(entries[i].name.indexOf(".") > 0 && entries[i].isFile) {
imagesArray.push(entries[i].fullPath);
}
}
onComplete();
}
}
I have not tested this code. You may have to make minor modifications to it if you see errors.

Categories