[TIMOB-17329] Android: Refactor Camera API to not use a temporary file
| GitHub Issue | n/a |
|---|---|
| Type | Improvement |
| Priority | High |
| Status | Closed |
| Resolution | Fixed |
| Resolution Date | 2014-08-18T18:25:27.000+0000 |
| Affected Version/s | n/a |
| Fix Version/s | Release 3.4.0 |
| Components | Android |
| Labels | module_media, qe-manualtest |
| Reporter | Ingo Muschenetz |
| Assignee | Ping Wang |
| Created | 2014-07-15T04:19:25.000+0000 |
| Updated | 2014-08-18T18:25:27.000+0000 |
Description
In Titanium, we use temporary files when we are dealing with data that can not be kept in memory to avoid OOM errors. One case is in the Ti.Media module when the user takes pictures and the savetoPhotoGallery is set to false.
The blob representing the response (
media property for the payload to the success callback) will clearly indicate if the blob represents a file (Titanium.Blob.file will return a valid Titanium.Filesystem.File object). Users are free to delete the file once they have processed the data.
We should refactor the API to not rely on the temporary file.
Test case from TIMOB-1510
var win1 = Titanium.UI.createWindow({ backgroundColor : '#fff', exitOnClose:true }); var saveToGallery = false; var hasCamera = Ti.Media.isCameraSupported; if(hasCamera) { var hasBackfacingCamera = hasCamera; var hasFrontfacingCamera = hasCamera; var front = false; var availableCameras = Ti.Media.availableCameras; hasBackfacingCamera = (availableCameras.indexOf(Ti.Media.CAMERA_REAR) >= 0); hasFrontfacingCamera = (availableCameras.indexOf(Ti.Media.CAMERA_FRONT) >= 0); var b1 = Ti.UI.createButton({ title:'Save To Gallery', left:0, top:0, color:'red', width:'50%', height:'10%', backgroundColor:'black', }) ; var b2 = Ti.UI.createButton({ title:'View Gallery', right:0, top:0, width:'50%', height:'10%', backgroundColor:'black', color:'white' }); win1.add(b1); win1.add(b2); var container = Ti.UI.createView({ top:'10%', height:'80%' }); var img = Ti.UI.createImageView({ }); var saveButton = Ti.UI.createButton({ title:'SAVE', backgroundColor:'black', color:'white', visible:false }); container.add(img); container.add(saveButton); win1.add(container); var b3 = Ti.UI.createButton({ title:'Native Camera', top:'90%', height:'10%', left:0, width:'50%', backgroundColor:'black', color:'white' }); win1.add(b3); var b4 = Ti.UI.createButton({ title:'Camera Overlay', top:'90%', height:'10%', right:0, width:'50%', backgroundColor:'black', color:'white' }); win1.add(b4); var overlayObj = Ti.UI.createView({}); var picBtn = Ti.UI.createButton({ title:'Snap Picture', top:'90%', height:'10%', left:0, width:'50%', backgroundColor:'black', color:'white' }); overlayObj.add(picBtn); picBtn.addEventListener('click',function(){ Ti.Media.takePicture(); }); if(hasFrontfacingCamera && hasBackfacingCamera) { var swapBtn = Ti.UI.createButton({ title:'Switch Camera', top:'90%', height:'10%', right:0, width:'50%', backgroundColor:'black', color:'white' }); overlayObj.add(swapBtn); swapBtn.addEventListener('click',function(){ if(front == true) { Ti.Media.switchCamera(Ti.Media.CAMERA_REAR); } else { Ti.Media.switchCamera(Ti.Media.CAMERA_FRONT); } front = !front; }); } else { //Adjust Button picBtn.width = Ti.UI.FILL; } saveButton.addEventListener('click',function(e){ if(img.image != undefined) { Ti.Media.saveToPhotoGallery(img.image,{ success:function(){ alert('Saved. Check In Gallery'); }, error:function(e){ var msg = 'Code: '+e.code+' Msg: '+e.error; alert(msg); } }); } else { Ti.API.info('NO IMAGE ON img to save to photo gallery'); } }); b1.addEventListener('click',function(){ saveToGallery = !saveToGallery; if(saveToGallery == true) { b1.color = 'green'; } else { b1.color = 'red'; } }); b2.addEventListener('click',function(){ Ti.Media.openPhotoGallery({}); }); b3.addEventListener('click',function(){ fireUpTheCamera(saveToGallery,false, false); }); b4.addEventListener('click',function(){ if(hasBackfacingCamera && hasFrontfacingCamera) { //Alwways start with back camera front = false; } else { //Start with what ever camera is available front = hasFrontfacingCamera; } fireUpTheCamera(saveToGallery,true, front); }); function fireUpTheCamera(save, hasoverlay, front) { var options = { success : function(e) { Ti.API.info('GOT SUCCESS CALLBACK. File location = '+e.media.nativePath); var imgWid = e.media.width; var imgHeight = e.media.height; var mSize = container.size; var mW = mSize.width; var mH = mSize.height; var wS = imgWid/mW; var hS = imgHeight/mH; var tS = (wS < hS) ? wS : hS; var dstWid = imgWid/tS; var dstHeight = imgHeight/ tS; Ti.API.info(imgWid+' '+imgHeight+' '+mW+' '+mH+' '+wS+' '+hS+' '+tS+' '+dstWid+' '+dstHeight); var resize = e.media.imageAsResized(dstWid,dstHeight); img.image = resize; saveButton.visible = true; }, cancel : function() { // create alert var a = Titanium.UI.createAlertDialog({ title : 'Camera', message: 'Action cancelled by user' }); a.show(); }, error : function(error) { // create alert var a = Titanium.UI.createAlertDialog({ title : 'Camera' }); // set message var msg = 'Unexpected error: ' + error.code; if(error.error != undefined) { msg = msg + ' Message: '+error.error; } a.setMessage(msg); a.show(); }, saveToPhotoGallery : save, mediaTypes : [Ti.Media.MEDIA_TYPE_PHOTO], autohide: true }; if(hasoverlay) { options.overlay = overlayObj; } if(front) { options.whichCamera = Ti.Media.CAMERA_FRONT; } Titanium.Media.showCamera(options); } }else { var label = Ti.UI.createLabel({ text:'NO CAMERAS ON DEVICE', color:'red' }); win1.add(label); } win1.open();CR + FR ok. Merged
3_3_X PR: https://github.com/appcelerator/titanium_mobile/pull/5935
Verified the refactor. The pics does not get saved as a temp file in the sdcard when "save to gallery" is false. Closing. Environment: Appc Studio : 3.4.0.201408051600 Ti SDK : 3.4.0.v20140815142514 Mac OSX : 10.8.5 Alloy : 1.4.1 CLI - 3.3.0 Code Processor: 1.1.1 Nexus 5 - android 4.4.4