mirror of
https://github.com/apache/cordova-plugin-camera.git
synced 2026-02-25 00:00:06 +08:00
Compare commits
15 Commits
rel/8.0.0
...
pr-resultf
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
277e21336f | ||
|
|
64b28461c6 | ||
|
|
1848db07ef | ||
|
|
77e85f2f08 | ||
|
|
b75cff893e | ||
|
|
3c1268531e | ||
|
|
fe1896cf1e | ||
|
|
d731cb9ad3 | ||
|
|
90ad137398 | ||
|
|
dc682b2532 | ||
|
|
599954887b | ||
|
|
80a2f18a05 | ||
|
|
8864262022 | ||
|
|
b002b48735 | ||
|
|
979155ee98 |
14
.github/workflows/ios.yml
vendored
14
.github/workflows/ios.yml
vendored
@@ -50,18 +50,26 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
versions:
|
||||
- os-version: macos-12
|
||||
- os-version: macos-14
|
||||
ios-version: 15.x
|
||||
xcode-version: 13.x
|
||||
xcode-version: 15.x
|
||||
|
||||
- os-version: macos-14
|
||||
ios-version: 16.x
|
||||
xcode-version: 14.x
|
||||
xcode-version: 15.x
|
||||
|
||||
- os-version: macos-14
|
||||
ios-version: 17.x
|
||||
xcode-version: 15.x
|
||||
|
||||
- os-version: macos-15
|
||||
ios-version: 18.x
|
||||
xcode-version: 16.x
|
||||
|
||||
- os-version: macos-26
|
||||
ios-version: 26.x
|
||||
xcode-version: 26.x
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
|
||||
193
README.md
193
README.md
@@ -30,11 +30,13 @@ the system's image library.
|
||||
|
||||
Although the object is attached to the global scoped `navigator`, it is not available until after the `deviceready` event.
|
||||
|
||||
document.addEventListener("deviceready", onDeviceReady, false);
|
||||
function onDeviceReady() {
|
||||
console.log(navigator.camera);
|
||||
}
|
||||
```js
|
||||
document.addEventListener("deviceready", onDeviceReady, false);
|
||||
|
||||
function onDeviceReady() {
|
||||
console.log(navigator.camera);
|
||||
}
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -65,41 +67,37 @@ In order for your changes to be accepted, you need to sign and submit an Apache
|
||||
|
||||
**And don't forget to test and document your code.**
|
||||
|
||||
### iOS Quirks
|
||||
### iOS Specifics
|
||||
|
||||
Since iOS 10 it's mandatory to provide an usage description in the `info.plist` if trying to access privacy-sensitive data. When the system prompts the user to allow access, this usage description string will displayed as part of the permission dialog box, but if you didn't provide the usage description, the app will crash before showing the dialog. Also, Apple will reject apps that access private data but don't provide an usage description.
|
||||
Since iOS 10 it's mandatory to provide a usage description in the `info.plist` when accessing privacy-sensitive data. The required keys depend on how you use the plugin and which iOS versions you support:
|
||||
|
||||
This plugins requires the following usage descriptions:
|
||||
| Key | Description |
|
||||
| ------------------------------ | ----------- |
|
||||
| NSCameraUsageDescription | Required whenever the camera is used (e.g. `Camera.PictureSourceType.CAMERA`). |
|
||||
| NSPhotoLibraryUsageDescription | Required only when your app runs on iOS 13 or older and using as `sourceType` `Camera.PictureSourceType.PHOTOLIBRARY`. On iOS 14+ the plugin uses PHPicker for read-only access, which does not need this key. |
|
||||
| NSPhotoLibraryAddUsageDescription | Required when the plugin writes to the user's library (e.g. `saveToPhotoAlbum=true`). |
|
||||
| NSLocationWhenInUseUsageDescription | Required if `CameraUsesGeolocation` is set to `true`. |
|
||||
|
||||
- `NSCameraUsageDescription` specifies the reason for your app to access the device's camera.
|
||||
- `NSPhotoLibraryUsageDescription` specifies the reason for your app to access the user's photo library.
|
||||
- `NSLocationWhenInUseUsageDescription` specifies the reason for your app to access the user's location information while your app is in use. (Set it if you have `CameraUsesGeolocation` preference set to `true`)
|
||||
- `NSPhotoLibraryAddUsageDescription` specifies the reason for your app to get write-only access to the user's photo library
|
||||
When the system prompts the user to allow access, this usage description string will be displayed as part of the permission dialog box. If you don't provide the required usage description, the app will crash before showing the dialog. Also, Apple will reject apps that access private data but don't provide a usage description.
|
||||
|
||||
To add these entries into the `info.plist`, you can use the `edit-config` tag in the `config.xml` like this:
|
||||
|
||||
```
|
||||
```xml
|
||||
<edit-config target="NSCameraUsageDescription" file="*-Info.plist" mode="merge">
|
||||
<string>need camera access to take pictures</string>
|
||||
</edit-config>
|
||||
```
|
||||
|
||||
```
|
||||
<edit-config target="NSPhotoLibraryUsageDescription" file="*-Info.plist" mode="merge">
|
||||
<string>need photo library access to get pictures from there</string>
|
||||
</edit-config>
|
||||
```
|
||||
|
||||
```
|
||||
<edit-config target="NSLocationWhenInUseUsageDescription" file="*-Info.plist" mode="merge">
|
||||
<string>need location access to find things nearby</string>
|
||||
</edit-config>
|
||||
```
|
||||
|
||||
```
|
||||
<edit-config target="NSPhotoLibraryAddUsageDescription" file="*-Info.plist" mode="merge">
|
||||
<string>need photo library access to save pictures there</string>
|
||||
</edit-config>
|
||||
|
||||
<edit-config target="NSLocationWhenInUseUsageDescription" file="*-Info.plist" mode="merge">
|
||||
<string>need location access to find things nearby</string>
|
||||
</edit-config>
|
||||
```
|
||||
|
||||
---
|
||||
@@ -120,12 +118,8 @@ To add these entries into the `info.plist`, you can use the `edit-config` tag in
|
||||
* [.EncodingType](#module_Camera.EncodingType) : <code>enum</code>
|
||||
* [.MediaType](#module_Camera.MediaType) : <code>enum</code>
|
||||
* [.PictureSourceType](#module_Camera.PictureSourceType) : <code>enum</code>
|
||||
* [.PopoverArrowDirection](#module_Camera.PopoverArrowDirection) : <code>enum</code>
|
||||
* [.Direction](#module_Camera.Direction) : <code>enum</code>
|
||||
|
||||
* [CameraPopoverHandle](#module_CameraPopoverHandle)
|
||||
* [CameraPopoverOptions](#module_CameraPopoverOptions)
|
||||
|
||||
---
|
||||
|
||||
<a name="module_camera"></a>
|
||||
@@ -218,7 +212,7 @@ __Supported Platforms__
|
||||
|
||||
More examples [here](#camera-getPicture-examples). Quirks [here](#camera-getPicture-quirks).
|
||||
|
||||
**Kind**: static method of <code>[camera](#module_camera)</code>
|
||||
**Kind**: static method of <code>[camera](#module_camera)</code>
|
||||
|
||||
| Param | Type | Description |
|
||||
| --- | --- | --- |
|
||||
@@ -226,7 +220,7 @@ More examples [here](#camera-getPicture-examples). Quirks [here](#camera-getPict
|
||||
| errorCallback | <code>[onError](#module_camera.onError)</code> | |
|
||||
| options | <code>[CameraOptions](#module_camera.CameraOptions)</code> | CameraOptions |
|
||||
|
||||
**Example**
|
||||
**Example**
|
||||
```js
|
||||
navigator.camera.getPicture(cameraSuccess, cameraError, cameraOptions);
|
||||
```
|
||||
@@ -242,8 +236,8 @@ __Supported Platforms__
|
||||
|
||||
- iOS
|
||||
|
||||
**Kind**: static method of <code>[camera](#module_camera)</code>
|
||||
**Example**
|
||||
**Kind**: static method of <code>[camera](#module_camera)</code>
|
||||
**Example**
|
||||
```js
|
||||
navigator.camera.cleanup(onSuccess, onFail);
|
||||
|
||||
@@ -260,7 +254,7 @@ function onFail(message) {
|
||||
### camera.onError : <code>function</code>
|
||||
Callback function that provides an error message.
|
||||
|
||||
**Kind**: static typedef of <code>[camera](#module_camera)</code>
|
||||
**Kind**: static typedef of <code>[camera](#module_camera)</code>
|
||||
|
||||
| Param | Type | Description |
|
||||
| --- | --- | --- |
|
||||
@@ -271,13 +265,13 @@ Callback function that provides an error message.
|
||||
### camera.onSuccess : <code>function</code>
|
||||
Callback function that provides the image data.
|
||||
|
||||
**Kind**: static typedef of <code>[camera](#module_camera)</code>
|
||||
**Kind**: static typedef of <code>[camera](#module_camera)</code>
|
||||
|
||||
| Param | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| imageData | <code>string</code> | Data URI, _or_ the image file URI, depending on [`cameraOptions`](#module_camera.CameraOptions) in effect. |
|
||||
|
||||
**Example**
|
||||
**Example**
|
||||
```js
|
||||
// Show image captured with FILE_URI
|
||||
function cameraCallback(imageData) {
|
||||
@@ -299,7 +293,7 @@ function cameraCallback(imageData) {
|
||||
Optional parameters to customize the camera settings.
|
||||
* [Quirks](#CameraOptions-quirks)
|
||||
|
||||
**Kind**: static typedef of <code>[camera](#module_camera)</code>
|
||||
**Kind**: static typedef of <code>[camera](#module_camera)</code>
|
||||
**Properties**
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
@@ -314,7 +308,6 @@ Optional parameters to customize the camera settings.
|
||||
| mediaType | <code>[MediaType](#module_Camera.MediaType)</code> | <code>PICTURE</code> | Set the type of media to select from. Only works when `PictureSourceType` is `PHOTOLIBRARY` or `SAVEDPHOTOALBUM`. |
|
||||
| correctOrientation | <code>Boolean</code> | | Rotate the image to correct for the orientation of the device during capture. |
|
||||
| saveToPhotoAlbum | <code>Boolean</code> | | Save the image to the photo album on the device after capture.<br />See [Android Quirks](#cameragetpicturesuccesscallback-errorcallback-options). |
|
||||
| popoverOptions | <code>[CameraPopoverOptions](#module_CameraPopoverOptions)</code> | | iOS-only options that specify popover location in iPad. |
|
||||
| cameraDirection | <code>[Direction](#module_Camera.Direction)</code> | <code>BACK</code> | Choose the camera to use (front- or back-facing). |
|
||||
|
||||
---
|
||||
@@ -327,7 +320,7 @@ Optional parameters to customize the camera settings.
|
||||
### Camera.DestinationType : <code>enum</code>
|
||||
Defines the output format of `Camera.getPicture` call.
|
||||
|
||||
**Kind**: static enum property of <code>[Camera](#module_Camera)</code>
|
||||
**Kind**: static enum property of <code>[Camera](#module_Camera)</code>
|
||||
**Properties**
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
@@ -338,7 +331,7 @@ Defines the output format of `Camera.getPicture` call.
|
||||
<a name="module_Camera.EncodingType"></a>
|
||||
|
||||
### Camera.EncodingType : <code>enum</code>
|
||||
**Kind**: static enum property of <code>[Camera](#module_Camera)</code>
|
||||
**Kind**: static enum property of <code>[Camera](#module_Camera)</code>
|
||||
**Properties**
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
@@ -349,7 +342,7 @@ Defines the output format of `Camera.getPicture` call.
|
||||
<a name="module_Camera.MediaType"></a>
|
||||
|
||||
### Camera.MediaType : <code>enum</code>
|
||||
**Kind**: static enum property of <code>[Camera](#module_Camera)</code>
|
||||
**Kind**: static enum property of <code>[Camera](#module_Camera)</code>
|
||||
**Properties**
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
@@ -363,35 +356,19 @@ Defines the output format of `Camera.getPicture` call.
|
||||
### Camera.PictureSourceType : <code>enum</code>
|
||||
Defines the output format of `Camera.getPicture` call.
|
||||
|
||||
**Kind**: static enum property of <code>[Camera](#module_Camera)</code>
|
||||
**Kind**: static enum property of <code>[Camera](#module_Camera)</code>
|
||||
**Properties**
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| PHOTOLIBRARY | <code>number</code> | <code>0</code> | Choose image from the device's photo library (same as SAVEDPHOTOALBUM for Android) |
|
||||
| PHOTOLIBRARY | <code>number</code> | <code>0</code> | Choose image from the device's photo library. |
|
||||
| CAMERA | <code>number</code> | <code>1</code> | Take picture from camera |
|
||||
| SAVEDPHOTOALBUM | <code>number</code> | <code>2</code> | Choose image only from the device's Camera Roll album (same as PHOTOLIBRARY for Android) |
|
||||
|
||||
<a name="module_Camera.PopoverArrowDirection"></a>
|
||||
|
||||
### Camera.PopoverArrowDirection : <code>enum</code>
|
||||
Matches iOS UIPopoverArrowDirection constants to specify arrow location on popover.
|
||||
|
||||
**Kind**: static enum property of <code>[Camera](#module_Camera)</code>
|
||||
**Properties**
|
||||
|
||||
| Name | Type | Default |
|
||||
| --- | --- | --- |
|
||||
| ARROW_UP | <code>number</code> | <code>1</code> |
|
||||
| ARROW_DOWN | <code>number</code> | <code>2</code> |
|
||||
| ARROW_LEFT | <code>number</code> | <code>4</code> |
|
||||
| ARROW_RIGHT | <code>number</code> | <code>8</code> |
|
||||
| ARROW_ANY | <code>number</code> | <code>15</code> |
|
||||
| SAVEDPHOTOALBUM | <code>number</code> | <code>2</code> | Same as `PHOTOLIBRARY`, when running on Android or iOS 14+. On iOS older than 14, an image can only be chosen from the device's Camera Roll album with this setting. |
|
||||
|
||||
<a name="module_Camera.Direction"></a>
|
||||
|
||||
### Camera.Direction : <code>enum</code>
|
||||
**Kind**: static enum property of <code>[Camera](#module_Camera)</code>
|
||||
**Kind**: static enum property of <code>[Camera](#module_Camera)</code>
|
||||
**Properties**
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
@@ -401,58 +378,6 @@ Matches iOS UIPopoverArrowDirection constants to specify arrow location on popov
|
||||
|
||||
---
|
||||
|
||||
<a name="module_CameraPopoverOptions"></a>
|
||||
|
||||
## CameraPopoverOptions
|
||||
iOS-only parameters that specify the anchor element location and arrow
|
||||
direction of the popover when selecting images from an iPad's library
|
||||
or album.
|
||||
Note that the size of the popover may change to adjust to the
|
||||
direction of the arrow and orientation of the screen. Make sure to
|
||||
account for orientation changes when specifying the anchor element
|
||||
location.
|
||||
|
||||
|
||||
| Param | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| [x] | <code>Number</code> | <code>0</code> | x pixel coordinate of screen element onto which to anchor the popover. |
|
||||
| [y] | <code>Number</code> | <code>32</code> | y pixel coordinate of screen element onto which to anchor the popover. |
|
||||
| [width] | <code>Number</code> | <code>320</code> | width, in pixels, of the screen element onto which to anchor the popover. |
|
||||
| [height] | <code>Number</code> | <code>480</code> | height, in pixels, of the screen element onto which to anchor the popover. |
|
||||
| [arrowDir] | <code>[PopoverArrowDirection](#module_Camera.PopoverArrowDirection)</code> | <code>ARROW_ANY</code> | Direction the arrow on the popover should point. |
|
||||
| [popoverWidth] | <code>Number</code> | <code>0</code> | width of the popover (0 or not specified will use apple's default width). |
|
||||
| [popoverHeight] | <code>Number</code> | <code>0</code> | height of the popover (0 or not specified will use apple's default height). |
|
||||
|
||||
---
|
||||
|
||||
<a name="module_CameraPopoverHandle"></a>
|
||||
|
||||
## CameraPopoverHandle
|
||||
A handle to an image picker popover.
|
||||
|
||||
__Supported Platforms__
|
||||
|
||||
- iOS
|
||||
|
||||
**Example**
|
||||
```js
|
||||
navigator.camera.getPicture(onSuccess, onFail,
|
||||
{
|
||||
destinationType: Camera.DestinationType.FILE_URI,
|
||||
sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
|
||||
popoverOptions: new CameraPopoverOptions(300, 300, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY, 300, 600)
|
||||
});
|
||||
|
||||
// Reposition the popover if the orientation changes.
|
||||
window.onorientationchange = function() {
|
||||
var cameraPopoverHandle = new CameraPopoverHandle();
|
||||
var cameraPopoverOptions = new CameraPopoverOptions(0, 0, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY, 400, 500);
|
||||
cameraPopoverHandle.setPosition(cameraPopoverOptions);
|
||||
}
|
||||
```
|
||||
---
|
||||
|
||||
|
||||
## `camera.getPicture` Errata
|
||||
|
||||
#### Example <a name="camera-getPicture-examples"></a>
|
||||
@@ -525,7 +450,7 @@ Can only return photos as data URI image.
|
||||
|
||||
Including a JavaScript `alert()` in either of the callback functions
|
||||
can cause problems. Wrap the alert within a `setTimeout()` to allow
|
||||
the iOS image picker or popover to fully close before the alert
|
||||
the iOS image picker to fully close before the alert
|
||||
displays:
|
||||
|
||||
```javascript
|
||||
@@ -643,23 +568,25 @@ function openCamera(selection) {
|
||||
|
||||
## Select a File from the Picture Library <a name="selectFile"></a>
|
||||
|
||||
When selecting a file using the file picker, you also need to set the CameraOptions object. In this example, set the `sourceType` to `Camera.PictureSourceType.SAVEDPHOTOALBUM`. To open the file picker, call `getPicture` just as you did in the previous example, passing in the success and error callbacks along with CameraOptions object.
|
||||
When selecting a file using the file picker, you also need to set the CameraOptions object. In this example, set the `sourceType` to `Camera.PictureSourceType.PHOTOLIBRARY`. To open the file picker, call `getPicture` just as you did in the previous example, passing in the success and error callbacks along with CameraOptions object.
|
||||
|
||||
```js
|
||||
function openFilePicker(selection) {
|
||||
|
||||
var srcType = Camera.PictureSourceType.SAVEDPHOTOALBUM;
|
||||
var srcType = Camera.PictureSourceType.PHOTOLIBRARY;
|
||||
var options = setOptions(srcType);
|
||||
var func = createNewFileEntry;
|
||||
|
||||
navigator.camera.getPicture(function cameraSuccess(imageUri) {
|
||||
|
||||
// Do something
|
||||
|
||||
}, function cameraError(error) {
|
||||
console.debug("Unable to obtain picture: " + error, "app");
|
||||
|
||||
}, options);
|
||||
navigator.camera.getPicture(
|
||||
// success callback
|
||||
(imageUri) => {
|
||||
// Do something
|
||||
},
|
||||
// error callback
|
||||
(error) => {
|
||||
console.debug("Unable to obtain picture: " + error, "app");
|
||||
},
|
||||
options);
|
||||
}
|
||||
```
|
||||
|
||||
@@ -670,7 +597,7 @@ Resizing a file selected with the file picker works just like resizing using the
|
||||
```js
|
||||
function openFilePicker(selection) {
|
||||
|
||||
var srcType = Camera.PictureSourceType.SAVEDPHOTOALBUM;
|
||||
var srcType = Camera.PictureSourceType.PHOTOLIBRARY;
|
||||
var options = setOptions(srcType);
|
||||
var func = createNewFileEntry;
|
||||
|
||||
@@ -681,14 +608,16 @@ function openFilePicker(selection) {
|
||||
options.targetWidth = 100;
|
||||
}
|
||||
|
||||
navigator.camera.getPicture(function cameraSuccess(imageUri) {
|
||||
|
||||
// Do something with image
|
||||
|
||||
}, function cameraError(error) {
|
||||
console.debug("Unable to obtain picture: " + error, "app");
|
||||
|
||||
}, options);
|
||||
navigator.camera.getPicture(
|
||||
// success callback
|
||||
(imageUri) {
|
||||
// Do something with image
|
||||
},
|
||||
// error callback
|
||||
(error) => {
|
||||
console.debug("Unable to obtain picture: " + error, "app");
|
||||
},
|
||||
options);
|
||||
}
|
||||
```
|
||||
|
||||
@@ -708,11 +637,11 @@ function getFileEntry(imgUri) {
|
||||
window.resolveLocalFileSystemURL(cordova.file.dataDirectory, function (dataDirectoryEntry) {
|
||||
fileEntry.copyTo(dataDirectoryEntry, "profilePic", onSuccess, onError);
|
||||
}, onError);
|
||||
|
||||
|
||||
// Example 2: Upload it!
|
||||
fileEntry.file(function (file) {
|
||||
var reader = new FileReader();
|
||||
|
||||
|
||||
reader.onloadend = function() {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('POST', 'https://myserver.com/upload');
|
||||
|
||||
16
package-lock.json
generated
16
package-lock.json
generated
@@ -1,18 +1,21 @@
|
||||
{
|
||||
"name": "cordova-plugin-camera",
|
||||
"version": "8.0.0",
|
||||
"version": "9.0.0-dev",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "cordova-plugin-camera",
|
||||
"version": "8.0.0",
|
||||
"version": "9.0.0-dev",
|
||||
"license": "Apache-2.0",
|
||||
"devDependencies": {
|
||||
"@cordova/eslint-config": "^5.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"cordovaDependencies": {
|
||||
"10.0.0": {
|
||||
"cordova": ">100"
|
||||
},
|
||||
"3.0.0": {
|
||||
"cordova-android": ">=6.3.0"
|
||||
},
|
||||
@@ -25,11 +28,6 @@
|
||||
"cordova-android": ">=9.0.0",
|
||||
"cordova-ios": ">=5.1.0"
|
||||
},
|
||||
"5.0.4-dev": {
|
||||
"cordova": ">=9.0.0",
|
||||
"cordova-android": "<10.0.0",
|
||||
"cordova-ios": ">=5.1.0"
|
||||
},
|
||||
"6.0.0": {
|
||||
"cordova": ">=9.0.0",
|
||||
"cordova-android": ">=10.0.0",
|
||||
@@ -46,7 +44,9 @@
|
||||
"cordova-ios": ">=5.1.0"
|
||||
},
|
||||
"9.0.0": {
|
||||
"cordova": ">100"
|
||||
"cordova": ">=9.0.0",
|
||||
"cordova-android": ">=12.0.0",
|
||||
"cordova-ios": ">=7.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
12
package.json
12
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cordova-plugin-camera",
|
||||
"version": "8.0.0",
|
||||
"version": "9.0.0-dev",
|
||||
"description": "Cordova Camera Plugin",
|
||||
"types": "./types/index.d.ts",
|
||||
"cordova": {
|
||||
@@ -41,11 +41,6 @@
|
||||
"cordova-ios": ">=5.1.0",
|
||||
"cordova": ">=9.0.0"
|
||||
},
|
||||
"5.0.4-dev": {
|
||||
"cordova-android": "<10.0.0",
|
||||
"cordova-ios": ">=5.1.0",
|
||||
"cordova": ">=9.0.0"
|
||||
},
|
||||
"6.0.0": {
|
||||
"cordova-android": ">=10.0.0",
|
||||
"cordova-ios": ">=5.1.0",
|
||||
@@ -62,6 +57,11 @@
|
||||
"cordova": ">=9.0.0"
|
||||
},
|
||||
"9.0.0": {
|
||||
"cordova-android": ">=12.0.0",
|
||||
"cordova-ios": ">=7.0.0",
|
||||
"cordova": ">=9.0.0"
|
||||
},
|
||||
"10.0.0": {
|
||||
"cordova": ">100"
|
||||
}
|
||||
}
|
||||
|
||||
16
plugin.xml
16
plugin.xml
@@ -21,7 +21,7 @@
|
||||
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
id="cordova-plugin-camera"
|
||||
version="8.0.0">
|
||||
version="9.0.0-dev">
|
||||
<name>Camera</name>
|
||||
<description>Cordova Camera Plugin</description>
|
||||
<license>Apache 2.0</license>
|
||||
@@ -32,17 +32,13 @@
|
||||
<engines>
|
||||
<engine name="cordova" version=">=9.0.0"/>
|
||||
<engine name="cordova-android" version=">=12.0.0" />
|
||||
<engine name="cordova-ios" version=">=5.1.0" />
|
||||
<engine name="cordova-ios" version=">=7.0.0" />
|
||||
</engines>
|
||||
|
||||
<js-module src="www/CameraConstants.js" name="Camera">
|
||||
<clobbers target="Camera" />
|
||||
</js-module>
|
||||
|
||||
<js-module src="www/CameraPopoverOptions.js" name="CameraPopoverOptions">
|
||||
<clobbers target="CameraPopoverOptions" />
|
||||
</js-module>
|
||||
|
||||
<js-module src="www/Camera.js" name="camera">
|
||||
<clobbers target="navigator.camera" />
|
||||
</js-module>
|
||||
@@ -91,10 +87,6 @@
|
||||
|
||||
<preference name="ANDROIDX_CORE_VERSION" default="1.6.+"/>
|
||||
<framework src="androidx.core:core:$ANDROIDX_CORE_VERSION" />
|
||||
|
||||
<js-module src="www/CameraPopoverHandle.js" name="CameraPopoverHandle">
|
||||
<clobbers target="CameraPopoverHandle" />
|
||||
</js-module>
|
||||
</platform>
|
||||
|
||||
<!-- ios -->
|
||||
@@ -106,10 +98,6 @@
|
||||
<preference name="CameraUsesGeolocation" value="false" />
|
||||
</config-file>
|
||||
|
||||
<js-module src="www/ios/CameraPopoverHandle.js" name="CameraPopoverHandle">
|
||||
<clobbers target="CameraPopoverHandle" />
|
||||
</js-module>
|
||||
|
||||
<header-file src="src/ios/UIImage+CropScaleOrientation.h" />
|
||||
<source-file src="src/ios/UIImage+CropScaleOrientation.m" />
|
||||
<header-file src="src/ios/CDVCamera.h" />
|
||||
|
||||
@@ -77,9 +77,10 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
private static final int DATA_URL = 0; // Return base64 encoded string
|
||||
private static final int FILE_URI = 1; // Return file uri (content://media/external/images/media/2 for Android)
|
||||
|
||||
private static final int PHOTOLIBRARY = 0; // Choose image from picture library (same as SAVEDPHOTOALBUM for Android)
|
||||
private static final int PHOTOLIBRARY = 0; // Choose image from picture library
|
||||
private static final int CAMERA = 1; // Take picture from camera
|
||||
private static final int SAVEDPHOTOALBUM = 2; // Choose image from picture library (same as PHOTOLIBRARY for Android)
|
||||
private static final int SAVEDPHOTOALBUM = 2; // Same as PHOTOLIBRARY. This settings makes only a difference on iOS older than 14,
|
||||
// where an image can only be chosen from the device's Camera Roll album, with this setting.
|
||||
|
||||
private static final int PICTURE = 0; // allow selection of still pictures only. DEFAULT. Will return format specified via DestinationType
|
||||
private static final int VIDEO = 1; // allow selection of video only, ONLY RETURNS URL
|
||||
@@ -332,6 +333,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
else
|
||||
{
|
||||
LOG.d(LOG_TAG, "Error: You don't have a default camera. Your device may not be CTS complaint.");
|
||||
throw new IllegalStateException("No camera application available.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -422,9 +424,15 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
intent.setAction(Intent.ACTION_GET_CONTENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
}
|
||||
|
||||
if (this.cordova != null) {
|
||||
this.cordova.startActivityForResult((CordovaPlugin) this, Intent.createChooser(intent,
|
||||
new String(title)), (srcType + 1) * 16 + returnType + 1);
|
||||
this.cordova.startActivityForResult(
|
||||
(CordovaPlugin) this,
|
||||
Intent.createChooser(
|
||||
intent,
|
||||
new String(title)),
|
||||
// Requestcode
|
||||
(srcType + 1) * 16 + returnType + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,26 @@
|
||||
#import <CoreLocation/CLLocationManager.h>
|
||||
#import <Cordova/CDVPlugin.h>
|
||||
|
||||
// Since iOS 14, we can use PHPickerViewController to select images from the photo library
|
||||
//
|
||||
// The following condition checks if the iOS 14 SDK is available for XCode
|
||||
// which is true for XCode 12+. It does not check on runtime, if the device is running iOS 14+.
|
||||
// For that API_AVAILABLE(ios(14)) is used for methods declarations and @available(iOS 14, *) for the code.
|
||||
// The condition here makes just sure that the code can compile in XCode
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000 // Always true on XCode12+
|
||||
|
||||
// Import UniformTypeIdentifiers.h for using UTType* things, available since iOS 14,
|
||||
// which replaces for e.g. kUTTypeImage with UTTypeImage, which must be used in the future instead
|
||||
// Currently only used for PHPickerViewController
|
||||
#import <UniformTypeIdentifiers/UniformTypeIdentifiers.h>
|
||||
|
||||
// Import PhotosUI framework for using PHPickerViewController
|
||||
// PhotosUI is already available since iOS 8, but since we need it currently
|
||||
// only for the PHPickerViewController, we import it conditionally here
|
||||
#import <PhotosUI/PhotosUI.h>
|
||||
|
||||
#endif
|
||||
|
||||
enum CDVDestinationType {
|
||||
DestinationTypeDataUrl = 0,
|
||||
DestinationTypeFileUri
|
||||
@@ -52,10 +72,12 @@ typedef NSUInteger CDVMediaType;
|
||||
@property (assign) BOOL allowsEditing;
|
||||
@property (assign) BOOL correctOrientation;
|
||||
@property (assign) BOOL saveToPhotoAlbum;
|
||||
@property (strong) NSDictionary* popoverOptions;
|
||||
@property (assign) UIImagePickerControllerCameraDevice cameraDirection;
|
||||
|
||||
@property (assign) BOOL popoverSupported;
|
||||
/**
|
||||
Include GPS location information in the image's EXIF metadata, when capturing JPEGs.
|
||||
This is YES when the preference `CameraUsesGeolocation` is set to true in config.xml.
|
||||
*/
|
||||
@property (assign) BOOL usesGeolocation;
|
||||
@property (assign) BOOL cropToSize;
|
||||
|
||||
@@ -63,13 +85,12 @@ typedef NSUInteger CDVMediaType;
|
||||
|
||||
@end
|
||||
|
||||
@interface CDVCameraPicker : UIImagePickerController
|
||||
@interface CDVUIImagePickerController : UIImagePickerController
|
||||
|
||||
@property (strong) CDVPictureOptions* pictureOptions;
|
||||
|
||||
@property (copy) NSString* callbackId;
|
||||
@property (copy) NSString* postUrl;
|
||||
@property (strong) UIPopoverController* pickerPopoverController;
|
||||
@property (assign) BOOL cropToSize;
|
||||
@property (strong) UIView* webView;
|
||||
|
||||
@@ -78,38 +99,47 @@ typedef NSUInteger CDVMediaType;
|
||||
@end
|
||||
|
||||
// ======================================================================= //
|
||||
|
||||
// Use PHPickerViewController in iOS 14+ to select images from the photo library
|
||||
// PHPickerViewControllerDelegate is only available since iOS 14
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000 // Always true on XCode12+
|
||||
@interface CDVCamera : CDVPlugin <UIImagePickerControllerDelegate,
|
||||
UINavigationControllerDelegate,
|
||||
CLLocationManagerDelegate,
|
||||
PHPickerViewControllerDelegate>
|
||||
{}
|
||||
#else
|
||||
@interface CDVCamera : CDVPlugin <UIImagePickerControllerDelegate,
|
||||
UINavigationControllerDelegate,
|
||||
UIPopoverControllerDelegate,
|
||||
CLLocationManagerDelegate>
|
||||
{}
|
||||
#endif
|
||||
|
||||
@property (strong) CDVCameraPicker* pickerController;
|
||||
@property (strong) CDVUIImagePickerController* cdvUIImagePickerController;
|
||||
@property (strong) NSMutableDictionary *metadata;
|
||||
@property (strong, nonatomic) CLLocationManager *locationManager;
|
||||
@property (strong) NSData* data;
|
||||
|
||||
/*
|
||||
* getPicture
|
||||
*
|
||||
* arguments:
|
||||
* 1: this is the javascript function that will be called with the results, the first parameter passed to the
|
||||
* javascript function is the picture as a Base64 encoded string
|
||||
* 2: this is the javascript function to be called if there was an error
|
||||
* options:
|
||||
* quality: integer between 1 and 100
|
||||
*/
|
||||
- (void)takePicture:(CDVInvokedUrlCommand*)command;
|
||||
- (void)cleanup:(CDVInvokedUrlCommand*)command;
|
||||
- (void)repositionPopover:(CDVInvokedUrlCommand*)command;
|
||||
|
||||
// UIImagePickerControllerDelegate methods
|
||||
- (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info;
|
||||
- (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingImage:(UIImage*)image editingInfo:(NSDictionary*)editingInfo;
|
||||
- (void)imagePickerControllerDidCancel:(UIImagePickerController*)picker;
|
||||
|
||||
// UINavigationControllerDelegate method
|
||||
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated;
|
||||
|
||||
// CLLocationManagerDelegate methods
|
||||
- (void)locationManager:(CLLocationManager*)manager didUpdateToLocation:(CLLocation*)newLocation fromLocation:(CLLocation*)oldLocation;
|
||||
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error;
|
||||
|
||||
// PHPickerViewController specific methods (iOS 14+)
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000 // Always true on XCode12+
|
||||
- (void)showPHPicker:(NSString*)callbackId withOptions:(CDVPictureOptions*)pictureOptions API_AVAILABLE(ios(14));
|
||||
- (void)processPHPickerImage:(UIImage*)image metadata:(NSDictionary*)metadata callbackId:(NSString*)callbackId options:(CDVPictureOptions*)options API_AVAILABLE(ios(14));
|
||||
// PHPickerViewControllerDelegate method
|
||||
- (void)picker:(PHPickerViewController *)picker didFinishPicking:(NSArray<PHPickerResult *> *)results API_AVAILABLE(ios(14));
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -37,28 +37,30 @@
|
||||
- (UIImage*)retrieveImage:(NSDictionary*)info options:(CDVPictureOptions*)options;
|
||||
- (CDVPluginResult*)resultForImage:(CDVPictureOptions*)options info:(NSDictionary*)info;
|
||||
- (CDVPluginResult*)resultForVideo:(NSDictionary*)info;
|
||||
- (NSDictionary*)convertImageMetadata:(NSData*)imageData;
|
||||
|
||||
@end
|
||||
|
||||
@implementation CameraTest
|
||||
|
||||
- (void)setUp {
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||
|
||||
self.plugin = [[CDVCamera alloc] init];
|
||||
}
|
||||
|
||||
- (void)tearDown {
|
||||
- (void)tearDown
|
||||
{
|
||||
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||
[super tearDown];
|
||||
}
|
||||
|
||||
- (void) testPictureOptionsCreate
|
||||
- (void)testPictureOptionsCreate
|
||||
{
|
||||
NSArray* args;
|
||||
CDVPictureOptions* options;
|
||||
NSDictionary* popoverOptions;
|
||||
|
||||
// No arguments, check whether the defaults are set
|
||||
args = @[];
|
||||
@@ -76,14 +78,10 @@
|
||||
XCTAssertEqual(options.allowsEditing, NO);
|
||||
XCTAssertEqual(options.correctOrientation, NO);
|
||||
XCTAssertEqual(options.saveToPhotoAlbum, NO);
|
||||
XCTAssertEqualObjects(options.popoverOptions, nil);
|
||||
XCTAssertEqual(options.cameraDirection, (int)UIImagePickerControllerCameraDeviceRear);
|
||||
XCTAssertEqual(options.popoverSupported, NO);
|
||||
XCTAssertEqual(options.usesGeolocation, NO);
|
||||
|
||||
// Set each argument, check whether they are set. different from defaults
|
||||
popoverOptions = @{ @"x" : @1, @"y" : @2, @"width" : @3, @"height" : @4, @"popoverWidth": @200, @"popoverHeight": @300 };
|
||||
|
||||
args = @[
|
||||
@(49),
|
||||
@(DestinationTypeDataUrl),
|
||||
@@ -95,7 +93,6 @@
|
||||
@YES,
|
||||
@YES,
|
||||
@YES,
|
||||
popoverOptions,
|
||||
@(UIImagePickerControllerCameraDeviceFront),
|
||||
];
|
||||
|
||||
@@ -112,22 +109,17 @@
|
||||
XCTAssertEqual(options.allowsEditing, YES);
|
||||
XCTAssertEqual(options.correctOrientation, YES);
|
||||
XCTAssertEqual(options.saveToPhotoAlbum, YES);
|
||||
XCTAssertEqualObjects(options.popoverOptions, popoverOptions);
|
||||
XCTAssertEqual(options.cameraDirection, (int)UIImagePickerControllerCameraDeviceFront);
|
||||
XCTAssertEqual(options.popoverSupported, NO);
|
||||
XCTAssertEqual(options.usesGeolocation, NO);
|
||||
}
|
||||
|
||||
- (void) testCameraPickerCreate
|
||||
- (void)testCameraPickerCreate
|
||||
{
|
||||
NSDictionary* popoverOptions;
|
||||
NSArray* args;
|
||||
CDVPictureOptions* pictureOptions;
|
||||
CDVCameraPicker* picker;
|
||||
CDVUIImagePickerController* picker;
|
||||
|
||||
// Souce is Camera, and image type
|
||||
|
||||
popoverOptions = @{ @"x" : @1, @"y" : @2, @"width" : @3, @"height" : @4, @"popoverWidth": @200, @"popoverHeight": @300 };
|
||||
// Source is Camera, uses always UIImagePickerController
|
||||
args = @[
|
||||
@(49),
|
||||
@(DestinationTypeDataUrl),
|
||||
@@ -139,7 +131,6 @@
|
||||
@YES,
|
||||
@YES,
|
||||
@YES,
|
||||
popoverOptions,
|
||||
@(UIImagePickerControllerCameraDeviceFront),
|
||||
];
|
||||
|
||||
@@ -147,7 +138,7 @@
|
||||
pictureOptions = [CDVPictureOptions createFromTakePictureArguments:command];
|
||||
|
||||
if ([UIImagePickerController isSourceTypeAvailable:pictureOptions.sourceType]) {
|
||||
picker = [CDVCameraPicker createFromPictureOptions:pictureOptions];
|
||||
picker = [CDVUIImagePickerController createFromPictureOptions:pictureOptions];
|
||||
|
||||
XCTAssertEqualObjects(picker.pictureOptions, pictureOptions);
|
||||
|
||||
@@ -157,7 +148,7 @@
|
||||
XCTAssertEqual(picker.cameraDevice, pictureOptions.cameraDirection);
|
||||
}
|
||||
|
||||
// Souce is not Camera, and all media types
|
||||
// Source is Photo Library, and all media types - On iOS 14+ uses PHPicker, below uses UIImagePickerController
|
||||
|
||||
args = @[
|
||||
@(49),
|
||||
@@ -170,7 +161,6 @@
|
||||
@YES,
|
||||
@YES,
|
||||
@YES,
|
||||
popoverOptions,
|
||||
@(UIImagePickerControllerCameraDeviceFront),
|
||||
];
|
||||
|
||||
@@ -178,7 +168,7 @@
|
||||
pictureOptions = [CDVPictureOptions createFromTakePictureArguments:command];
|
||||
|
||||
if ([UIImagePickerController isSourceTypeAvailable:pictureOptions.sourceType]) {
|
||||
picker = [CDVCameraPicker createFromPictureOptions:pictureOptions];
|
||||
picker = [CDVUIImagePickerController createFromPictureOptions:pictureOptions];
|
||||
|
||||
XCTAssertEqualObjects(picker.pictureOptions, pictureOptions);
|
||||
|
||||
@@ -187,7 +177,7 @@
|
||||
XCTAssertEqualObjects(picker.mediaTypes, [UIImagePickerController availableMediaTypesForSourceType:picker.sourceType]);
|
||||
}
|
||||
|
||||
// Souce is not Camera, and either Image or Movie media type
|
||||
// Source is Photo Library, and either Image or Movie media type - On iOS 14+ uses PHPicker
|
||||
|
||||
args = @[
|
||||
@(49),
|
||||
@@ -200,7 +190,6 @@
|
||||
@YES,
|
||||
@YES,
|
||||
@YES,
|
||||
popoverOptions,
|
||||
@(UIImagePickerControllerCameraDeviceFront),
|
||||
];
|
||||
|
||||
@@ -208,7 +197,7 @@
|
||||
pictureOptions = [CDVPictureOptions createFromTakePictureArguments:command];
|
||||
|
||||
if ([UIImagePickerController isSourceTypeAvailable:pictureOptions.sourceType]) {
|
||||
picker = [CDVCameraPicker createFromPictureOptions:pictureOptions];
|
||||
picker = [CDVUIImagePickerController createFromPictureOptions:pictureOptions];
|
||||
|
||||
XCTAssertEqualObjects(picker.pictureOptions, pictureOptions);
|
||||
|
||||
@@ -218,7 +207,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (UIImage*) createImage:(CGRect)rect orientation:(UIImageOrientation)imageOrientation {
|
||||
- (UIImage*)createImage:(CGRect)rect orientation:(UIImageOrientation)imageOrientation
|
||||
{
|
||||
UIGraphicsBeginImageContext(rect.size);
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
|
||||
@@ -233,8 +223,8 @@
|
||||
return image;
|
||||
}
|
||||
|
||||
- (void) testImageScaleCropForSize {
|
||||
|
||||
- (void)testImageScaleCropForSize
|
||||
{
|
||||
UIImage *sourceImagePortrait, *sourceImageLandscape, *targetImage;
|
||||
CGSize targetSize = CGSizeZero;
|
||||
|
||||
@@ -279,7 +269,8 @@
|
||||
XCTAssertEqual(targetImage.size.height, targetSize.height);
|
||||
}
|
||||
|
||||
- (void) testImageScaleNoCropForSize {
|
||||
- (void)testImageScaleNoCropForSize
|
||||
{
|
||||
UIImage *sourceImagePortrait, *sourceImageLandscape, *targetImage;
|
||||
CGSize targetSize = CGSizeZero;
|
||||
|
||||
@@ -330,7 +321,8 @@
|
||||
XCTAssertEqual(targetImage.size.height, targetSize.height);
|
||||
}
|
||||
|
||||
- (void) testImageCorrectedForOrientation {
|
||||
- (void)testImageCorrectedForOrientation
|
||||
{
|
||||
UIImage *sourceImagePortrait, *sourceImageLandscape, *targetImage;
|
||||
CGSize targetSize = CGSizeZero;
|
||||
|
||||
@@ -383,7 +375,7 @@
|
||||
}
|
||||
|
||||
|
||||
- (void) testRetrieveImage
|
||||
- (void)testRetrieveImage
|
||||
{
|
||||
CDVPictureOptions* pictureOptions = [[CDVPictureOptions alloc] init];
|
||||
NSDictionary *infoDict1, *infoDict2;
|
||||
@@ -461,7 +453,7 @@
|
||||
XCTAssertEqual(resultImage.size.height, scaledImageWithCrop.size.height);
|
||||
}
|
||||
|
||||
- (void) testProcessImage
|
||||
- (void)testProcessImage
|
||||
{
|
||||
CDVPictureOptions* pictureOptions = [[CDVPictureOptions alloc] init];
|
||||
NSData* resultData;
|
||||
@@ -508,4 +500,123 @@
|
||||
// TODO: usesGeolocation is not tested
|
||||
}
|
||||
|
||||
#pragma mark - PHPickerViewController Tests (iOS 14+)
|
||||
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000 // Always true on XCode12+
|
||||
- (void)testPHPickerAvailability API_AVAILABLE(ios(14))
|
||||
{
|
||||
XCTAssertNotNil([PHPickerViewController class]);
|
||||
|
||||
PHPickerConfiguration *config = [[PHPickerConfiguration alloc] init];
|
||||
XCTAssertNotNil(config);
|
||||
|
||||
config.filter = [PHPickerFilter imagesFilter];
|
||||
XCTAssertNotNil(config.filter);
|
||||
|
||||
PHPickerViewController *picker = [[PHPickerViewController alloc] initWithConfiguration:config];
|
||||
XCTAssertNotNil(picker);
|
||||
}
|
||||
|
||||
- (void)testPHPickerConfiguration API_AVAILABLE(ios(14))
|
||||
{
|
||||
// Test image filter configuration
|
||||
PHPickerConfiguration *imageConfig = [[PHPickerConfiguration alloc] init];
|
||||
imageConfig.filter = [PHPickerFilter imagesFilter];
|
||||
imageConfig.selectionLimit = 1;
|
||||
|
||||
XCTAssertNotNil(imageConfig);
|
||||
XCTAssertEqual(imageConfig.selectionLimit, 1);
|
||||
|
||||
// Test video filter configuration
|
||||
PHPickerConfiguration *videoConfig = [[PHPickerConfiguration alloc] init];
|
||||
videoConfig.filter = [PHPickerFilter videosFilter];
|
||||
|
||||
XCTAssertNotNil(videoConfig.filter);
|
||||
|
||||
// Test all media types configuration
|
||||
PHPickerConfiguration *allConfig = [[PHPickerConfiguration alloc] init];
|
||||
allConfig.filter = [PHPickerFilter anyFilterMatchingSubfilters:@[
|
||||
[PHPickerFilter imagesFilter],
|
||||
[PHPickerFilter videosFilter]
|
||||
]];
|
||||
|
||||
XCTAssertNotNil(allConfig.filter);
|
||||
}
|
||||
|
||||
- (void)testPHPickerDelegateConformance API_AVAILABLE(ios(14))
|
||||
{
|
||||
// Test that CDVCamera conforms to PHPickerViewControllerDelegate
|
||||
XCTAssertTrue([self.plugin conformsToProtocol:@protocol(PHPickerViewControllerDelegate)]);
|
||||
|
||||
// Test that the delegate method is implemented
|
||||
SEL delegateSelector = @selector(picker:didFinishPicking:);
|
||||
XCTAssertTrue([self.plugin respondsToSelector:delegateSelector]);
|
||||
}
|
||||
|
||||
- (void)testShowPHPickerMethod API_AVAILABLE(ios(14))
|
||||
{
|
||||
// Test that showPHPicker method exists
|
||||
SEL showPHPickerSelector = @selector(showPHPicker:withOptions:);
|
||||
XCTAssertTrue([self.plugin respondsToSelector:showPHPickerSelector]);
|
||||
|
||||
// Test that processPHPickerImage method exists
|
||||
SEL processSelector = @selector(processPHPickerImage:assetIdentifier:callbackId:options:);
|
||||
XCTAssertTrue([self.plugin respondsToSelector:processSelector]);
|
||||
|
||||
// Test that processPHPickerImage method exists
|
||||
SEL processPHPickerImageSelector = @selector(processPHPickerImage:metadata:callbackId:options:);
|
||||
XCTAssertTrue([self.plugin respondsToSelector:processPHPickerImageSelector]);
|
||||
}
|
||||
#endif
|
||||
|
||||
- (void)testConvertImageMetadata
|
||||
{
|
||||
// Create a test image
|
||||
UIImage* testImage = [self createImage:CGRectMake(0, 0, 100, 100) orientation:UIImageOrientationUp];
|
||||
NSData* imageData = UIImageJPEGRepresentation(testImage, 1.0);
|
||||
|
||||
XCTAssertNotNil(imageData);
|
||||
|
||||
// Test metadata conversion
|
||||
NSDictionary* metadata = [self.plugin convertImageMetadata:imageData];
|
||||
|
||||
// Metadata may be nil for generated images, but the method should not crash
|
||||
// Real camera images would have EXIF data
|
||||
XCTAssertTrue(metadata == nil || [metadata isKindOfClass:[NSDictionary class]]);
|
||||
}
|
||||
|
||||
- (void)testPictureOptionsForPHPicker
|
||||
{
|
||||
NSArray* args;
|
||||
CDVPictureOptions* options;
|
||||
|
||||
// Test options configuration for photo library (which would use PHPicker on iOS 14+)
|
||||
args = @[
|
||||
@(75),
|
||||
@(DestinationTypeFileUri),
|
||||
@(UIImagePickerControllerSourceTypePhotoLibrary),
|
||||
@(800),
|
||||
@(600),
|
||||
@(EncodingTypeJPEG),
|
||||
@(MediaTypePicture),
|
||||
@NO,
|
||||
@YES,
|
||||
@NO,
|
||||
[NSNull null],
|
||||
@(UIImagePickerControllerCameraDeviceRear),
|
||||
];
|
||||
|
||||
CDVInvokedUrlCommand* command = [[CDVInvokedUrlCommand alloc] initWithArguments:args callbackId:@"dummy" className:@"myclassname" methodName:@"mymethodname"];
|
||||
options = [CDVPictureOptions createFromTakePictureArguments:command];
|
||||
|
||||
// Verify options are correctly set for photo library source
|
||||
XCTAssertEqual(options.sourceType, (int)UIImagePickerControllerSourceTypePhotoLibrary);
|
||||
XCTAssertEqual([options.quality intValue], 75);
|
||||
XCTAssertEqual(options.destinationType, (int)DestinationTypeFileUri);
|
||||
XCTAssertEqual(options.targetSize.width, 800);
|
||||
XCTAssertEqual(options.targetSize.height, 600);
|
||||
XCTAssertEqual(options.correctOrientation, YES);
|
||||
XCTAssertEqual(options.mediaType, (int)MediaTypePicture);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
4
tests/package-lock.json
generated
4
tests/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "cordova-plugin-camera-tests",
|
||||
"version": "8.0.0",
|
||||
"version": "8.0.1-dev",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "cordova-plugin-camera-tests",
|
||||
"version": "8.0.0",
|
||||
"version": "8.0.1-dev",
|
||||
"license": "Apache-2.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cordova-plugin-camera-tests",
|
||||
"version": "8.0.0",
|
||||
"version": "9.0.0-dev",
|
||||
"description": "",
|
||||
"cordova": {
|
||||
"id": "cordova-plugin-camera-tests",
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:rim="http://www.blackberry.com/ns/widgets"
|
||||
id="cordova-plugin-camera-tests"
|
||||
version="8.0.0">
|
||||
version="9.0.0-dev">
|
||||
<name>Cordova Camera Plugin Tests</name>
|
||||
<license>Apache 2.0</license>
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/* globals Camera, resolveLocalFileSystemURL, FileEntry, CameraPopoverOptions, LocalFileSystem */
|
||||
/* globals Camera, resolveLocalFileSystemURL, FileEntry, LocalFileSystem */
|
||||
/* eslint-env jasmine */
|
||||
|
||||
exports.defineAutoTests = function () {
|
||||
@@ -156,13 +156,7 @@ exports.defineManualTests = function (contentEl, createActionButton) {
|
||||
clearStatus();
|
||||
const options = extractOptions();
|
||||
log('Getting picture with options: ' + JSON.stringify(options));
|
||||
const popoverHandle = navigator.camera.getPicture(getPictureWin, onGetPictureError, options);
|
||||
|
||||
// Reposition the popover if the orientation changes.
|
||||
window.onorientationchange = function () {
|
||||
const newPopoverOptions = new CameraPopoverOptions(0, 0, 100, 100, 0, 300, 400);
|
||||
popoverHandle.setPosition(newPopoverOptions);
|
||||
};
|
||||
navigator.camera.getPicture(getPictureWin, onGetPictureError, options);
|
||||
}
|
||||
|
||||
function logCallback (apiName, success) {
|
||||
|
||||
55
types/index.d.ts
vendored
55
types/index.d.ts
vendored
@@ -36,11 +36,6 @@ interface Camera {
|
||||
cameraSuccess: (data: string) => void,
|
||||
cameraError: (message: string) => void,
|
||||
cameraOptions?: CameraOptions): void;
|
||||
// Next will work only on iOS
|
||||
//getPicture(
|
||||
// cameraSuccess: (data: string) => void,
|
||||
// cameraError: (message: string) => void,
|
||||
// cameraOptions?: CameraOptions): CameraPopoverHandle;
|
||||
}
|
||||
|
||||
interface CameraOptions {
|
||||
@@ -58,7 +53,7 @@ interface CameraOptions {
|
||||
* Defined in navigator.camera.PictureSourceType. Default is CAMERA.
|
||||
* PHOTOLIBRARY : 0,
|
||||
* CAMERA : 1,
|
||||
* SAVEDPHOTOALBUM : 2
|
||||
* SAVEDPHOTOALBUM : 2 // same as PHOTOLIBRARY, kept for backward compatibility
|
||||
*/
|
||||
sourceType?: number;
|
||||
/** Allow simple editing of image before selection. */
|
||||
@@ -100,46 +95,6 @@ interface CameraOptions {
|
||||
* BACK: 1
|
||||
*/
|
||||
cameraDirection?: number;
|
||||
/** iOS-only options that specify popover location in iPad. Defined in CameraPopoverOptions. */
|
||||
popoverOptions?: CameraPopoverOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* A handle to the popover dialog created by navigator.camera.getPicture. Used on iOS only.
|
||||
*/
|
||||
interface CameraPopoverHandle {
|
||||
/**
|
||||
* Set the position of the popover.
|
||||
* @param popoverOptions the CameraPopoverOptions that specify the new position.
|
||||
*/
|
||||
setPosition(popoverOptions: CameraPopoverOptions): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* iOS-only parameters that specify the anchor element location and arrow direction
|
||||
* of the popover when selecting images from an iPad's library or album.
|
||||
*/
|
||||
interface CameraPopoverOptions {
|
||||
x: number;
|
||||
y: number;
|
||||
width: number;
|
||||
height: number;
|
||||
/**
|
||||
* Direction the arrow on the popover should point. Defined in Camera.PopoverArrowDirection
|
||||
* Matches iOS UIPopoverArrowDirection constants.
|
||||
* ARROW_UP : 1,
|
||||
* ARROW_DOWN : 2,
|
||||
* ARROW_LEFT : 4,
|
||||
* ARROW_RIGHT : 8,
|
||||
* ARROW_ANY : 15
|
||||
*/
|
||||
arrowDir : number;
|
||||
popoverWidth: number;
|
||||
popoverHeight: number;
|
||||
}
|
||||
|
||||
declare class CameraPopoverOptions implements CameraPopoverOptions {
|
||||
constructor(x?: number, y?: number, width?: number, height?: number, arrowDir?: number);
|
||||
}
|
||||
|
||||
declare var Camera: {
|
||||
@@ -166,12 +121,4 @@ declare var Camera: {
|
||||
CAMERA: number;
|
||||
SAVEDPHOTOALBUM: number;
|
||||
}
|
||||
// Used only on iOS
|
||||
PopoverArrowDirection: {
|
||||
ARROW_UP: number;
|
||||
ARROW_DOWN: number;
|
||||
ARROW_LEFT: number;
|
||||
ARROW_RIGHT: number;
|
||||
ARROW_ANY: number;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -22,8 +22,6 @@
|
||||
const argscheck = require('cordova/argscheck');
|
||||
const exec = require('cordova/exec');
|
||||
const Camera = require('./Camera');
|
||||
// XXX: commented out
|
||||
// CameraPopoverHandle = require('./CameraPopoverHandle');
|
||||
|
||||
/**
|
||||
* @namespace navigator
|
||||
@@ -73,7 +71,6 @@ for (const key in Camera) {
|
||||
* @property {module:Camera.MediaType} [mediaType=PICTURE] - Set the type of media to select from. Only works when `PictureSourceType` is `PHOTOLIBRARY` or `SAVEDPHOTOALBUM`.
|
||||
* @property {Boolean} [correctOrientation] - Rotate the image to correct for the orientation of the device during capture.
|
||||
* @property {Boolean} [saveToPhotoAlbum] - Save the image to the photo album on the device after capture.
|
||||
* @property {module:CameraPopoverOptions} [popoverOptions] - iOS-only options that specify popover location in iPad.
|
||||
* @property {module:Camera.Direction} [cameraDirection=BACK] - Choose the camera to use (front- or back-facing).
|
||||
*/
|
||||
|
||||
@@ -140,7 +137,6 @@ cameraExport.getPicture = function (successCallback, errorCallback, options) {
|
||||
const allowEdit = !!options.allowEdit;
|
||||
const correctOrientation = !!options.correctOrientation;
|
||||
const saveToPhotoAlbum = !!options.saveToPhotoAlbum;
|
||||
const popoverOptions = getValue(options.popoverOptions, null);
|
||||
const cameraDirection = getValue(options.cameraDirection, Camera.Direction.BACK);
|
||||
|
||||
if (allowEdit) {
|
||||
@@ -148,11 +144,9 @@ cameraExport.getPicture = function (successCallback, errorCallback, options) {
|
||||
}
|
||||
|
||||
const args = [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType,
|
||||
mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions, cameraDirection];
|
||||
mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, cameraDirection];
|
||||
|
||||
exec(successCallback, errorCallback, 'Camera', 'takePicture', args);
|
||||
// XXX: commented out
|
||||
// return new CameraPopoverHandle();
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -62,24 +62,19 @@ module.exports = {
|
||||
* @enum {number}
|
||||
*/
|
||||
PictureSourceType: {
|
||||
/** Choose image from the device's photo library (same as SAVEDPHOTOALBUM for Android) */
|
||||
/**
|
||||
* Choose image from the device's photo library.
|
||||
**/
|
||||
PHOTOLIBRARY: 0,
|
||||
/** Take picture from camera */
|
||||
CAMERA: 1,
|
||||
/** Choose image only from the device's Camera Roll album (same as PHOTOLIBRARY for Android) */
|
||||
/**
|
||||
* Same as PHOTOLIBRARY, when running on Android, or iOS 14+.
|
||||
* On iOS older than 14, an image can only be chosen from the device's Camera Roll album
|
||||
* with this setting.
|
||||
**/
|
||||
SAVEDPHOTOALBUM: 2
|
||||
},
|
||||
/**
|
||||
* Matches iOS UIPopoverArrowDirection constants to specify arrow location on popover.
|
||||
* @enum {number}
|
||||
*/
|
||||
PopoverArrowDirection: {
|
||||
ARROW_UP: 1,
|
||||
ARROW_DOWN: 2,
|
||||
ARROW_LEFT: 4,
|
||||
ARROW_RIGHT: 8,
|
||||
ARROW_ANY: 15
|
||||
},
|
||||
/**
|
||||
* @enum {number}
|
||||
*/
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore in favour of iOS' one
|
||||
* A handle to an image picker popover.
|
||||
*/
|
||||
const CameraPopoverHandle = function () {
|
||||
this.setPosition = function (popoverOptions) {
|
||||
console.log('CameraPopoverHandle.setPosition is only supported on iOS.');
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = CameraPopoverHandle;
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
const Camera = require('./Camera');
|
||||
|
||||
/**
|
||||
* @namespace navigator
|
||||
*/
|
||||
|
||||
/**
|
||||
* iOS-only parameters that specify the anchor element location and arrow
|
||||
* direction of the popover when selecting images from an iPad's library
|
||||
* or album.
|
||||
* Note that the size of the popover may change to adjust to the
|
||||
* direction of the arrow and orientation of the screen. Make sure to
|
||||
* account for orientation changes when specifying the anchor element
|
||||
* location.
|
||||
* @module CameraPopoverOptions
|
||||
* @param {Number} [x=0] - x pixel coordinate of screen element onto which to anchor the popover.
|
||||
* @param {Number} [y=32] - y pixel coordinate of screen element onto which to anchor the popover.
|
||||
* @param {Number} [width=320] - width, in pixels, of the screen element onto which to anchor the popover.
|
||||
* @param {Number} [height=480] - height, in pixels, of the screen element onto which to anchor the popover.
|
||||
* @param {module:Camera.PopoverArrowDirection} [arrowDir=ARROW_ANY] - Direction the arrow on the popover should point.
|
||||
* @param {Number} [popoverWidth=0] - width of the popover (0 or not specified will use apple's default width).
|
||||
* @param {Number} [popoverHeight=0] - height of the popover (0 or not specified will use apple's default height).
|
||||
*/
|
||||
const CameraPopoverOptions = function (x, y, width, height, arrowDir, popoverWidth, popoverHeight) {
|
||||
// information of rectangle that popover should be anchored to
|
||||
this.x = x || 0;
|
||||
this.y = y || 32;
|
||||
this.width = width || 320;
|
||||
this.height = height || 480;
|
||||
this.arrowDir = arrowDir || Camera.PopoverArrowDirection.ARROW_ANY;
|
||||
this.popoverWidth = popoverWidth || 0;
|
||||
this.popoverHeight = popoverHeight || 0;
|
||||
};
|
||||
|
||||
module.exports = CameraPopoverOptions;
|
||||
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
const exec = require('cordova/exec');
|
||||
|
||||
/**
|
||||
* @namespace navigator
|
||||
*/
|
||||
|
||||
/**
|
||||
* A handle to an image picker popover.
|
||||
*
|
||||
* __Supported Platforms__
|
||||
*
|
||||
* - iOS
|
||||
*
|
||||
* @example
|
||||
* navigator.camera.getPicture(onSuccess, onFail,
|
||||
* {
|
||||
* destinationType: Camera.DestinationType.FILE_URI,
|
||||
* sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
|
||||
* popoverOptions: new CameraPopoverOptions(300, 300, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY, 300, 600)
|
||||
* });
|
||||
*
|
||||
* // Reposition the popover if the orientation changes.
|
||||
* window.onorientationchange = function() {
|
||||
* var cameraPopoverHandle = new CameraPopoverHandle();
|
||||
* var cameraPopoverOptions = new CameraPopoverOptions(0, 0, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY, 400, 500);
|
||||
* cameraPopoverHandle.setPosition(cameraPopoverOptions);
|
||||
* }
|
||||
* @module CameraPopoverHandle
|
||||
*/
|
||||
const CameraPopoverHandle = function () {
|
||||
/**
|
||||
* Can be used to reposition the image selection dialog,
|
||||
* for example, when the device orientation changes.
|
||||
* @memberof CameraPopoverHandle
|
||||
* @instance
|
||||
* @method setPosition
|
||||
* @param {module:CameraPopoverOptions} popoverOptions
|
||||
*/
|
||||
this.setPosition = function (popoverOptions) {
|
||||
const args = [popoverOptions];
|
||||
exec(null, null, 'Camera', 'repositionPopover', args);
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = CameraPopoverHandle;
|
||||
Reference in New Issue
Block a user