feat: add stop API to close active camera or media picker (#873)

- document stop API in README
- add stop to TypeScript definitions
- Generated-By: GPT-5.3-Codex

---------

Co-authored-by: Nitya Santosh <nityasantosh.channoju@planonsoftware.com>
Co-authored-by: Manuel Beck <manuelbeck87@outlook.de>
This commit is contained in:
Nitya Santosh
2026-07-30 09:09:07 +02:00
committed by GitHub
co-authored by Nitya Santosh Manuel Beck
parent a7cd05b20c
commit 8f30bf4efa
6 changed files with 91 additions and 2 deletions
+26
View File
@@ -169,6 +169,7 @@ To add these entries into the `info.plist`, you can use the `edit-config` tag in
- [camera](#module_camera)
- [.getPicture(successCallback, errorCallback, options)](#module_camera.getPicture)
- [.stop()](#module_camera.stop)
- [.cleanup()](#module_camera.cleanup)
- [.onError](#module_camera.onError) : <code>function</code>
- [.onSuccess](#module_camera.onSuccess) : <code>function</code>
@@ -273,6 +274,31 @@ More examples [here](#camera-getPicture-examples). Quirks [here](#camera-getPict
```js
navigator.camera.getPicture(cameraSuccess, cameraError, cameraOptions);
```
<a name="module_camera.stop"></a>
### camera.stop()
Closes the active camera or photo library picker UI.
__Supported Platforms__
- Android
- iOS
**Kind**: static method of <code>[camera](#module_camera)</code>
**Example**
```js
navigator.camera.stop(onSuccess, onFail);
function onSuccess() {
console.log('Camera stopped successfully.');
}
function onFail(message) {
alert('Failed because: ' + message);
}
```
<a name="module_camera.cleanup"></a>
### camera.cleanup()
+24 -2
View File
@@ -102,6 +102,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
private static final String IMAGE_URI_KEY = "imageUri";
private static final String TAKE_PICTURE_ACTION = "takePicture";
private static final String STOP_ACTION = "stop";
public static final int PERMISSION_DENIED_ERROR = 20;
public static final int TAKE_PIC_SEC = 0;
@@ -146,12 +147,11 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
* @return A PluginResult object with a status and message.
*/
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
this.callbackContext = callbackContext;
this.applicationId = cordova.getContext().getPackageName();
this.applicationId = preferences.getString("applicationId", this.applicationId);
if (action.equals(TAKE_PICTURE_ACTION)) {
this.callbackContext = callbackContext;
this.srcType = CAMERA;
this.destType = FILE_URI;
this.saveToPhotoAlbum = false;
@@ -216,6 +216,10 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
r.setKeepCallback(true);
callbackContext.sendPluginResult(r);
return true;
} else if (action.equals(STOP_ACTION)) {
this.stopCamera();
callbackContext.success();
return true;
}
return false;
@@ -307,6 +311,24 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
}
}
/**
* Closes any active camera or media picker activity started by this plugin.
*/
public void stopCamera() {
if (this.cordova == null || this.cordova.getActivity() == null) {
return;
}
int[] sourceTypes = { CAMERA, PHOTOLIBRARY, SAVEDPHOTOALBUM };
int[] returnTypes = { DATA_URL, FILE_URI };
for (int sourceType : sourceTypes) {
for (int returnType : returnTypes) {
this.cordova.getActivity().finishActivity((sourceType + 1) * 16 + returnType + 1);
}
}
}
public void takePicture(int returnType, int encodingType)
{
// Let's use the intent and see what happens
+1
View File
@@ -121,6 +121,7 @@ typedef NSUInteger CDVMediaType;
- (void)takePicture:(CDVInvokedUrlCommand*)command;
- (void)cleanup:(CDVInvokedUrlCommand*)command;
- (void)stop:(CDVInvokedUrlCommand*)command;
// UIImagePickerControllerDelegate methods
- (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info;
+20
View File
@@ -233,6 +233,26 @@ static NSString* MIME_JPEG = @"image/jpeg";
});
}
- (void)stop:(CDVInvokedUrlCommand*)command
{
dispatch_async(dispatch_get_main_queue(), ^{
UIViewController* presentedViewController = self.viewController.presentedViewController;
if (presentedViewController == nil) {
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
return;
}
[presentedViewController dismissViewControllerAnimated:YES completion:^{
self.hasPendingOperation = NO;
self.cdvUIImagePickerController = nil;
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
}];
});
}
- (void)sendNoPermissionResult:(NSString*)callbackId
{
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"has no access to camera"]; // error callback expects string ATM
+8
View File
@@ -17,6 +17,14 @@ interface Navigator {
* This plugin provides an API for taking pictures and for choosing images from the system's image library.
*/
interface Camera {
/**
* Closes the active camera or photo library picker UI.
* @param onSuccess Success callback, that called when stop succeeds.
* @param onError Error callback, that get an error message.
*/
stop(
onSuccess: () => void,
onError: (message: string) => void): void;
/**
* Removes intermediate photos taken by the camera from temporary storage.
* @param onSuccess Success callback, that called when cleanup succeeds.
+12
View File
@@ -147,6 +147,18 @@ cameraExport.getPicture = function (successCallback, errorCallback, options) {
exec(successCallback, errorCallback, 'Camera', 'takePicture', args);
};
/**
* Closes the active camera or media picker UI.
*
* __Supported Platforms__
*
* - Android
* - iOS
*/
cameraExport.stop = function (successCallback, errorCallback) {
exec(successCallback, errorCallback, 'Camera', 'stop', []);
};
/**
* Removes intermediate image files that are kept in temporary storage
* after calling [`camera.getPicture`]{@link module:camera.getPicture}. Applies only when the value of