This is my first question on StackOverflow so please bear with my noobness.
I am writing a Cordova app with Ionic Framework and I am trying to upload multiple files from the camera to a server while displaying the uploaded files in a list and showing the progress for each of them. But I can't seem to figure out how to delete the files from the display list after a successful upload. I am trying to use the ID of the File I get after I push it to the array, but those seem to be incorrect sometimes. E.g. the ID in the progress event is different than in the success event and therefore I am removing the wrong file from the list or sometimes no file.
$scope.choosePic = function() {
window.imagePicker.getPictures(
function(results) {
for (var i = 0; i < results.length; i++) {
console.log('Image URI: ' + results[i]);
onSuccess(results[i]);
}
}, function (error) {
console.log('Error: ' + error);
}
);
}
$scope.delete = function ( item ) {
$scope.items.splice($scope.items.indexOf(item), 1);
}
var onSuccess = function(FILE_URI) {
console.log(FILE_URI);
$scope.picData = FILE_URI;
var filename = $scope.makeid();
var length = $scope.items.push({name: filename, image: $scope.picData, progress:0 });
$scope.$apply();
send($scope.picData,filename,length);
};
var onFail = function(e) {
console.log("On fail " + e);
}
send = function(imagedata,filename,length) {
var options = new FileUploadOptions();
var url = window.localStorage['URL'];
options.fileKey="file";
options.chunkedMode = false;
options.mimeType="image/jpeg";
options.headers = {Connection: "close"};
var params = {};
params.APIKEY = window.localStorage['APIKEY'];
params.DEVICEID = device.uuid;
options.params = params;
var ft = new FileTransfer();
var ID = length -1;
ft.onprogress = function(progressEvent) {
if (progressEvent.lengthComputable) {
var perc = Math.floor(progressEvent.loaded / progressEvent.total * 100);
if(!(typeof $scope.items[ID] == 'undefined')){
$scope.items[ID].progress=perc;
$scope.$apply();
console.log($scope.items[ID].name + "Upload progress: " + perc);
}
} else {
}
};
function onUploadSuccess(r) {
//alert("ID = " + ID + " Code = " + r.responseCode + "Response = " + r.response + "Sent = " + r.bytesSent);
//alert($scope.items[ID].name);
console.log("ID = " + ID + " Code = " + r.responseCode + "Response = " + r.response + "Sent = " + r.bytesSent);
$scope.items.splice(ID, 1); // remove uploaded image from list
$scope.$apply();
}
function onUploadFail(error) {
alert("An error has occurred: Code = " + error.code);
//console.log("upload error source " + error.source);
// console.log("upload error target " + error.target);
}
options.fileName=filename+".jpg";
ft.upload(imagedata, encodeURI(url), onUploadSuccess, onUploadFail, options);
}
});
I know this code probably rather clumsy but this the first time I am working with AngularJS and Cordova and the likes of it. Thanks for your help in advance.
Related
We are working on hydrid apps. Recently we got the requirement to support voice sms. We did R&D on that but we didn't have any luck. So we are trying to record 1 minute voice then we send it to a server. We don't know is it correct way. Please guide to us.
We tried like this https://www.npmjs.com/package/cordova-plugin-audio-recorder-api
var recorder = new Object;
function stop(){
recorder.stop = function() {
window.plugins.audioRecorderAPI.stop(function(msg) {
// success
alert('ok: ' + msg);
}, function(msg) {
// failed
alert('ko: ' + msg);
});
}}
function record{
recorder.record = function() {
window.plugins.audioRecorderAPI.record(function(msg) {
// complete
alert('ok: ' + msg);
}, function(msg) {
// failed
alert('ko: ' + msg);
}, 30); // record 30 seconds
}}
function playback(){
recorder.playback = function() {
window.plugins.audioRecorderAPI.playback(function(msg) {
// complete
alert('ok: ' + msg);
}, function(msg) {
// failed
alert('ko: ' + msg);
});
}}
We please guide to proper way to achieve our task.
I developing an Android application using Titanium Appcelerator. I had tried to Post text and Image via facebook feed dialog
.. But error while load my local image URL..
var fileimg = Titanium.Filesystem.getFile(backupDir.nativePath, "myimg.jpg");
var fb_data1 = {
description : "Some good text",
picture : fileimg.nativePath,
link : "www.googlee.com",
};
facebook_qfav.dialog("feed", fb_data1, showRequestResult);
function showRequestResult(e) {
var s = '';
if (e.success) {
s = "SUCCESS";
if (e.result) {
s += "; " + e.result;
}
if (e.data) {
s += "; " + e.data;
}
if (!e.result && !e.data) {
s = '"success",but no data from FB.I am guessing you cancelled the dialog.';
}
} else if (e.cancelled) {
s = "CANCELLED";
} else {
s = "FAILED ";
if (e.error) {
s += "; " + e.error;
alert("facebook Share " + s);
}
}
}
ERROR: "Image URL not properly formatted"
File path will be like this: file:///storage/sdcard0/myimg.jpg
But if i pass the remote URL to the picture property , the image is shown in the dialog...
what happens to the local URL..?
I think the only issue is that nativepath has capital P in it. so, its : nativePath
so instead of picture : fileimg.nativepath, It Should be picture : fileimg.nativePath,
Documentation.
Hope it helps.
I'm trying to send file from Android host to Samsung Gear device using Samsung Mobile SDK no matter how had I try, always get FILE_IO error.
I was trying all available permissions (on both sides).
Could anyone send me any hint?
Android side:
String filename = "file:///storage/emulated/0/Download/TestRecipe2-25.zip";
if (mGuruAgentService != null) mGuruAgentService.sendFile(filename);
public int sendFile(String fileName) {
if (mFileTransfer == null)
registerForFileTransfer();
if (mFileTransfer != null) {
try {
Log.i(TAG, "Sending file " + fileName);
tx = mFileTransfer.send(mPeerAgent, fileName);
return tx;
} catch (Exception e)
{
Log.i(TAG, "Cannot send file" + e.getMessage());
}
}
return 0;
}
Tizen side:
function fileReceiveInt() {
var newFilePath = "downloads/file.zip";
var receivefilecallback =
{
onreceive: function(transferId, fileName)
{
console.log("Incoming file transfer request form the remote peer agent. transferId: " + transferId + " file name : " + fileName);
try {
gFileTransfer.receiveFile(transferId, newFilePath);
} catch(e) {
console.log("Error Exception, error name : " + e.name + ", error message : " + e.message);
}
},
onprogress: function(transferId, progress)
{
console.log("onprogress transferId: " + transferId + ", progress : " + progress);
},
oncomplete: function(transferId, localPath)
{
console.log("File transfer complete. transferId: " + transferId);
},
onerror: function(errorCode, transferId)
{
console.log("FileReceiveError transferId: " + transferId + " code : " + errorCode);
}
}
try {
console.log('setting recieve interface');
gFileTransfer = SAAgent.getSAFileTransfer();
gFileTransfer.setFileReceiveListener(receivefilecallback);
} catch (err) {
console.log('getSAFileTransfer exception <' + err.name + '> : ' + err.message);
}
}
I will always get onError in tizen with FILE_IO error :(
I was testing gFileTransfer.receiveFile(transferId, ""); for default path, and File:///opt/usr/media/Downloads...
My tizen privileges:
<tizen:privilege name="http://tizen.org/privilege/content.read"/>
<tizen:privilege name="http://developer.samsung.com/privilege/accessoryprotocol"/>
<tizen:privilege name="http://tizen.org/privilege/content.write"/>
<tizen:privilege name="http://tizen.org/privilege/filesystem.read"/>
<tizen:privilege name="http://tizen.org/privilege/filesystem.write"/>
<tizen:privilege name="http://tizen.org/privilege/unlimitedstorage"/>
Thanks in advance for any help.
Change both filepaths and it should work.
Change Android's side to:
String filename = Environment.getExternalStorageDirectory() + "/Download/TestRecipe2-25.zip";
Change Tizen's side to:
var newFilePath = "file:///opt/usr/media/Downloads/file.zip";
I am at my whit's end.
I will try to keep it brief.
Using Cordova/Phonegap 3.0 (and get the same results on 2.8.0).
Android version 4.0.4.
Code works on BlackBerry10 (Q10 and Z10).
On Android it errors with a JSON Error (no, I'm not parsing JSON, this seems to come out of cordova's bowels). I will paste the JSON.stringified error object at the end of this.
So, on to code then:
First a filesystem success function:
function onFSSuccess(fileSystem) {
if (fileSystem == null) {
window.alert("fileSystem is null");
}
var root = fileSystem.root;
root.getDirectory("com.app.id",{create:true},gotDir,onError);};
Then a function to handle success with directory retrieval:
function gotDir(d){
DATADIR = d;
doTheDl (d.fullPath + "/update.sql",fileTransfer);
};
Then the actual call to get the filesystem:
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, onFSSuccess, null);
Then a function to download the file:
function doTheDl (localPath,fileTransfer) {
try {
window.alert ("Downloading to '" + localPath + "'");
fileTransfer.download (
uri,
localPath,
function (entry) {
try {
$("#dbDownloadProgressContainer").text("File saved to " + entry.name + ". Applying script to database...");
dbInitObj.applyUpdateScript(entry);
}
catch (e) {
window.alert ( e);
}
},
function (err) {
window.alert ("ERROROR!!! - " + err);
var errCodeName = err.code;
switch (err.code) {
case FileTransferError.FILE_NOT_FOUND_ERR:
errCodeName ='FILE_NOT_FOUND_ERR';
break;
case FileTransferError.INVALID_URL_ERR:
errCodeName="INVALID_URL_ERR";
break;
case FileTransferError.CONNECTION_ERR:
errCodeName="CONNECTION_ERR";
break;
case FileTransferError.ABORT_ERR:
errCodeName="ABORT_ERR";
break;
default:
errCodeName = "UNKNOWN";
break;
}
window.alert ("Download failed: " + err.source + ", " + err.target + ", " + errCodeName);
},
true
);
}
catch (e) {
window.alert ( e);
}
}
Man, gotta love all these async callbacks...
Next we get to the heart of the matter, trying to READ the downloaded file:
//Bulk of applyUpdateScript script ommited, but eventually it gets here:
function readComplete (evt) {
$("#dbDownloadProgressContainer").text("Parsing script file...");
//Got this gem from here: http://beckism.com/2010/09/splitting-lines-javascript/
var lines = evt.target.result.match(/^.*([\n\r]+|$)/gm);
//var lineIndx = lines.length;
window.setTimeout(function () {
$("#dbDownloadProgressContainer").text("Processing " + lines.length + " statements");
},50);
};
try {
var fileReader = new FileReader();
fileReader.onloadend=readComplete;
fileReader.onerror=function (err) {
//var errStr = translateFileError (err);
window.alert ("FileReader.onerror: " +JSON.stringify (err));
};
fileReader.onloadstart=function (evt) {
window.alert ("FileReader.onloadstart - " + JSON.stringify (evt));
};
fileReader.onload=function (evt)
{
window.alert ("FileReader.onload - Called when the read has successfully completed.- " + JSON.stringify (evt));
};
fileReader.onprogress = function (evt)
{
window.alert ("FileReader.onprogress - " + JSON.stringify (evt));
}
fileReader.onabort = function (evt)
{
window.alert ("FileReader.onabort - " + JSON.stringify (evt));
}
function gotFile (fileEntry) {
window.alert ("Activating reader for file '" + fileEntry.fullPath + "'");
fileReader.readAsText(fileEntry);
};
function noFileFound (fileError) {
alert ("Can not access database update script: code " + translateFileError (fileError));
};
// window.alert ("scriptPath.name = " + scriptPath.name);
DATADIR.getFile (scriptPath.name,null,gotFile,noFileFound);
}
catch (e) {
window.alert (e);
}
NOW, when I hit the reading bits, I eventually get this from the 'onerror' event (rember this is the JSON.stringfied error object:
{
"type":"error",
"bubbles":false,
"cancelBubble":false,
"cancelable":false,
"lengthComputable":false,
"loaded":0,
"total":0,
"target":{
"_readyState":2,
"_error":{
"code":"JSON error"
},
"_result":null,
"_fileName":"file:///mnt/sdcard/com.app.id/update.sql",
"_realReader":{
"error":null,
"result":"",
"readyState":0
}
}
}
Please also note that 'com.app.id' is a place holder for the actual app ID - can't paste that for fear of sensitive names. I did try other folder names as well.
Other notable(?) items:
The download progress event seems to indicate that we are downloading precisely double the actual file size (wtf?)
Results are the same on android device and emulator
BlackBerry10 seems to work fine
Thanks in advance to any clever people....
OK.
This was the solution:
function gotFile (fileEntry) {
fileEntry.file (function (file) {
fileReader.readAsText(file);
});
};
So thanks a BAJILLION to this dude:
http://www.html5rocks.com/en/tutorials/file/filesystem/?ModPagespeed=noscript
In case you missed it, the magic is the call to the "file(...)" function on the fileEntry object.
Why it works on the BB10 WITHOUT it....aarrgggghhh
I am using facebook plugin to login and logout a user, which are working fine. The problem is when I request for the logged in user details using the function FB.api('/me'), it always gives the following error:
{"message":"An active access token must be used to query information about the current user.","type":"OAuthException","code":2500}
I used the debug mode to check PluginResult(pr) and JSONObject of the response. JSONObject contains the user information, which I required, I dont get where I am doing wrong.
Plz help......
MY CODE:
function login() {
FB.login(function(response) {
if (response.session) {
console.log('Welcome! Fetching your information.... ');
FB.api('/me', function(response) {
console.log('Good to see you, ' + JSON.stringify(response) + '.');
});
} else {
console.log('User cancelled login or did not fully authorize.');
}
},{scope: 'email,user_likes'});
}
function logout() {
FB.logout(function(response) {
console.log(localStorage.getItem("user_fb_log_status"));
localStorage.setItem("user_fb_log_status","LOGGED_OUT");
alert('logged out');
});
}
The above code is working fine to login and logout the user. Below is the code i used to get the user details,
function me() {
FB.api('/me', { fields: 'id, name, picture' }, function(response) {
if (response.error) {
alert(JSON.stringify(response.error));
} else {
var data = document.getElementById('data');
fdata=response.data;
console.log("fdata: "+fdata);
response.data.forEach(function(item) {
var d = document.createElement('div');
d.innerHTML = "<img src="+item.picture+"/>"+item.name;
data.appendChild(d);
});
}
});
}
You need access token to retrieve more details than basic user information. Check that whether you have correct access token in Debug Tool to and ensure that you have all require permissions set permission.
Problem solved after changing the "session" in 'getResponse' method in ConnectPlugin to "authResponse"
FB.api method is working fine for me to get the user details and post a feed to the facebook after I change the following method in ConnectPlugin.java as following.
public JSONObject getResponse() {
String response = "{" + "\"status\": \""
+ (facebook.isSessionValid() ? "connected" : "unknown") + "\","
+
// "\"session\": {" + "\"access_token\": \""
// + facebook.getAccessToken() + "\"," + "\"expires\": \""
// + facebook.getAccessExpires() + "\","
// + "\"session_key\": true," + "\"sig\": \"...\","
// + "\"uid\": \"" + this.userId + "\"" +
"\"authResponse\": {" +
"\"accessToken\": \"" + facebook.getAccessToken() + "\"," +
"\"expiresIn\": \"" + facebook.getAccessExpires() + "\"," +
"\"session_key\": true," +
"\"sig\": \"...\"," +
"\"userId\": \"" + this.userId + "\"" +
"}" + "}";
try {
return new JSONObject(response);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return new JSONObject();
}