Recentemente, tenho trabalhado no projeto phonegap/cordova. O principal objetivo do projeto era tirar fotos com a câmera do dispositivo e enviá-las para o servidor. É um projeto apache cordova usando o plugin camera. De acordo com a documentação, podemos enviar imagens com o seguinte código javascript:
navigator.camera.getPicture(onSuccess, onFail, {
quality: 100,
destinationType: Camera.DestinationType.DATA_URL
});
function onSuccess(imageData) {
// here we can upload imageData to the server
}
function onFail(message) {
alert('Failed because: ' + message);
}
Como podemos ver, nosso plugin devolve uma versão codificada em base64 de nossa imagem, e podemos enviá-la ao servidor utilizando o JQuery, por exemplo.
function onSuccess(imageData) {
$.post( "upload.php", {data: imageData}, function(data) {
alert("Image uploaded!");
});
}
O lado do servidor é trivial. Precisamos apenas ler a variável ‘data’ requisitada, realizar uma decodificação base64 e teremos a nossa imagem binária pronta para ser salva.
Testei com um smartphone Android antigo (com uma câmera não tão boa) e funciona, mas quando tentei usá-lo com um telefone Android melhor (com uma câmera de 8Mpx) ele ficou carregando e não funcionou. Depois de ler melhor a documentação, percebi que essa não é a melhor forma de enviar imagens para o servidor. Ela só funciona se a imagem é pequena. A base64 aumenta o tamanho da imagem e nosso dispositivo pode ter problemas para manipular a memória. Essa forma também é lenta como uma tartaruga.
A melhor maneira (aquela que funciona de fato) é, em vez de enviar imagens em base64 para o servidor, salvá-las dentro de uma pasta temporária no dispositivo e enviá-las usando o plugin de transferência de arquivos.
var pictureSource; // picture source
var destinationType; // sets the format of returned value
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
pictureSource = navigator.camera.PictureSourceType;
destinationType = navigator.camera.DestinationType;
}
function clearCache() {
navigator.camera.cleanup();
}
var retries = 0;
function onCapturePhoto(fileURI) {
var win = function (r) {
clearCache();
retries = 0;
alert('Done!');
}
var fail = function (error) {
if (retries == 0) {
retries ++
setTimeout(function() {
onCapturePhoto(fileURI)
}, 1000)
} else {
retries = 0;
clearCache();
alert('Ups. Something wrong happens!');
}
}
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = fileURI.substr(fileURI.lastIndexOf('/') + 1);
options.mimeType = "image/jpeg";
options.params = {}; // if we need to send parameters to the server request
var ft = new FileTransfer();
ft.upload(fileURI, encodeURI("http://host/upload"), win, fail, options);
}
function capturePhoto() {
navigator.camera.getPicture(onCapturePhoto, onFail, {
quality: 100,
destinationType: destinationType.FILE_URI
});
}
function onFail(message) {
alert('Failed because: ' + message);
}
Eu percebi que às vezes isso falhava. Parece ser um bug no plugin do cordova (não tenho certeza); por causa disso, se você ler o meu código, pode ver que se pf.upload falhar eu tento novamente (apenas uma vez). Com esse pequeno truque, funciona que é uma beleza (e ainda é rápido).
A parte do servidor é bastante simples. Precisamos apenas manipular os arquivos enviados. Aqui está um exemplo minimalista em PHP:
<?php move_uploaded_file($_FILES["file"]["tmp_name"], '/path/to/file');
E é só. Podemos fazer facilmente o upload de nossas fotos de nossos smartphones usando phonegap/cordova.
***
Artigo traduzido pela Redação iMasters, com autorização do autor. Publicado originalmente em http://gonzalo123.com/2013/10/28/taking-photos-with-a-phonegapcordova-application-and-uploading-them-to-the-server/




