We are working on an iOS project in Ionic. We want the cordova screenshot plugin to fire on ionicview enter (when first entering the app), and then use cordova file transfer to send the screenshot.
The below code does not work when first time entering the view. When we leave the view and come back however, it does send a screenshot.
However, the first logAction DOES fire on the first time entering this view while the second logAction does not. When entering this view for the second time, both logActions are fired.
This is the part of the code i am referring to:
$scope.$on('$ionicView.enter', function () {
$scope.logAction({
"Message": "Login screen succesfully entered",
"Succeeded": true,
"transaction": 1,
"Category": "Info",
"Device": 0,
})
$cordovaScreenshot.capture().then(function(filepath){
$scope.logAction({
"Message": filepath,
"Succeeded": true,
"transaction": 1,
"Category": "Info",
"Device": 0,
})
$cordovaScreenshot.send(filepath);
});
});
This is the cordovaScreenshot file
angular.module('testScreenshots.services', [])
.service('$cordovaScreenshot', ['$q',function ($q) {
return {
fileURL: "",
capture: function (filename, extension, quality) {
var randomNumber = Math.random();
console.log("" + randomNumber);
filename = "testPicture" + randomNumber.toString();
extension = extension || 'jpg';
quality = quality || '100';
var defer = $q.defer();
navigator.screenshot.save(function (error, res){
if (error) {
console.error(error);
defer.reject(error);
} else {
console.log('screenshot saved in: ', res.filePath);
this.fileURL = "file://" + res.filePath;
defer.resolve(res.filePath);
console.log("inside the save function: "+this.fileURL);
}
}, extension, quality, filename);
return defer.promise;
},
send: function(filepath){
var win = function (r) {
console.log("Code = " + r.responseCode);
console.log("Response = " + r.response);
console.log("Sent = " + r.bytesSent);
}
var fail = function (error) {
alert("An error has occurred: Code = " + error.code);
console.log("upload error source " + error.source);
console.log("upload error target " + error.target);
}
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = filepath.substr(filepath.lastIndexOf('/') + 1);
options.mimeType = "multipart/form-data";
options.chunkedMode = false;
options.headers = {
Connection: "close"
};
var ft = new FileTransfer();
ft.upload(filepath, encodeURI("http://192.168.6.165:8080//api/uploadpicture"), win, fail, options);
}
};
}])
The iOS simulator we use on the Mac had this issue. After trying to run it on a device the issue no longer affected us.
This issue thus seems to relate to using the iOS simulator.
Related
The idea of what I'm currently doing is that you can take a photo or select one from the gallery and upload it to a server. I was having trouble with using the cordova FileTransfer to send and upload the image. It was either not sending at all or $_FILES["file"] would be empty.
I have separate buttons to bring up the camera and gallery:
<button id="takePicture" name="takePicture" ng-click="openCamera();">Take Photo</button>
<button id="getPicture" name="getPicture" ng-click="openGallery();">Choose From Gallery</button>
Solution:
$scope.openCamera = function()
{
navigator.camera.getPicture(onSuccess, onError,
{ quality : 100,
destinationType : Camera.DestinationType.FILE_URI
});
function onSuccess(imageURI)
{
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = imageURI.substr(imageURI.lastIndexOf("/")+1);
options.mimeType = "image/jpeg";
options.httpMethod = "POST";
options.chunkedMode = false;
options.params = { filePath : imageURI.split("?")[0] };
var fileTransfer = new FileTransfer;
fileTransfer.upload(imageURI, encodeURI("upload.php"), uploadComplete, uploadError, options);
function uploadComplete(result)
{
console.log("Code = " + result.responseCode);
console.log("Response = " + result.response);
console.log("Sent = " + result.bytesSent);
}
function uploadError(error)
{
alert("An error has occurred: Code = " + error.code);
console.log("upload error source " + error.source);
console.log("upload error target " + error.target);
}
}
function onError(message)
{
alert("fail");
alert('Failed because: ' + message);
}
}
The data sent will then be received on the upload.php file. You should be able to check if the data has been sent by inspecting the files var_dump($_FILES);
As Sletheren mentioned it can also be done using $cordovaFileTransfer.upload();
This is how it works on my side:
First thing: The destinationType should be Camera.DestinationType.FILE_URI,
Second: Set the filename to: filename = imageURI.split('?')[0];
Third: the fileTransfer takes these arguments (it works on my side) :
$cordovaFileTransfer.upload(url, filename, options)
I have a view button and on click I am calling Web API to download the word document file.
WebAPI is working fine, when I paste the download URL in browser (for example http://localhost:50963/api/Download/1022), browser is showing a pop-up to save/cancel.
I wanted to have the same behavior, i.e. when user click on View button, I need to show above download pop-up. API is getting called successfully, see below screenshot
download.service.ts
export class DownloadService {
constructor(private http: Http) {}
private downloadUrl = 'http://localhost:50963/api/Download/';
//Fetch all existing Templates
DownloadDocument(Doc_Id: number){
return this.http.get(this.downloadUrl + Doc_Id.toString())
}
}
document-list.component.ts
DownloadArticle(Doc: ArticleModel){
console.log("inside downloadarticle()",Doc.Doc_Id);
this.downloadservice.DownloadDocument(Doc.Doc_Id)
.subscribe(
err => {
console.log(err);
});
}
You need to do some workaround here. Angular 'http' service cannot give what you want. I pasted all my workable code here. You need to pick the part of your need.
retrieveJquery(fileId: number, fileName: string): void {
let that = this;
let useBase64 = false;
let iOS = false;
if (navigator.platform)
iOS = /iPad|iPhone|iPod/.test(navigator.platform);
else if (navigator.userAgent)
iOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
let android = false;
if (navigator.platform)
android = /android/.test(navigator.platform);
else if (navigator.userAgent)
android = /android/.test(navigator.userAgent);
//useBase64 = iOS;
if (iOS || android) {
window.open('cloud/api/file/retrieve?fileId=' + fileId + '&base64=-1&_access_token=' + this.utilsSvc.getToken(), '_blank');
}
else {
$.ajax({
type: "GET",
headers: { 'Authorization': this.utilsSvc.getToken() },
url: 'cloud/api/file/retrieve',
data: {
'fileId': fileId,
'base64': useBase64 ? '1' : '0'
}
,
xhrFields: {
responseType: 'blob'
}
}).fail(function (jqXHR, textStatus) {
if (jqXHR.status === 501)
alert('Please configure service url first.');
else if (jqXHR.status === 404)
alert('File not found');
else
alert('Retrieving file failed: ' + textStatus + " : " + jqXHR.responseText);
}).done(function (data) {
if (useBase64)
window.open('data:' + that.utilsSvc.getMimeType(fileName) + ';base64, ' + data, '_blank');
else {
let blob = new Blob([data]);
if (window.navigator && window.navigator.msSaveOrOpenBlob)
window.navigator.msSaveOrOpenBlob(blob, fileName);
else {
let link = document.createElement('a');
link.target = '_blank';
link.href = window.URL.createObjectURL(blob);
link.setAttribute("download", fileName);
link.click();
}
}
});
}
}
There is a mobile app in which i want to delete the cached images downloaded by a particular user after log out.Suppose user1 logged in and download few images and user2 logged in and downloaded few images.User2 should not see downloaded images of any other user.
downloadFile : function(downloadLink, downloadFileName, downloadFileMimeType) {
$ionicLoading.show({
template: '<ion-spinner></ion-spinner>'
});
var accessToken = $window.localStorage.getItem(SYSTEM.AUTH_TOKEN);
var options = {
headers : {
'Authorization' : 'Bearer ' + accessToken
}
};
var ext;
if (downloadFileMimeType == 'application/pdf') {
ext = '.pdf';
} else {
ext = '.jpg';
}
var localPath;
if(ionic.Platform.isAndroid()){
localPath = cordova.file.externalCacheDirectory;
}else{
localPath = cordova.file.cacheDirectory;
}
localPath = localPath + downloadFileName.trim().replace(/\s+/g, '-') + ext;
var ft = new FileTransfer();
ft.download(downloadLink, localPath, function(entry) {
$ionicLoading.hide();
console.log("Downloading report on path - " + entry.toURL());
cordova.plugins.fileOpener2.open(entry.toURL(), downloadFileMimeType, {
error : function(e) {
console.log('Error status: ' + e.status + ' - Error message: ' + e.message);
},
success : function(fileEntry) {
console.log('File opened successfully');
}
});
}, function fail(error) {
$ionicLoading.hide();
console.log("Error while downloading report with error code - " + error.code);
}, true, options);
}
You can store files downloaded by specific user under a user specific folder in device and delete the same when the other user logs in. Else you can follow some file naming convention specific to the users while storing the files in folder and delete those files specific to particular user when the other user logs in. The sample snippet for directory deletion and its contents using cordova file plugin is as follows:
function clearDirectory() {
if (ionic.Platform.isAndroid()) {
window.resolveLocalFileSystemURL(cordova.file.externalRootDirectory, onFileSystemDirSuccess, fail);
} else {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, onFileSystemDirSuccess, fail);
}
function onFileSystemDirSuccess(fileSystem) {
var entry = "";
if (ionic.Platform.isAndroid()) {
entry = fileSystem;
} else {
entry = fileSystem.root;
}
entry.getDirectory("DIRECTORY_TO_DELETE", {
create: true,
exclusive: false
},
function(entry) {
entry.removeRecursively(function() {
console.log("Remove Recursively Succeeded");
}, fail);
}, getDirFail);
}
function getDirFail(error) {
navigator.notification.alert("Error");
};
function fail(error) {
navigator.notification.alert("Error");
};
}
I am developing an application for a radio station, have a section to download your audio programs. Works perfectly on Android and iOS, but Windows Phone starts downloading (very very slow) and after a time the application breaks showing this error message
An exception of type 'System.Runtime.InteropServices.SEHException' occurred in Unknown Module. and wasn't handled before a managed/native boundary
Also during the short time that is downloading shows this message
DispatchFileTransferProgress : FileTransfer1024600849
The size of the files you download is between 15 and 20 mb.
Anyone know what happens? Thanks in advance
Edited for add code
Code:
window.requestFileSystem(
LocalFileSystem.PERSISTENT,
0,
function onRequestFileSystemSuccess(fileSystem) {
fileSystem.root.getDirectory(
'Radio', //Directorory was created when apps starts firs time
{ create: true, exclusive: false },
function(directoryEntry) {
directoryEntry.getFile(
'dummy.html',
{ create: true, exclusive: false },
function onGetFileSuccess(fileEntry) {
var path = fileEntry.toURL().replace('dummy.html', '');
var fileTransfer = new FileTransfer();
fileEntry.remove();
var url = record.get('file');
var file = record.get('file').split('/');
fileTransfer.onprogress = function(progressEvent) {
if (progressEvent.lengthComputable) {
console.log('Downloaded: ' + ((progressEvent.loaded / progressEvent.total) * 100));
}
};
fileTransfer.download(
url,
path + file[file.length - 1],
function(file) {
console.log('Downloaded!');
},
function(error) {
console.log("download error source " + error.source);
console.log("download error target " + error.target);
console.log("upload error code" + error.code);
}
);
},
function fail(error) {
console.log('Get file ' + error.code);
}
);
},
function fail(error) {
console.log('Get directory ' + error.code);
}
);
},
function fail(error) {
console.log('Get file system ' + error.code);
}
);
Miguel
I'm currently starting work for my bachelor thesis and recently started 'digging' into the use of node.js and webSocket. My webSocket server runs without problems when accessed in Firefox 15.0 and Chrome 21.0.1180.89 m. In Opera 12.02, there seems to be a problem with the client-server handshake. This is what Opera's error console says:
[31.08.2012 01:03:51] WebSockets - http://10.0.0.2/
Connection
WebSocket handshake failure, invalid response code '400'.
Funny thgough: I can't find this error anywhere in the Dragonfly console's network log. All the fields that are requested when accessing the website (index.html, client.js etc.) are found and served as they should be (HTTP Status code 200 OK). Also, the only status codes that my server returns are 200, 404 and 500, so this looks like it's coming from within webSocket itself.
And yes, webSocket IS enabled in Opera...I have no idea what the problem could be
Any help would be really appreciated :)
EDIT:
This is my code so far so you can see which headers my server sends and how I create webSocket connections with my client.js:
server.js:
// load required modules:
var http = require("http");
var WebSocketServer = require("websocket").server;
path = require("path");
url = require("url");
filesys = require("fs");
// declare listening port vars:
var httpListeningPort = 80;
var webSocketListeningPort = 80;
// create HTTP-server:
var httpSrv = http.createServer(function(request, response) {
console.log((new Date()) + ":\tReceived request for " + request.url);
// response.writeHead(200);
// response.end();
var myPath = url.parse(request.url).pathname;
var fullPath = path.join(process.cwd(), myPath);
if(myPath === "/") {
fullPath += "index.html";
console.log("Full path:\t" + fullPath);
filesys.readFile(fullPath, "binary", function(err, file) {
if(err) {
response.writeHeader(500, {"Content-Type": "text/plain"});
response.write(err + "\n");
response.end();
}
else {
response.writeHeader(200);
response.write(file, "binary");
response.end();
}
});
}
else {
path.exists(fullPath, function(exists) {
if(!exists) {
response.writeHeader(404, {"Content-Type": "text/plain"});
response.write("404 Not Found\n");
response.end();
}
else {
filesys.readFile(fullPath, "binary", function(err, file) {
if(err) {
response.writeHeader(500, {"Content-Type": "text/plain"});
response.write(err + "\n");
response.end();
}
else {
response.writeHeader(200);
response.write(file, "binary");
response.end();
}
});
}
});
}
});
httpSrv.listen(httpListeningPort, function() {
console.log((new Date()) + ":\tServer is now listening on port " + httpListeningPort);
});
// create webSocket server and tie it to the http server:
wsServer = new WebSocketServer({
httpServer: httpSrv
});
function originChecker(origin) {
if(origin) {
console.log("Origin " + origin + " is allowed");
return true;
} else {
console.log("origin is NOT allowed.");
return false;
}
}
// how to handle requests:
wsServer.on("request", function(request) {
// check whether origin is allowed or not:
if(originChecker(request.origin) === false) {
request.reject();
console.log((new Date()) + ":\tConnection request from origin " + request.origin + " rejected.");
return;
}
// accept the connecteion request -> open the connection:
var connection = request.accept(null, request.origin);
console.log((new Date()) + ":\tConnection request from " + request.origin + " accepted.");
// handle incoming messages from the clients:
connection.on("message", function(message) {
if(message.type === "utf8") {
console.log((new Date()) + ":\tReceived message from " + request.origin + ":\nType: " + message.type + "\nLength: " + message.utf8Data.length + "\nMessage: " + message.utf8Data);
// echo "Message received":
connection.sendUTF(JSON.stringify( { type: "message", data: "Message received !" } ));
} else {
// send error message back to client:
console.log((new Date()) + ":\tReceived message from " + request.origin + ":\nERROR:\tMessage is NOT UTF-8! it's " + message.type);
connection.sendUTF(JSON.stringify( { type: "message", data: "ONLY UTF-8 accepted !" } ));
}
});
// what to do when connection is closed:
connection.on("close", function() {
console.log((new Date()) + ":\tClient #" + connection.remoteAddress + " disconnected.");
});
});
client.js:
function client() {
if("WebSocket" in window) {
alert("WebSocket is supported by your browser!");
// try to connect to the webSocket server:
var connection = null;
connection = new WebSocket("ws://10.0.0.2:80");
// things to do once the connection is opened:
connection.onopen = function() {
alert("INFO:\tConnection to server is OPEN");
document.getElementById("msgInput").focus();
document.getElementById("msgInput").disabled = false;
document.getElementById("msgInput").value = "";
document.getElementById("msgInput").onkeyup = function(key) {
switch(key.keyCode) {
case 13: if(document.getElementById("msgInput").value === "") {
break;
}
var messageText = document.getElementById("msgInput").value;
document.getElementById("msgInput").disabled = true;
document.getElementById("msgInput").value = "";
document.getElementById("statusHeader").innerHTML = "Sending...";
connection.send(messageText);
break;
default: document.getElementById("statusHeader").innerHTML = "Press ENTER to send!";
}
};
};
connection.onerror = function(error) {
document.body.style.backgroundColor = "#220000";
document.body.style.color = "#aa0000";
document.getElementById("statusHeader").innerHTML = "ERROR connecting to server -> OFFLINE";
return;
};
connection.onmessage = function(message) {
try {
var json = JSON.parse(message.data);
} catch (error) {
alert("ERROR parsing message:\t" + error);
return;
}
document.getElementById("statusHeader").innerHTML = json.data;
document.getElementById("msgInput").disabled = false;
};
connection.onclose = function() {
setTimeout(function() {
document.body.style.backgroundColor = "#808080";
document.body.style.color = "#ffffff";
document.getElementById("statusHeader").innerHTML = "OFFLINE";
document.getElementById("msgInput").disabled = true;
document.getElementById("msgInput").value = "OFFLINE";
}, 5000);
return;
};
} else {
alert("WebSocket is NOT supported by your browser! Exiting now.");
return;
}
};
According to a recent question Opera 12 supports an older, incompatible version of websockets. This version (Hixie-76) uses a different set of headers in its handshake. Your server presumably doesn't understand these which explains its 400 error response.
If you can afford to wait for Opera to catch up, the easiest 'solution' is to use other browsers for your testing for now. The hixie protocol drafts are deprecated so Opera is bound to upgrade to RFC 6455 eventually.