Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-23230] iOS,Android: An event for the camera has been opened successfully.

GitHub Issuen/a
TypeNew Feature
PriorityMedium
StatusClosed
ResolutionFixed
Resolution Date2016-06-03T02:40:38.000+0000
Affected Version/sn/a
Fix Version/sRelease 6.0.0
ComponentsTiAPI
LabelsCamera, Media
ReporterMotiur Rahman
AssigneeHieu Pham
Created2016-04-18T18:13:03.000+0000
Updated2018-08-06T17:49:20.000+0000

Description

description

Suppose we have an app that automatically takes photos. At the moment what I do is invoke "Ti.Media.showCamera" then wait 2 seconds and then invoke Ti.Media.takePicture. But some devices take some time to open the camera. So the app is crashed when "Ti.Media.takePicture" is called before opening the camera. So the better way to know if the camera has been opened successfully using an event? I am not sure about the native behaviour.

Comments

  1. Angel Petkov 2016-04-28

    There is no event for when the camera has opened and it cannot be added without subclassing the UIImagePickerController. However, you can listen out for the [paused event](https://docs.appcelerator.com/platform/latest/#!/api/Titanium.App-event-paused) it will get fired once the application enters the background. You can take the picture inside that event, i would add a delay of a second just to avoid possible crashes.
  2. Motiur Rahman 2016-05-09

    [~apetkov], "paused" event only Fired when the application transitions to the background on a multitasked system. So if the application goes to the background then how can we take picture? We need event when the camera has opened successfully. So I think, that is not fit here. Now as a workaround we are using delay function "setTimeout". So when we can get this feature? This is needed for both android and iOS Thanks.
  3. Angel Petkov 2016-05-10

    Hello, yeah you're right adding the pause or paused event will not work, as they do not get executed once the camera overlays the application which i thought it would, as you can execute commands as the application enters the background. I've looked in to this issue more, there is no delegates for when the camera is opened so i cannot create an js callback event. I will think about this more and give an update soon, for the movement i cannot think of ways to implement this feature with good practices.
  4. Hieu Pham 2016-06-02

    To clarify, "takePicture()" is only used when the camera has overlay. On Android, we have our own activity to control the overlay, so this can be done.
  5. Hieu Pham 2016-06-02

    Android PR: https://github.com/appcelerator/titanium_mobile/pull/8039
  6. Hieu Pham 2016-06-02

    Testing code:
       var window = Ti.UI.createWindow();
       var overlay = Ti.UI.createView();
       var button = Titanium.UI.createButton({
       	color : '#fff',
       	bottom : "10dp",
       	width : "130dp",
       	height : "50dp",
       	font : {
       		fontSize : "14dp",
       		fontWeight : 'bold',
       		fontFamily : 'Helvetica Neue'
       	},
       	title : 'Take Picture'
       });
       
       button.addEventListener('click', function() {
       	Ti.Media.takePicture();
       });
       
       window.add(overlay);
       overlay.add(button);
       window.addEventListener('open', function(e){
          var cameraPermission = "android.permission.CAMERA";
          var storagePermission = "android.permission.READ_EXTERNAL_STORAGE";
          var hasCameraPerm = Ti.Android.hasPermission(cameraPermission);
          var hasStoragePerm = Ti.Android.hasPermission(storagePermission);
          var permissionsToRequest = [];
          if (!hasCameraPerm) {
          	permissionsToRequest.push(cameraPermission);
          }
          if (!hasStoragePerm) {
          	permissionsToRequest.push(storagePermission);
          }
          if (permissionsToRequest.length > 0) {
          	Ti.Android.requestPermissions(permissionsToRequest, function(e) {
              	if (e.success) {
              		showCamera();
              	} else {
              		Ti.API.info("ERROR: " + e.error);
              	}
          	});
          } else {
          		showCamera();
          }
       });
       Ti.Media.addEventListener('cameraready', function(e){
           Ti.Media.takePicture();
       })
       var container = Ti.UI.createView({
               top:'10%',
               height:'80%'
           });
       
       var img = Ti.UI.createImageView({
           });
       
       container.add(img);
       window.add(container);
       window.open();
       
       function showCamera() {
           Ti.Media.showCamera({
              success : function(e) {
                           Ti.API.info('GOT SUCCESS CALLBACK');
                           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;
              },
       	   overlay : overlay,
       	   mediaTypes : [Ti.Media.MEDIA_TYPE_PHOTO],
       	   saveToPhotoGallery : true
           });
       }
       
    1. Run code, should take picture automatically.
  7. Ashraf Abu 2016-06-03

    Android PR has been reviewed and merged into master for Release 6.0.0. https://github.com/appcelerator/titanium_mobile/pull/8039
  8. Hans Knöchel 2016-06-03

    iOS does not provide an API for checking if the camera was focussed. I would place it in -(void)displayModalPicker:(UIViewController*)picker_ settings:(NSDictionary*)args, but that is only the place where it starts opening so not good enough. Besides that, I never saw an application crashing on iOS, so the issue might only affect Android.
  9. Hieu Pham 2016-06-06

    The event is not just to prevent a crash, but to make sure takePicture() takes a picture, instead of doing nothing because the camera is not ready.
  10. Abir Mukherjee 2016-10-05

    I verified that the fix works on this environment: NPM Version: 2.15.9 Node Version: 4.5.0 Mac OS: 10.11.6 Appc CLI: 5.5.0 Appc CLI NPM: 4.2.7 Titanium SDK version: 6.0.0.v20161002235150 Appcelerator Studio, build: 4.8.0.201609290836 Xcode 8.0 GM I verified the fix on two different Android devices (5.1.1 and 6.0). I opened and closed the app 10 times using the demo code, and a picture was taken consistently each time. [~apetkov] you had noted that you will create a new ticket for iOS. Can you confirm if there is a new ticket for iOS? I will then close this one.
  11. Eric Merriman 2018-08-06

    Cleaning up older fixed issues. If this issue should not have been closed as fixed, please reopen.

JSON Source