Now, I have a problem with uploading some images on the server. My code works perfectly on iOS devices, but when I'm trying to upload on Android, it just doesn't do anything. Before the filetransfer, I'm trying to alert the ImageURI, but it's not happening as well.
I'm using PhoneGap Build with Phonegap version 3.4.0 and Sencha Touch 2.3. In the config.xml I use the core phonegap camera plugin: <gap:plugin name="org.apache.cordova.camera" />.
My fileupload script looks like this:
Ext.define('my_app.controller.Fileupload', {
extend: 'Ext.app.Controller',
requires: [
'Ext.MessageBox'
],
config: {
refs: {
fileupload: '#fileupload',
getLibraryImage: 'button[action=getLibraryImage]',
getCameraImage: 'button[action=getCameraImage]'
},
control: {
getLibraryImage: {
tap: 'getLibraryImage'
},
getCameraImage: {
tap: 'getCameraImage'
}
}
},
getLibraryImage: function() {
navigator.camera.getPicture(this.fileupload, onFail, {
destinationType: Camera.DestinationType.FILE_URI,
sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
allowEdit: true,
targetWidth: 800,
targetHeight: 800
});
function onFail(message) {
alert('Failed because: ' + message);
}
},
getCameraImage: function() {
navigator.camera.getPicture(this.fileupload, onFail, {
destinationType: Camera.DestinationType.FILE_URI,
sourceType: Camera.PictureSourceType.CAMERA,
quality: 100,
allowEdit: true,
targetWidth: 800,
targetHeight: 800
});
function onFail(message) {
alert('Failed because: ' + message);
}
},
fileupload: function(imageURI) {
alert(imageURI);
Ext.Viewport.setMasked({
xtype: 'loadmask',
message: Loc.t('LOADMASK.FILEUPLOAD'),
styleHtmlContent: true,
indicator: true
});
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = imageURI.substr(imageURI.lastIndexOf('/') + 1);
options.mimeType = "image/jpeg";
// if (Ext.os.is('Android')) {
// options.chunkedMode = true;
// }
var user = JSON.parse(localStorage.getItem('user'));
var user_id = user.id;
var username = user.username;
var params = new Object();
params.user_id = user_id;
params.username = username;
options.params = params;
var ft = new FileTransfer();
ft.upload(imageURI, encodeURI("my_upload_uri"), win, fail, options);
function win(response) {
if (Ext.JSON.decode(response.response).error) {
Ext.Viewport.setMasked(false);
Ext.Msg.alert('my_app', Ext.JSON.decode(response.response).error);
} else {
my_app.app.getController('Basic').ProfileImages();
Ext.Msg.alert('my_app', Ext.JSON.decode(response.response).success);
}
}
function fail(error) {
Ext.Viewport.setMasked(false);
alert("An error has occurred: Code = " + error.code);
}
}
});
If anyone can see the problem, I'd really appreciate the help! Thanks in advance.
My problem solved by upgrading to PhoneGap version 3.6.3.
Related
I am relatively new to Ionic 2, Cordova & mobile. I followed a sample app to build a simple camera app. It is very similar to the code in a couple of other questions. Running on my android phone, the camera takes the picture but no image is displayed. The "takePicture fired" log entry displays but no further log entries. Is there something I am missing like a permission issue? Can't understand why I am not even seeing a log entry.
Relevant code:
mypage.html
<button ion-button block color="primary" (click)="takePicture()">Take Picture</button>
...
<img [src]="base64Image" *ngIf="base64Image" />
mypage.ts
export class MyPage {
public base64Image: string;
constructor(public navCtrl: NavController) {
}
takePicture() {
console.log("takePicture fired.");
Camera.getPicture({
destinationType: Camera.DestinationType.DATA_URL,
sourceType: Camera.PictureSourceType.CAMERA,
encodingType: Camera.EncodingType.JPEG,
targetWidth: 1000,
targetHeight: 1000
}).then((imageData) => {
// imageData is a base64 encoded string
this.base64Image = "data:image/jpeg;base64," + imageData;
if (this.base64Image) {
console.log("base64Image = " + this.base64Image);
}
else {
console.log("base64Image = NULL");
}
}, (err) => {
console.log("An error occurred.");
console.error(err);
});
});
Step 1: In your class.ts
import { Camera } from 'ionic-native';
Step 2: HTML
<img [src]="base64Image" *ngIf="base64Image" (click)="captureImage()"/>
Step 3:
captureImage(){
Camera.getPicture({
quality: 100,
saveToPhotoAlbum: true,
destinationType: Camera.DestinationType.FILE_URI,
sourceType: Camera.PictureSourceType.CAMERA,
allowEdit: true,
correctOrientation: false
})
.then((result) => {
this.base64Image = result;
console.log('Image URI: ' + this.base64Image);
}, (error) => {
console.log("ERROR -> " + JSON.stringify(error));
});
}
It's working fine...
Cheers!
I'm using the cordova camera plugin (I have fetched the latest version from their github) and it is working great on iOS, but it does nothing on Android (Emulator). I'm using Ionic 1. It does open the Camera and all these things, but after I press "Save", nothing else happens.
I know I can't use the camera, so I choose pictures form camera roll. But it seems the getPicture method is never called
Here is the code:
var index = btnIndex;
var source = -1;
if(index == 1){
//choose from album
if(ionic.Platform.isIOS()){
source = Camera.PictureSourceType.PHOTOLIBRARY;
}else{
source = Camera.PictureSourceType.SAVEDPHOTOALBUM;
}
}else if(index == 2){
//take new picture
source = Camera.PictureSourceType.CAMERA;
}
if(source > -1) {
var options = {
quality: 50,
destinationType: Camera.DestinationType.FILE_URI,
sourceType: source,
allowEdit: true,
encodingType: Camera.EncodingType.JPEG,
targetWidth: 320,
targetHeight: 320,
popoverOptions: CameraPopoverOptions,
saveToPhotoAlbum: false,
correctOrientation: true
};
$cordovaCamera.getPicture(options).then(function (imageURI) {
console.log("send file to server");
var imgTag = document.getElementById("myImage");
alert("imageURI: " + imageURI);
var url = SERVER.url + "upload.php";
var opt = new FileUploadOptions();
opt.fileName = $scope.currentUser.clientID + ".jpg";
$cordovaFileTransfer.upload(url, imageURI, opt)
.then(function(result) {
imgTag.src = $scope.currentUser.clientID + ".jpg?" + new Date().getTime(); //time is used to refresh the image
}, function(err) {
alert("Ein Fehler ist aufgetreten: " + JSON.stringify(err));
}, function (progress) {
console.log("progress: " + progress);
});
}), function(error){
alert("ERROR: " + JSON.stringify(error));
};
$cordovaCamera.cleanup();
}
It's an ionic app with $cordovaImagePicker and $cordovaCamera functions in the same controller and both called from the same reservation.html
This is the controller definition:
.controller('AppCtrl', ['$scope', '$timeout', '$ionicModal', '$localStorage', '$cordovaCamera', '$ionicPlatform', '$cordovaImagePicker', function($scope, $timeout, $ionicModal, $localStorage, $cordovaCamera, $ionicPlatform, $cordovaImagePicker){
I installed $cordovaImagePicker using ionic plugin add cordova-plugin-imagepicker and $cordovaCamera using ionic plugin add cordova-plugin-camera
This is the controller code:
$ionicPlatform.ready(function() {
var options1 = {
quality: 50,
destinationType: Camera.DestinationType.DATA_URL,
sourceType: Camera.PictureSourceType.CAMERA,
allowEdit: true,
encodingType: Camera.EncodingType.JPEG,
targetWidth: 100,
targetHeight: 100,
popoverOptions: CameraPopoverOptions,
saveToPhotoAlbum: false
};
$scope.takePicture = function() {
$cordovaCamera.getPicture(options1).then(function(imageData) {
$scope.registration.imgSrc = "data:image/jpeg;base64," + imageData;
}, function(err) {
console.log(err);
});
$scope.registerform.show();
};
var options2 = {
maximumImagesCount: 1,
width: 800,
height: 800,
quality: 80
};
$scope.getPicture = function() {
$cordovaImagePicker.getPictures(options2).then(function (results) {
for (var i = 0; i < results.length; i++) {
console.log('Image URI: ' + results[i]);
$scope.registration.imgSrc = results[i];
}
}, function(error) {
// error getting photos
console.log(error);
});
};
});
}])
I'm running the app on an android 5 phone.
The takePicture function works perfectly.
The getPicture function does not work.
The devTools console shows:
TypeError: Cannot read property 'getPictures' of undefined
at Object.getPictures (file:///android_asset/www/lib/ngCordova/dist/ng-cordova.js:4420:28)
at Scope.$scope.getPicture (file:///android_asset/www/js/controllers.js:132:37)
at fn (eval at <anonymous> (file:///android_asset/www/lib/ionic/js/ionic.bundle.js:26457:15), <anonymous>:4:221)
at file:///android_asset/www/lib/ionic/js/ionic.bundle.js:62386:9
at Scope.$eval (file:///android_asset/www/lib/ionic/js/ionic.bundle.js:29158:28)
at Scope.$apply (file:///android_asset/www/lib/ionic/js/ionic.bundle.js:29257:23)
at HTMLButtonElement.<anonymous> (file:///android_asset/www/lib/ionic/js/ionic.bundle.js:62385:13)
at HTMLButtonElement.eventHandler (file:///android_asset/www/lib/ionic/js/ionic.bundle.js:16583:21)
at triggerMouseEvent (file:///android_asset/www/lib/ionic/js/ionic.bundle.js:2948:7)
at tapClick (file:///android_asset/www/lib/ionic/js/ionic.bundle.js:2937:3)
The error seems to be saying that getPictures is in the scope of Scope.$scope.getPicture but that's not how the code is organised.
I've tried uninstalling and reinstalling $cordovaImagePicker but no change.
After hours of searching for an answer I found this link
https://github.com/ratkop/-cordova-imagePickerEx/issues/8
and reinstalled imagePicker with this :
ionic plugin add https://github.com/b-alidra/-cordova-imagePickerEx.git --save
and it now works without any errors.
I have an app to take photos and upload them when the user synchronises their app. However, it keeps giving me errors after I take the photo and doesnt save it at all to phone.
Here is my code:
(function () {
'use strict';
var serviceId = 'camera';
angular.module('app').service(serviceId, ['$cordovaCamera', '$cordovaFile', '$q', function ($cordovaCamera, $cordovaFile, $q) {
this.takePhoto = function () {
if (window.Camera) {
var options = {
quality: 75,
destinationType: Camera.DestinationType.FILE_URI,
sourceType: Camera.PictureSourceType.CAMERA,
allowEdit: false,
encodingType: Camera.EncodingType.JPEG,
targetWidth: 800,
targetHeight: 800,
saveToPhotoAlbum: true,
correctOrientation: true
};
return $cordovaCamera.getPicture(options).then(function (imageData) {
console.log("Photo Success: " + imageData);
return imageData;
}, function (err) {
console.error("Error taking photo: " + JSON.stringify(err));
throw err;
});
} else {
var deferred = $q.defer();
deferred.resolve("/img/sunrise.jpg");
return deferred.promise;
}
}
}]);
})();
What am I doing wrong here?
First make sure that you include the Camera and File plugins in your project.If not please add this two plugins,
cordova plugin add org.apache.cordova.camera
and
cordova plugin add org.apache.cordova.file
I have made small example for you.Here I am using Ionic’s ngCordova to implement the Camera functionality,.
Conroller
$scope.photoSave = function() {
if (window.cordova) {
var options = {
quality: 100,
destinationType: Camera.DestinationType.FILE_URI,
sourceType: Camera.PictureSourceType.CAMERA,
encodingType: Camera.EncodingType.JPEG,
cameraDirection: 1,
saveToPhotoAlbum: true
};
$cordovaCamera.getPicture(options).then(function(imagePath) {
$scope.imgURI = imagePath;
//Grab the file name of the photo in the temporary directory
var currentName = imagePath.replace(/^.*[\\\/]/, '');
//Create a new name for the photo
var d = new Date(),
n = d.getTime(),
newFileName = n + ".jpg";
//Move the file to permanent storage
$cordovaFile.moveFile(cordova.file.tempDirectory, currentName, cordova.file.dataDirectory, newFileName).then(function(success) {
//success.nativeURL will contain the path to the photo in permanent storage, do whatever you wish with it, e.g:
//createPhoto(success.nativeURL);
}, function(error) {
//an error occured
});
}, function(error) {
//An error occured
});
}
};
HTML
<ion-view>
<ion-content>
<button ng-click="photoSave()">Capture</button>
</ion-content>
</ion-view>
Refer
I have a service upload imageto amazon s3 after i sign it with my own backend using cordova file-transfer plugin.
I call this service after taking a picture using cordova camera plugin to upload the taken picture to the s3 bucket.
The app sign correctly with my own backend but when it trigger the function upload i get the error i defined in the title.
This is the service that it call an end point in my backend to sign the file and then upload the image to amazon s3:
//Image upload Service
.factory('S3Uploader', function($q, $window, $http, $ionicPopup, API_URL) {
var signingURI = API_URL + "s3signing";
function upload(imageURI, fileName) {
document.addEventListener('deviceready', function() {
console.log('Uploading ' + fileName + ' to S3');
var deferred = $q.defer(),
ft = new FileTransfer(),
options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = fileName;
options.mimeType = "image/jpeg";
options.chunkedMode = false;
console.log('Requesting signed doc ' + signingURI);
$http.post(signingURI, {
"fileName": fileName
})
.success(function(data) {
console.log('Got signed doc: ' + JSON.stringify(data));
options.params = {
"auth": true,
"key": fileName,
"AWSAccessKeyId": data.awsKey,
"acl": "public-read",
"policy": data.policy,
"signature": data.signature,
"Content-Type": "image/jpeg"
};
ft.upload(imageURI, "https://" + data.bucket + ".s3.amazonaws.com/",
function(e) {
console.log("Upload succeeded");
console.log(JSON.stringify(e));
deferred.resolve(e);
$ionicPopup.alert({
title: 'great',
content: 'The image upload to amazon success'
});
},
function(e) {
deferred.reject(e);
$ionicPopup.alert({
title: 'Oops',
content: 'The image upload failed to amazon'
});
}, options);
})
.error(function(data, status, headers, config) {
console.log(JSON.stringify(data));
console.log(status);
$ionicPopup.alert({
title: 'Oops',
content: 'The image upload failed to sign with node'
});
});
return deferred.promise;
}, false); //device ready
}
return {
upload: upload
}
})
and here is the controller code where am calling the camera plugin and in the success of taking the picture am calling the upload function from the S3Uploader service:
.controller('newItemCtrl', function($scope, $http, $ionicPopup, $timeout, $cordovaCamera, API_URL, me, S3Uploader) {
$scope.selectPicture = function() {
document.addEventListener('deviceready', function() {
var options = {
destinationType: Camera.DestinationType.FILE_URI,
sourceType: Camera.PictureSourceType.CAMERA,
allowEdit: true,
encodingType: Camera.EncodingType.JPEG,
targetWidth: 300,
targetHeight: 300,
};
$cordovaCamera.getPicture(options).then(function(imageURI) {
$scope.imageSrc = imageURI;
// upload to Amazon s3 bucket
var fileName = new Date().getTime() + ".jpg";
S3Uploader.upload(imageURI, fileName).then(function() {
alert("upload to S3 successed");
});
}, function(err) {
alert(err);
});
}, false); // device ready
}; // Select picture
})
i get the erorr in this line of the controller:
S3Uploader.upload(imageURI, fileName).then(function() {
it's also important to mention am using crosswalk with my ionic app.
Your current implementation of S3Uploader.upload does not return a promise, it returns nothing. Move your declaration and return of the promise to directly inside the S3Uploader.upload function and not nested inside the document.addEventListener code.
Change your code to something like:
.factory('S3Uploader', function($q, $window, $http, $ionicPopup, API_URL) {
var signingURI = API_URL + "s3signing";
function upload(imageURI, fileName) {
var deferred = $q.defer()
document.addEventListener('deviceready', function() {
// Removed for brevity
}, false);
return deferred.promise;
}
return {
upload: upload
}
})
You are creating and returning your deferred object and it's promise from an event listener. Not the upload factory method.
Something along these lines is what you need:
.factory('S3Uploader', function($q) {
function upload() {
var deferred = $q.defer();
// listener logic
return deferred.promise;
}
return {
upload : upload
}
});
You will have problems with this, as you will want a new deferred object for each time the listener is fired. Adding a listener to a factory method to perform something seems like a bad pattern to me. The event should wrap the invocation of the factory method.