mirror of
https://github.com/apache/cordova-plugin-camera.git
synced 2026-02-03 00:06:46 +08:00
Compare commits
81 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9eba35e2f6 | ||
|
|
8b83171ee2 | ||
|
|
c9e6a9a38a | ||
|
|
cc48945f37 | ||
|
|
8b3410bcc6 | ||
|
|
485a11e0f4 | ||
|
|
2d47a26271 | ||
|
|
2d2352f695 | ||
|
|
2f003d2b49 | ||
|
|
3a90bb7d55 | ||
|
|
b13cbdeb16 | ||
|
|
ee192d94b4 | ||
|
|
d9eb83bcb9 | ||
|
|
84f96c1067 | ||
|
|
61064ae3ed | ||
|
|
9ec8aea073 | ||
|
|
9db952e161 | ||
|
|
06d609cfa4 | ||
|
|
cc1076d3cb | ||
|
|
48d4213b2d | ||
|
|
9b566d3f0b | ||
|
|
b63a0d83e0 | ||
|
|
9fe94479e2 | ||
|
|
2f89666db7 | ||
|
|
f8682b9162 | ||
|
|
0ed6406864 | ||
|
|
fa58e83fca | ||
|
|
a3af38ad5b | ||
|
|
c98607c613 | ||
|
|
b89645c749 | ||
|
|
1beeafb6e8 | ||
|
|
7813ad9bef | ||
|
|
6e19147b09 | ||
|
|
9f159d757a | ||
|
|
62d1b01e81 | ||
|
|
92d67d990d | ||
|
|
0accbf560b | ||
|
|
e588907ac7 | ||
|
|
3ed3d887ca | ||
|
|
f010394af8 | ||
|
|
00e0a7dc46 | ||
|
|
fee72c7c04 | ||
|
|
5807458a1d | ||
|
|
c13e9f327b | ||
|
|
7e8fe0bae9 | ||
|
|
3f8c53f7f3 | ||
|
|
4e439d85c3 | ||
|
|
b62fdf50f7 | ||
|
|
744d72a33b | ||
|
|
3d26986bfd | ||
|
|
fed798e6c7 | ||
|
|
2027d69606 | ||
|
|
7129fb2c12 | ||
|
|
b695717240 | ||
|
|
acff98058f | ||
|
|
8a7326969f | ||
|
|
a05f169984 | ||
|
|
dcc81bfbe1 | ||
|
|
278b527702 | ||
|
|
d7ca7edf88 | ||
|
|
f283502545 | ||
|
|
a831e15a91 | ||
|
|
3586ea58a2 | ||
|
|
cc840b6cef | ||
|
|
0115458ce8 | ||
|
|
2eef096861 | ||
|
|
cf35b1bb2a | ||
|
|
39bff2f41d | ||
|
|
7551778e13 | ||
|
|
e3a431cbeb | ||
|
|
832d6e3bea | ||
|
|
2a7469e065 | ||
|
|
af98d57417 | ||
|
|
57b177f3fb | ||
|
|
f2b4eeded0 | ||
|
|
d4a55f20ec | ||
|
|
68e18a97d1 | ||
|
|
bfaef0ff25 | ||
|
|
0ba547cd3c | ||
|
|
6d058fe9e7 | ||
|
|
daf5fa48dd |
22
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
22
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<!--
|
||||
Please make sure the checklist boxes are all checked before submitting the PR. The checklist
|
||||
is intended as a quick reference, for complete details please see our Contributor Guidelines:
|
||||
|
||||
http://cordova.apache.org/contribute/contribute_guidelines.html
|
||||
|
||||
Thanks!
|
||||
-->
|
||||
|
||||
### Platforms affected
|
||||
|
||||
|
||||
### What does this PR do?
|
||||
|
||||
|
||||
### What testing has been done on this change?
|
||||
|
||||
|
||||
### Checklist
|
||||
- [ ] [Reported an issue](http://cordova.apache.org/contribute/issues.html) in the JIRA database
|
||||
- [ ] Commit message follows the format: "CB-3232: (android) Fix bug with resolving file paths", where CB-xxxx is the JIRA ID & "android" is the platform affected.
|
||||
- [ ] Added automated test coverage as appropriate for this change.
|
||||
313
README.md
313
README.md
@@ -1,3 +1,7 @@
|
||||
---
|
||||
title: Camera
|
||||
description: Take pictures with the device camera.
|
||||
---
|
||||
<!---
|
||||
# license: Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
@@ -17,7 +21,9 @@
|
||||
# under the License.
|
||||
-->
|
||||
|
||||
[](https://travis-ci.org/apache/cordova-plugin-camera)
|
||||
|Android|iOS| Windows 8.1 Store | Windows 8.1 Phone | Windows 10 Store | Travis CI |
|
||||
|:-:|:-:|:-:|:-:|:-:|:-:|
|
||||
|[](http://cordova-ci.cloudapp.net:8080/job/cordova-periodic-build/PLATFORM=android,PLUGIN=cordova-plugin-camera/)|[](http://cordova-ci.cloudapp.net:8080/job/cordova-periodic-build/PLATFORM=ios,PLUGIN=cordova-plugin-camera/)|[](http://cordova-ci.cloudapp.net:8080/job/cordova-periodic-build/PLATFORM=windows-8.1-store,PLUGIN=cordova-plugin-camera/)|[](http://cordova-ci.cloudapp.net:8080/job/cordova-periodic-build/PLATFORM=windows-8.1-phone,PLUGIN=cordova-plugin-camera/)|[](http://cordova-ci.cloudapp.net:8080/job/cordova-periodic-build/PLATFORM=windows-10-store,PLUGIN=cordova-plugin-camera/)|[](https://travis-ci.org/apache/cordova-plugin-camera)
|
||||
|
||||
# cordova-plugin-camera
|
||||
|
||||
@@ -67,26 +73,47 @@ In order for your changes to be accepted, you need to sign and submit an Apache
|
||||
Documentation consists of template and API docs produced from the plugin JS code and should be regenerated before each commit (done automatically via [husky](https://github.com/typicode/husky), running `npm run gen-docs` script as a `precommit` hook - see `package.json` for details).
|
||||
|
||||
|
||||
|
||||
### iOS Quirks
|
||||
|
||||
Since iOS 10 it's mandatory to add a `NSCameraUsageDescription` and `NSPhotoLibraryUsageDescription` in the info.plist.
|
||||
|
||||
- `NSCameraUsageDescription` describes the reason that the app accesses the user’s camera.
|
||||
- `NSPhotoLibraryUsageDescription` describes the reason the app accesses the user's photo library.
|
||||
|
||||
When the system prompts the user to allow access, this string is displayed as part of the dialog box.
|
||||
|
||||
To add this entry you can pass the following variables on plugin install.
|
||||
|
||||
- `CAMERA_USAGE_DESCRIPTION` for `NSCameraUsageDescription`
|
||||
- `PHOTOLIBRARY_USAGE_DESCRIPTION` for `NSPhotoLibraryUsageDescription`
|
||||
|
||||
Example:
|
||||
|
||||
cordova plugin add cordova-plugin-camera --variable CAMERA_USAGE_DESCRIPTION="your usage message" --variable PHOTOLIBRARY_USAGE_DESCRIPTION="your usage message"
|
||||
|
||||
If you don't pass the variable, the plugin will add an empty string as value.
|
||||
|
||||
---
|
||||
|
||||
# API Reference
|
||||
# API Reference <a name="reference"></a>
|
||||
|
||||
|
||||
* [camera](#module_camera)
|
||||
* [.getPicture(successCallback, errorCallback, options)](#module_camera.getPicture)
|
||||
* [.cleanup()](#module_camera.cleanup)
|
||||
* [.onError](#module_camera.onError) : <code>function</code>
|
||||
* [.onSuccess](#module_camera.onSuccess) : <code>function</code>
|
||||
* [.CameraOptions](#module_camera.CameraOptions) : <code>Object</code>
|
||||
* [.getPicture(successCallback, errorCallback, options)](#module_camera.getPicture)
|
||||
* [.cleanup()](#module_camera.cleanup)
|
||||
* [.onError](#module_camera.onError) : <code>function</code>
|
||||
* [.onSuccess](#module_camera.onSuccess) : <code>function</code>
|
||||
* [.CameraOptions](#module_camera.CameraOptions) : <code>Object</code>
|
||||
|
||||
|
||||
* [Camera](#module_Camera)
|
||||
* [.DestinationType](#module_Camera.DestinationType) : <code>enum</code>
|
||||
* [.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>
|
||||
* [.DestinationType](#module_Camera.DestinationType) : <code>enum</code>
|
||||
* [.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)
|
||||
@@ -94,8 +121,10 @@ Documentation consists of template and API docs produced from the plugin JS code
|
||||
---
|
||||
|
||||
<a name="module_camera"></a>
|
||||
|
||||
## camera
|
||||
<a name="module_camera.getPicture"></a>
|
||||
|
||||
### camera.getPicture(successCallback, errorCallback, options)
|
||||
Takes a photo using the camera, or retrieves a photo from the device's
|
||||
image gallery. The image is passed to the success callback as a
|
||||
@@ -108,26 +137,20 @@ Once the user snaps the photo, the camera application closes and the application
|
||||
|
||||
If `Camera.sourceType` is `Camera.PictureSourceType.PHOTOLIBRARY` or
|
||||
`Camera.PictureSourceType.SAVEDPHOTOALBUM`, then a dialog displays
|
||||
that allows users to select an existing image. The
|
||||
`camera.getPicture` function returns a [`CameraPopoverHandle`](#module_CameraPopoverHandle) object,
|
||||
which can be used to reposition the image selection dialog, for
|
||||
example, when the device orientation changes.
|
||||
that allows users to select an existing image.
|
||||
|
||||
The return value is sent to the [`cameraSuccess`](#module_camera.onSuccess) callback function, in
|
||||
one of the following formats, depending on the specified
|
||||
`cameraOptions`:
|
||||
|
||||
- A `String` containing the Base64-encoded photo image.
|
||||
|
||||
- A `String` representing the image file location on local storage (default).
|
||||
|
||||
You can do whatever you want with the encoded image or URI, for
|
||||
example:
|
||||
|
||||
- Render the image in an `<img>` tag, as in the example below
|
||||
|
||||
- Save the data locally (`LocalStorage`, [Lawnchair](http://brianleroux.github.com/lawnchair/), etc.)
|
||||
|
||||
- Post the data to a remote server
|
||||
|
||||
__NOTE__: Photo resolution on newer devices is quite good. Photos
|
||||
@@ -163,6 +186,7 @@ More examples [here](#camera-getPicture-examples). Quirks [here](#camera-getPict
|
||||
navigator.camera.getPicture(cameraSuccess, cameraError, cameraOptions);
|
||||
```
|
||||
<a name="module_camera.cleanup"></a>
|
||||
|
||||
### camera.cleanup()
|
||||
Removes intermediate image files that are kept in temporary storage
|
||||
after calling [`camera.getPicture`](#module_camera.getPicture). Applies only when the value of
|
||||
@@ -187,6 +211,7 @@ function onFail(message) {
|
||||
}
|
||||
```
|
||||
<a name="module_camera.onError"></a>
|
||||
|
||||
### camera.onError : <code>function</code>
|
||||
Callback function that provides an error message.
|
||||
|
||||
@@ -197,6 +222,7 @@ Callback function that provides an error message.
|
||||
| message | <code>string</code> | The message is provided by the device's native code. |
|
||||
|
||||
<a name="module_camera.onSuccess"></a>
|
||||
|
||||
### camera.onSuccess : <code>function</code>
|
||||
Callback function that provides the image data.
|
||||
|
||||
@@ -216,6 +242,7 @@ function cameraCallback(imageData) {
|
||||
}
|
||||
```
|
||||
<a name="module_camera.CameraOptions"></a>
|
||||
|
||||
### camera.CameraOptions : <code>Object</code>
|
||||
Optional parameters to customize the camera settings.
|
||||
* [Quirks](#CameraOptions-quirks)
|
||||
@@ -241,9 +268,17 @@ Optional parameters to customize the camera settings.
|
||||
---
|
||||
|
||||
<a name="module_Camera"></a>
|
||||
|
||||
## Camera
|
||||
<a name="module_Camera.DestinationType"></a>
|
||||
|
||||
### Camera.DestinationType : <code>enum</code>
|
||||
Defines the output format of `Camera.getPicture` call.
|
||||
_Note:_ On iOS passing `DestinationType.NATIVE_URI` along with
|
||||
`PictureSourceType.PHOTOLIBRARY` or `PictureSourceType.SAVEDPHOTOALBUM` will
|
||||
disable any image modifications (resize, quality change, cropping, etc.) due
|
||||
to implementation specific.
|
||||
|
||||
**Kind**: static enum property of <code>[Camera](#module_Camera)</code>
|
||||
**Properties**
|
||||
|
||||
@@ -254,6 +289,7 @@ Optional parameters to customize the camera settings.
|
||||
| NATIVE_URI | <code>number</code> | <code>2</code> | Return native uri (eg. asset-library://... for iOS) |
|
||||
|
||||
<a name="module_Camera.EncodingType"></a>
|
||||
|
||||
### Camera.EncodingType : <code>enum</code>
|
||||
**Kind**: static enum property of <code>[Camera](#module_Camera)</code>
|
||||
**Properties**
|
||||
@@ -264,6 +300,7 @@ Optional parameters to customize the camera settings.
|
||||
| PNG | <code>number</code> | <code>1</code> | Return PNG encoded image |
|
||||
|
||||
<a name="module_Camera.MediaType"></a>
|
||||
|
||||
### Camera.MediaType : <code>enum</code>
|
||||
**Kind**: static enum property of <code>[Camera](#module_Camera)</code>
|
||||
**Properties**
|
||||
@@ -275,17 +312,24 @@ Optional parameters to customize the camera settings.
|
||||
| ALLMEDIA | <code>number</code> | <code>2</code> | Allow selection from all media types |
|
||||
|
||||
<a name="module_Camera.PictureSourceType"></a>
|
||||
|
||||
### Camera.PictureSourceType : <code>enum</code>
|
||||
Defines the output format of `Camera.getPicture` call.
|
||||
_Note:_ On iOS passing `PictureSourceType.PHOTOLIBRARY` or `PictureSourceType.SAVEDPHOTOALBUM`
|
||||
along with `DestinationType.NATIVE_URI` will disable any image modifications (resize, quality
|
||||
change, cropping, etc.) due to implementation specific.
|
||||
|
||||
**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 picture library (same as SAVEDPHOTOALBUM for Android) |
|
||||
| PHOTOLIBRARY | <code>number</code> | <code>0</code> | Choose image from the device's photo library (same as SAVEDPHOTOALBUM for Android) |
|
||||
| CAMERA | <code>number</code> | <code>1</code> | Take picture from camera |
|
||||
| SAVEDPHOTOALBUM | <code>number</code> | <code>2</code> | Choose image from picture library (same as PHOTOLIBRARY for Android) |
|
||||
| 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.
|
||||
|
||||
@@ -301,6 +345,7 @@ Matches iOS UIPopoverArrowDirection constants to specify arrow location on popov
|
||||
| ARROW_ANY | <code>number</code> | <code>15</code> |
|
||||
|
||||
<a name="module_Camera.Direction"></a>
|
||||
|
||||
### Camera.Direction : <code>enum</code>
|
||||
**Kind**: static enum property of <code>[Camera](#module_Camera)</code>
|
||||
**Properties**
|
||||
@@ -313,8 +358,15 @@ 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
|
||||
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 |
|
||||
@@ -328,6 +380,7 @@ iOS-only parameters that specify the anchor element location and arrow
direction
|
||||
---
|
||||
|
||||
<a name="module_CameraPopoverHandle"></a>
|
||||
|
||||
## CameraPopoverHandle
|
||||
A handle to an image picker popover.
|
||||
|
||||
@@ -337,7 +390,7 @@ __Supported Platforms__
|
||||
|
||||
**Example**
|
||||
```js
|
||||
__Supported Platforms__
|
||||
navigator.camera.getPicture(onSuccess, onFail,
|
||||
{
|
||||
destinationType: Camera.DestinationType.FILE_URI,
|
||||
sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
|
||||
@@ -346,6 +399,7 @@ var cameraPopoverHandle = navigator.camera.getPicture(onSuccess, onFail,
|
||||
|
||||
// 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);
|
||||
cameraPopoverHandle.setPosition(cameraPopoverOptions);
|
||||
}
|
||||
@@ -439,6 +493,16 @@ displays:
|
||||
Invoking the native camera application while the device is connected
|
||||
via Zune does not work, and triggers an error callback.
|
||||
|
||||
#### Windows quirks
|
||||
|
||||
On Windows Phone 8.1 using `SAVEDPHOTOALBUM` or `PHOTOLIBRARY` as a source type causes application to suspend until file picker returns the selected image and
|
||||
then restore with start page as defined in app's `config.xml`. In case when `camera.getPicture` was called from different page, this will lead to reloading
|
||||
start page from scratch and success and error callbacks will never be called.
|
||||
|
||||
To avoid this we suggest using SPA pattern or call `camera.getPicture` only from your app's start page.
|
||||
|
||||
More information about Windows Phone 8.1 picker APIs is here: [How to continue your Windows Phone app after calling a file picker](https://msdn.microsoft.com/en-us/library/windows/apps/dn720490.aspx)
|
||||
|
||||
#### Tizen Quirks
|
||||
|
||||
Tizen only supports a `destinationType` of
|
||||
@@ -504,6 +568,8 @@ Tizen only supports a `destinationType` of
|
||||
|
||||
- When using `destinationType.NATIVE_URI` and `sourceType.CAMERA`, photos are saved in the saved photo album regardless on the value of `saveToPhotoAlbum` parameter.
|
||||
|
||||
- When using `destinationType.NATIVE_URI` and `sourceType.PHOTOLIBRARY` or `sourceType.SAVEDPHOTOALBUM`, all editing options are ignored and link is returned to original picture.
|
||||
|
||||
#### Tizen Quirks
|
||||
|
||||
- options not supported
|
||||
@@ -526,3 +592,202 @@ Tizen only supports a `destinationType` of
|
||||
[web_activities]: https://hacks.mozilla.org/2013/01/introducing-web-activities/
|
||||
[wp8_bug]: https://issues.apache.org/jira/browse/CB-2083
|
||||
[msdn_wp8_docs]: http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh394006.aspx
|
||||
|
||||
## Sample: Take Pictures, Select Pictures from the Picture Library, and Get Thumbnails <a name="sample"></a>
|
||||
|
||||
The Camera plugin allows you to do things like open the device's Camera app and take a picture, or open the file picker and select one. The code snippets in this section demonstrate different tasks including:
|
||||
|
||||
* Open the Camera app and [take a Picture](#takePicture)
|
||||
* Take a picture and [return thumbnails](#getThumbnails) (resized picture)
|
||||
* Take a picture and [generate a FileEntry object](#convert)
|
||||
* [Select a file](#selectFile) from the picture library
|
||||
* Select a JPEG image and [return thumbnails](#getFileThumbnails) (resized image)
|
||||
* Select an image and [generate a FileEntry object](#convert)
|
||||
|
||||
## Take a Picture <a name="takePicture"></a>
|
||||
|
||||
Before you can take a picture, you need to set some Camera plugin options to pass into the Camera plugin's `getPicture` function. Here is a common set of recommendations. In this example, you create the object that you will use for the Camera options, and set the `sourceType` dynamically to support both the Camera app and the file picker.
|
||||
|
||||
```js
|
||||
function setOptions(srcType) {
|
||||
var options = {
|
||||
// Some common settings are 20, 50, and 100
|
||||
quality: 50,
|
||||
destinationType: Camera.DestinationType.FILE_URI,
|
||||
// In this app, dynamically set the picture source, Camera or photo gallery
|
||||
sourceType: srcType,
|
||||
encodingType: Camera.EncodingType.JPEG,
|
||||
mediaType: Camera.MediaType.PICTURE,
|
||||
allowEdit: true,
|
||||
correctOrientation: true //Corrects Android orientation quirks
|
||||
}
|
||||
return options;
|
||||
}
|
||||
```
|
||||
|
||||
Typically, you want to use a FILE_URI instead of a DATA_URL to avoid most memory issues. JPEG is the recommended encoding type for Android.
|
||||
|
||||
You take a picture by passing in the options object to `getPicture`, which takes a CameraOptions object as the third argument. When you call `setOptions`, pass `Camera.PictureSourceType.CAMERA` as the picture source.
|
||||
|
||||
```js
|
||||
function openCamera(selection) {
|
||||
|
||||
var srcType = Camera.PictureSourceType.CAMERA;
|
||||
var options = setOptions(srcType);
|
||||
var func = createNewFileEntry;
|
||||
|
||||
navigator.camera.getPicture(function cameraSuccess(imageUri) {
|
||||
|
||||
displayImage(imageUri);
|
||||
// You may choose to copy the picture, save it somewhere, or upload.
|
||||
func(imageUri);
|
||||
|
||||
}, function cameraError(error) {
|
||||
console.debug("Unable to obtain picture: " + error, "app");
|
||||
|
||||
}, options);
|
||||
}
|
||||
```
|
||||
|
||||
Once you take the picture, you can display it or do something else. In this example, call the app's `displayImage` function from the preceding code.
|
||||
|
||||
```js
|
||||
function displayImage(imgUri) {
|
||||
|
||||
var elem = document.getElementById('imageFile');
|
||||
elem.src = imgUri;
|
||||
}
|
||||
```
|
||||
|
||||
To display the image on some platforms, you might need to include the main part of the URI in the Content-Security-Policy `<meta>` element in index.html. For example, on Windows 10, you can include `ms-appdata:` in your `<meta>` element. Here is an example.
|
||||
|
||||
```html
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: ms-appdata: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *">
|
||||
```
|
||||
|
||||
## Take a Picture and Return Thumbnails (Resize the Picture) <a name="getThumbnails"></a>
|
||||
|
||||
To get smaller images, you can return a resized image by passing both `targetHeight` and `targetWidth` values with your CameraOptions object. In this example, you resize the returned image to fit in a 100px by 100px box (the aspect ratio is maintained, so 100px is either the height or width, whichever is greater in the source).
|
||||
|
||||
```js
|
||||
function openCamera(selection) {
|
||||
|
||||
var srcType = Camera.PictureSourceType.CAMERA;
|
||||
var options = setOptions(srcType);
|
||||
var func = createNewFileEntry;
|
||||
|
||||
if (selection == "camera-thmb") {
|
||||
options.targetHeight = 100;
|
||||
options.targetWidth = 100;
|
||||
}
|
||||
|
||||
navigator.camera.getPicture(function cameraSuccess(imageUri) {
|
||||
|
||||
// Do something
|
||||
|
||||
}, function cameraError(error) {
|
||||
console.debug("Unable to obtain picture: " + error, "app");
|
||||
|
||||
}, options);
|
||||
}
|
||||
```
|
||||
|
||||
## 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.
|
||||
|
||||
```js
|
||||
function openFilePicker(selection) {
|
||||
|
||||
var srcType = Camera.PictureSourceType.SAVEDPHOTOALBUM;
|
||||
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);
|
||||
}
|
||||
```
|
||||
|
||||
## Select an Image and Return Thumbnails (resized images) <a name="getFileThumbnails"></a>
|
||||
|
||||
Resizing a file selected with the file picker works just like resizing using the Camera app; set the `targetHeight` and `targetWidth` options.
|
||||
|
||||
```js
|
||||
function openFilePicker(selection) {
|
||||
|
||||
var srcType = Camera.PictureSourceType.SAVEDPHOTOALBUM;
|
||||
var options = setOptions(srcType);
|
||||
var func = createNewFileEntry;
|
||||
|
||||
if (selection == "picker-thmb") {
|
||||
// To downscale a selected image,
|
||||
// Camera.EncodingType (e.g., JPEG) must match the selected image type.
|
||||
options.targetHeight = 100;
|
||||
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);
|
||||
}
|
||||
```
|
||||
|
||||
## Take a picture and get a FileEntry Object <a name="convert"></a>
|
||||
|
||||
If you want to do something like copy the image to another location, or upload it somewhere using the FileTransfer plugin, you need to get a FileEntry object for the returned picture. To do that, call `window.resolveLocalFileSystemURL` on the file URI returned by the Camera app. If you need to use a FileEntry object, set the `destinationType` to `Camera.DestinationType.FILE_URI` in your CameraOptions object (this is also the default value).
|
||||
|
||||
>*Note* You need the [File plugin](https://www.npmjs.com/package/cordova-plugin-file) to call `window.resolveLocalFileSystemURL`.
|
||||
|
||||
Here is the call to `window.resolveLocalFileSystemURL`. The image URI is passed to this function from the success callback of `getPicture`. The success handler of `resolveLocalFileSystemURL` receives the FileEntry object.
|
||||
|
||||
```js
|
||||
function getFileEntry(imgUri) {
|
||||
window.resolveLocalFileSystemURL(imgUri, function success(fileEntry) {
|
||||
|
||||
// Do something with the FileEntry object, like write to it, upload it, etc.
|
||||
// writeFile(fileEntry, imgUri);
|
||||
console.log("got file: " + fileEntry.fullPath);
|
||||
// displayFileData(fileEntry.nativeURL, "Native URL");
|
||||
|
||||
}, function () {
|
||||
// If don't get the FileEntry (which may happen when testing
|
||||
// on some emulators), copy to a new FileEntry.
|
||||
createNewFileEntry(imgUri);
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
In the example shown in the preceding code, you call the app's `createNewFileEntry` function if you don't get a valid FileEntry object. The image URI returned from the Camera app should result in a valid FileEntry, but platform behavior on some emulators may be different for files returned from the file picker.
|
||||
|
||||
>*Note* To see an example of writing to a FileEntry, see the [File plugin README](https://www.npmjs.com/package/cordova-plugin-file).
|
||||
|
||||
The code shown here creates a file in your app's cache (in sandboxed storage) named `tempFile.jpeg`. With the new FileEntry object, you can copy the image to the file or do something else like upload it.
|
||||
|
||||
```js
|
||||
function createNewFileEntry(imgUri) {
|
||||
window.resolveLocalFileSystemURL(cordova.file.cacheDirectory, function success(dirEntry) {
|
||||
|
||||
// JPEG file
|
||||
dirEntry.getFile("tempFile.jpeg", { create: true, exclusive: false }, function (fileEntry) {
|
||||
|
||||
// Do something with it, like write to it, upload it, etc.
|
||||
// writeFile(fileEntry, imgUri);
|
||||
console.log("got file: " + fileEntry.fullPath);
|
||||
// displayFileData(fileEntry.fullPath, "File copied to");
|
||||
|
||||
}, onErrorCreateFile);
|
||||
|
||||
}, onErrorResolveUrl);
|
||||
}
|
||||
```
|
||||
|
||||
486
RELEASENOTES.md
486
RELEASENOTES.md
@@ -20,16 +20,480 @@
|
||||
-->
|
||||
# Release Notes
|
||||
|
||||
### 2.3.1 (Dec 07, 2016)
|
||||
* Fix missing license headers.
|
||||
* [CB-12086](https://issues.apache.org/jira/browse/CB-12086) Regenerate README.md from template
|
||||
* Added NSPhotoLibraryUsageDescription parameter to example install command Fixing some usages of NSPhotoLibraryUsageDescriptionentry
|
||||
* Close #124: I can crop fine with Photos. We should not have adopted Crop, since it makes no sense on Android.
|
||||
* Updating compat dependency to 1.1.0 or better
|
||||
* Close #199. We save photos to a shared Pictures directory, similar to the behaviour of the Twitter application
|
||||
* Close #201. Running out of memory shouldn't be graceful.
|
||||
* Close #228. We don't require these permissions on Camera, since we use intents.
|
||||
* Close #241
|
||||
* Bumping the CI
|
||||
* [CB-11625](https://issues.apache.org/jira/browse/CB-11625) Forgot to add CordovaUri.java to plugin.xml
|
||||
* [CB-11625](https://issues.apache.org/jira/browse/CB-11625) Files Provider does not work with Android 4.4.4 or lower, and I have no idea why. Working around with CordovaUri
|
||||
* [CB-11625](https://issues.apache.org/jira/browse/CB-11625) (Android) : Make this work with previous versions of Cordova via cordova-plugin-compat
|
||||
* BuildConfig from test project crept in source code thanks to Android Studio, removing
|
||||
* WTF. Directory, not file. Not sure why I did that
|
||||
* [CB-11625](https://issues.apache.org/jira/browse/CB-11625) Managed to get Content Providers to work with a weird mix of Content Providers and non-Content Providers
|
||||
* Adding provider_paths.xml so this works
|
||||
* Partially modified plugin.xml
|
||||
* [CB-11625](https://issues.apache.org/jira/browse/CB-11625) Working on fix to API 24 no longer allowing File URIs to be passed across intents
|
||||
* [CB-11917](https://issues.apache.org/jira/browse/CB-11917) - Remove pull request template checklist item: "iCLA has been submitted…"
|
||||
* Closing invalid pull request: close #98
|
||||
* [CB-11832](https://issues.apache.org/jira/browse/CB-11832) Incremented plugin version.
|
||||
* [CB-11832](https://issues.apache.org/jira/browse/CB-11832) Updated version and RELEASENOTES.md for release 2.3.0
|
||||
* [CB-11795](https://issues.apache.org/jira/browse/CB-11795) Add 'protective' entry to cordovaDependencies
|
||||
* [CB-11661](https://issues.apache.org/jira/browse/CB-11661) (ios) Add mandatory iOS 10 privacy description
|
||||
* [CB-11661](https://issues.apache.org/jira/browse/CB-11661) (ios) Add mandatory iOS 10 privacy description
|
||||
* Revert "close #229"
|
||||
* Removed unneeded file
|
||||
* close #229
|
||||
* [CB-11661](https://issues.apache.org/jira/browse/CB-11661) (ios) Add mandatory iOS 10 privacy description
|
||||
* [CB-11714](https://issues.apache.org/jira/browse/CB-11714) (windows) added more explicit content-type when converting to target data on canvas
|
||||
* [CB-11295](https://issues.apache.org/jira/browse/CB-11295) Add WP8.1 quirk when choosing image from photoalbum
|
||||
* [CB-10067](https://issues.apache.org/jira/browse/CB-10067) Update PictureSourceType JSDoc to reflect README update
|
||||
* [CB-9070](https://issues.apache.org/jira/browse/CB-9070) Update CameraPopoverHandle docs to reflect README update
|
||||
* Plugin uses Android Log class and not Cordova LOG class
|
||||
* [CB-11631](https://issues.apache.org/jira/browse/CB-11631) Appium tests: A working fix for a flaky "selection canceled" failure
|
||||
* [CB-11709](https://issues.apache.org/jira/browse/CB-11709) Tests should use resolveLocalFileSystemURL() instead of deprecated resolveFileSystemURI()
|
||||
* Closing invalid PR
|
||||
* [CB-11695](https://issues.apache.org/jira/browse/CB-11695) Increased session creation timeout for Appium tests
|
||||
* [CB-11631](https://issues.apache.org/jira/browse/CB-11631) Appium tests: A fix for a flaky "selection cancelled" failure
|
||||
* [CB-11656](https://issues.apache.org/jira/browse/CB-11656) (Android) Appium tests: Fixed side menu opening on some more resolutions
|
||||
* [CB-11656](https://issues.apache.org/jira/browse/CB-11656) (Android) Appium tests: Fixed side menu opening on certain resolutions
|
||||
* [CB-11376](https://issues.apache.org/jira/browse/CB-11376) (ios): fix CameraUsesGeolocation error
|
||||
* [CB-10067](https://issues.apache.org/jira/browse/CB-10067) (ios) clarifications on PictureSourceType
|
||||
* [CB-11410](https://issues.apache.org/jira/browse/CB-11410) (ios) fix cameraPopoverHandle.setPosition
|
||||
* [CB-9070.](https://issues.apache.org/jira/browse/CB-9070.) (ios) Fixed CameraPopoverHandle documentation
|
||||
* [CB-11447](https://issues.apache.org/jira/browse/CB-11447) Respect output format when retrieving images from gallery
|
||||
* [CB-11447](https://issues.apache.org/jira/browse/CB-11447) Resolve iOS tests failures due to iOS quirks
|
||||
* [CB-11553](https://issues.apache.org/jira/browse/CB-11553) Pend failing Appium tests on Sauce Labs for the time being (reverted from commit b69571724035f41642f3ee612c5b66e1f0c4386c)
|
||||
* [CB-11553](https://issues.apache.org/jira/browse/CB-11553) Pend failing Appium tests on Sauce Labs for the time being
|
||||
* [CB-11498](https://issues.apache.org/jira/browse/CB-11498) [Android] Appium tests should not fail when there is no camera
|
||||
* Add badges for paramedic builds on Jenkins
|
||||
* [CB-11296](https://issues.apache.org/jira/browse/CB-11296) Appium: Better element clicking and session error handling
|
||||
* [CB-11232](https://issues.apache.org/jira/browse/CB-11232) Appium tests: fixed element tapping on iOS 9
|
||||
* [CB-11183](https://issues.apache.org/jira/browse/CB-11183) Appium tests: Added image verification
|
||||
* Closing stale PRs. This closes #114, closes #104
|
||||
* Closing stale PRs. This closes #85, closes #93
|
||||
* fixed some bad formatting that hid HTML tags and added link to sample
|
||||
* Closing stale PRs. Close #167
|
||||
* Closing stale PRs. Close #147
|
||||
* Set android quality default value to 50 on the java code
|
||||
* Moving message in PR template to a comment
|
||||
* Add pull request template. This closes #213
|
||||
* [CB-11228](https://issues.apache.org/jira/browse/CB-11228) browser: Add classes for styling purposes
|
||||
* [CB-10139](https://issues.apache.org/jira/browse/CB-10139) browser: Respect target width and height
|
||||
* Stale PRs: closes #149, closes #148, closes #155, closes #107, closes #71, closes #55, closes #14
|
||||
* [CB-11227](https://issues.apache.org/jira/browse/CB-11227) browser: Fix incorrect mime type
|
||||
* [CB-11162](https://issues.apache.org/jira/browse/CB-11162) Appium tests: retry spec on failure
|
||||
* Reverted indenting done by Android Studio
|
||||
* Adding missing function
|
||||
* [CB-4078](https://issues.apache.org/jira/browse/CB-4078) Fix for orientation/scaling on Android 4.4+ devices
|
||||
* [CB-11165](https://issues.apache.org/jira/browse/CB-11165) removed peer dependency
|
||||
* [CB-11147](https://issues.apache.org/jira/browse/CB-11147) Appium tests: generate descriptive spec names
|
||||
* [CB-10996](https://issues.apache.org/jira/browse/CB-10996) Adding front matter to README.md
|
||||
* [CB-11128](https://issues.apache.org/jira/browse/CB-11128) Appum tests: Fixed some of the flaky failures
|
||||
* [CB-11003](https://issues.apache.org/jira/browse/CB-11003) Added Sample section to the Camera plugin README
|
||||
* [CB-11091](https://issues.apache.org/jira/browse/CB-11091) Incremented plugin version.
|
||||
* Updated version and RELEASENOTES.md for release 2.2.0
|
||||
* [CB-10873](https://issues.apache.org/jira/browse/CB-10873) - Avoid crash due to usage of uninitialized variable when writing geolocation data to image destination - Properly handle 'CameraUsesGeolocation' option by properly setting geolocation data in EXIF header in all cases
|
||||
* [CB-10873](https://issues.apache.org/jira/browse/CB-10873) Avoid crash due to usage of uninitialized variable when writing geolocation data to image destination
|
||||
* [CB-11073](https://issues.apache.org/jira/browse/CB-11073) Appium tests stability improvements
|
||||
* Replace PermissionHelper.java with cordova-plugin-compat
|
||||
* Making focus handler work only for windows 10 phone
|
||||
* [CB-10865](https://issues.apache.org/jira/browse/CB-10865) Run ios native tests on Travis
|
||||
* [CB-10120](https://issues.apache.org/jira/browse/CB-10120) android: Fixing use of constants and PermissionHelper
|
||||
* [CB-10120](https://issues.apache.org/jira/browse/CB-10120) android: Fix missing CAMERA permission for Android M
|
||||
* [CB-10756](https://issues.apache.org/jira/browse/CB-10756) Adding sterner warnings about DATA_URL
|
||||
* [CB-10460](https://issues.apache.org/jira/browse/CB-10460) getRealPath return null in some cases
|
||||
* clean RELEASENOTES for bold font
|
||||
* Appium tests: tweaking some timeouts and default screenshot path
|
||||
* [CB-10820](https://issues.apache.org/jira/browse/CB-10820) Incremented plugin version.
|
||||
* [CB-10820](https://issues.apache.org/jira/browse/CB-10820) Updated version and RELEASENOTES.md for release 2.1.1
|
||||
* [CB-10825](https://issues.apache.org/jira/browse/CB-10825) android: Always request READ permission for gallery source
|
||||
* added apache license header to appium files
|
||||
* [CB-10720](https://issues.apache.org/jira/browse/CB-10720) Fixed spelling, capitalization, and other small issues.
|
||||
* [CB-10414](https://issues.apache.org/jira/browse/CB-10414) Adding focus handler to resume video when user comes back on leaving the app while preview was running
|
||||
* Appium tests: adjust swipe distance on Android
|
||||
* [CB-10750](https://issues.apache.org/jira/browse/CB-10750) Appium tests: fail fast if session is irrecoverable
|
||||
* Adding missing semi colon
|
||||
* Adding focus handler to make sure filepicker gets launched when app is active
|
||||
* [CB-10128](https://issues.apache.org/jira/browse/CB-10128) [iOS] Fixed how checks access authorization to camera & library. This closes #146
|
||||
* [CB-10636](https://issues.apache.org/jira/browse/CB-10636) Add JSHint for plugins
|
||||
* [CB-10639](https://issues.apache.org/jira/browse/CB-10639) Appium tests: Added some timeouts, Taking a screenshot on failure, Retry taking a picture up to 3 times, Try to restart the Appium session if it's lost
|
||||
* [CB-10552](https://issues.apache.org/jira/browse/CB-10552) Replacing images in README.md.
|
||||
* Added a lot of more cases to get the real path
|
||||
* Fix for [CB-10625](https://issues.apache.org/jira/browse/CB-10625)
|
||||
* [CB-10619](https://issues.apache.org/jira/browse/CB-10619) Appium tests: Properly switch to webview
|
||||
* [CB-10397](https://issues.apache.org/jira/browse/CB-10397) Added Appium tests
|
||||
* [CB-10576](https://issues.apache.org/jira/browse/CB-10576) MobileSpec can't get results for Windows-Store 8.1 Builds
|
||||
* chore: edit package.json license to match SPDX id
|
||||
* [CB-10539](https://issues.apache.org/jira/browse/CB-10539) Commenting out the verySmallQvga maxResolution option
|
||||
* [CB-10541](https://issues.apache.org/jira/browse/CB-10541) Changing default maxResoltion to be highestAvailable for CameraCaptureUI
|
||||
* [CB-10113](https://issues.apache.org/jira/browse/CB-10113) Browser - Layer camera UI on top of all!
|
||||
* [CB-10502](https://issues.apache.org/jira/browse/CB-10502) Fix camera plugin exception in Chrome when click capture.
|
||||
* Adding comments
|
||||
* Camera tapping fix
|
||||
* [CB-10368](https://issues.apache.org/jira/browse/CB-10368) Incremented plugin version.
|
||||
* [CB-10368](https://issues.apache.org/jira/browse/CB-10368) Updated version and RELEASENOTES.md for release 2.1.0
|
||||
* added .ratignore
|
||||
* [CB-10319](https://issues.apache.org/jira/browse/CB-10319) android: Adding reflective helper methods for permission requests
|
||||
* [CB-9189](https://issues.apache.org/jira/browse/CB-9189) android: Implementing save/restore API to handle Activity destruction
|
||||
* [CB-10241](https://issues.apache.org/jira/browse/CB-10241) - App Crash cause by Camera Plugin ios 7
|
||||
* [CB-10035](https://issues.apache.org/jira/browse/CB-10035) Incremented plugin version.
|
||||
* [CB-8940](https://issues.apache.org/jira/browse/CB-8940) Setting z-index values to maximum for UI buttons. This closes #140.
|
||||
* [CB-10035](https://issues.apache.org/jira/browse/CB-10035) linked issues in RELEASENOTES.md
|
||||
* [CB-10035](https://issues.apache.org/jira/browse/CB-10035) Updated version and RELEASENOTES.md for release 2.0.0
|
||||
* removed r prefix from tags
|
||||
* [CB-10035](https://issues.apache.org/jira/browse/CB-10035) Updated RELEASENOTES to be newest to oldest
|
||||
* remove unneeded weakness
|
||||
* [CB-8863](https://issues.apache.org/jira/browse/CB-8863) correct block usage for async calls
|
||||
* [CB-5479](https://issues.apache.org/jira/browse/CB-5479) android: changed saveToPhotoAlbum to save uncompressed images
|
||||
* [CB-9169](https://issues.apache.org/jira/browse/CB-9169) android: Fixed filetype for uncompressed images and added quirk
|
||||
* [CB-9446](https://issues.apache.org/jira/browse/CB-9446) related: Removing CordovaResource library code in favour of the code we're supposed to be deprecating because that at least works.
|
||||
* [CB-9942](https://issues.apache.org/jira/browse/CB-9942) Normalize line endings in Camera plugin docs
|
||||
* [CB-9910](https://issues.apache.org/jira/browse/CB-9910) android: Add permission request for some gallery requests
|
||||
* [CB-7668](https://issues.apache.org/jira/browse/CB-7668) android: Adding a sterner warning for allowedit on Android
|
||||
* Actually fixing the contribute link.
|
||||
* Fixing contribute link.
|
||||
* Using the CordovaResourceApi to fine paths of files in the background thread. If the file doesn't exist, return the content URI We also do a refactor to bring this in line. This code got bike-shedded a bit.
|
||||
* Add engine tag for Cordova-Android 5.0.x
|
||||
* Fix permission handling
|
||||
* [CB-9583](https://issues.apache.org/jira/browse/CB-9583) Permissions for Marshmallow
|
||||
* Closes stale pull requests. Close #91, close #82, close #59, close #20
|
||||
* Try to use realpath filename instead of default modified.jpg
|
||||
* change 'case' to else-if. This closes #113
|
||||
* [CB-6190](https://issues.apache.org/jira/browse/CB-6190) - iOS camera plugin ignores quality parameter
|
||||
* [CB-9633](https://issues.apache.org/jira/browse/CB-9633) iOS Taking a Picture With Option destinationType:NATIVE_URI Doesn't Show Image
|
||||
* [CB-9745](https://issues.apache.org/jira/browse/CB-9745) Camera plugin docs should be generated from the source
|
||||
* [CB-9622](https://issues.apache.org/jira/browse/CB-9622) Windows Phone 8 Camera Option destinationType:NATIVE_URI is a NO-OP
|
||||
* [CB-9623](https://issues.apache.org/jira/browse/CB-9623) Fixes various issues when encodingType set to png
|
||||
* [CB-9591](https://issues.apache.org/jira/browse/CB-9591) Retaining aspect ratio when resizing
|
||||
* [CB-9443](https://issues.apache.org/jira/browse/CB-9443) Pick correct maxResolution This closes #111, closes #56
|
||||
* [CB-9151](https://issues.apache.org/jira/browse/CB-9151) Trigger captureAction only once
|
||||
* [CB-9413](https://issues.apache.org/jira/browse/CB-9413) Close RandomAccessStream once copied
|
||||
* [CB-5661](https://issues.apache.org/jira/browse/CB-5661) Remove outdated iOS quirks about memory
|
||||
* Closing stale pull request: close #106
|
||||
* [CB-9349](https://issues.apache.org/jira/browse/CB-9349) Focus control and nice UI
|
||||
* Closing stale pull request: close #73
|
||||
* Closing stale pull request: close #77
|
||||
* remove travis-ci integration
|
||||
* [CB-9259](https://issues.apache.org/jira/browse/CB-9259) Forgot to add another check on which URI we're using when fixing this thing the first time
|
||||
* [CB-9247](https://issues.apache.org/jira/browse/CB-9247) - typo
|
||||
* [CB-9247](https://issues.apache.org/jira/browse/CB-9247) - Added macro to conditionally add NSData+Base64.h
|
||||
* [CB-9247](https://issues.apache.org/jira/browse/CB-9247) - Fixes compilation errors with cordova-ios 4.x
|
||||
* Fix returning native url on windows.
|
||||
* [CB-9192](https://issues.apache.org/jira/browse/CB-9192) Incremented plugin version.
|
||||
* [CB-9202](https://issues.apache.org/jira/browse/CB-9202) updated repo url to github mirror in package.json
|
||||
* [CB-9192](https://issues.apache.org/jira/browse/CB-9192) Updated version and RELEASENOTES.md for release 1.2.0
|
||||
* Closing stale pull request: close #84
|
||||
* Closing stale pull request: close #66
|
||||
* [CB-9128](https://issues.apache.org/jira/browse/CB-9128) cordova-plugin-camera documentation translation: cordova-plugin-camera
|
||||
* Update docs. This closes #100
|
||||
* attempt to fix npm markdown issue
|
||||
* [CB-8883](https://issues.apache.org/jira/browse/CB-8883) fix picture rotation issue
|
||||
* one more alias
|
||||
* Fixed some nit white-space issues, aliased a little more
|
||||
* major refactor : readability
|
||||
* Patch for CB-8498, this closes #64
|
||||
* [CB-8879](https://issues.apache.org/jira/browse/CB-8879) fix stripe issue with correct aspect ratio
|
||||
* [CB-8601](https://issues.apache.org/jira/browse/CB-8601) - iOS camera unit tests broken
|
||||
* [CB-7667](https://issues.apache.org/jira/browse/CB-7667) iOS8: Handle case where camera is not authorized (closes #49)
|
||||
* add missing license header
|
||||
* [CB-8959](https://issues.apache.org/jira/browse/CB-8959) Incremented plugin version.
|
||||
* [CB-8959](https://issues.apache.org/jira/browse/CB-8959) Updated version and RELEASENOTES.md for release 1.1.0
|
||||
* [CB-8943](https://issues.apache.org/jira/browse/CB-8943) fix PickAndContinue issue on Win10Phone
|
||||
* [CB-8253](https://issues.apache.org/jira/browse/CB-8253) Fix potential unreleased resources
|
||||
* [CB-8909](https://issues.apache.org/jira/browse/CB-8909) Remove unused import from File
|
||||
* [CB-8404](https://issues.apache.org/jira/browse/CB-8404) typo fix cameraproxy.js
|
||||
* [CB-8404](https://issues.apache.org/jira/browse/CB-8404) Rotate camera feed with device orientation
|
||||
* [CB-8054](https://issues.apache.org/jira/browse/CB-8054) Support taking pictures from file for WP8
|
||||
* [CB-8405](https://issues.apache.org/jira/browse/CB-8405) Use z-index instead of z-order
|
||||
* [CB-8858](https://issues.apache.org/jira/browse/CB-8858) Incremented plugin version.
|
||||
* [CB-8858](https://issues.apache.org/jira/browse/CB-8858) Updated version in package.json for release 1.0.0
|
||||
* Revert "CB-8858 Incremented plugin version."
|
||||
* [CB-8858](https://issues.apache.org/jira/browse/CB-8858) Incremented plugin version.
|
||||
* [CB-8858](https://issues.apache.org/jira/browse/CB-8858) Updated version and RELEASENOTES.md for release 1.0.0
|
||||
* [CB-8780](https://issues.apache.org/jira/browse/CB-8780) - Display popover using main thread. Fixes popover slowness (closes #81)
|
||||
* [CB-8746](https://issues.apache.org/jira/browse/CB-8746) bumped version of file dependency in package.json too
|
||||
* [CB-8746](https://issues.apache.org/jira/browse/CB-8746) bumped version of file dependency
|
||||
* [CB-8746](https://issues.apache.org/jira/browse/CB-8746) gave plugin major version bump
|
||||
* CR fixes
|
||||
* [CB-8707](https://issues.apache.org/jira/browse/CB-8707) refactoring windows code to improve readability
|
||||
* [CB-8706](https://issues.apache.org/jira/browse/CB-8706) use filePicker if saveToPhotoAlbum is true
|
||||
* [CB-8706](https://issues.apache.org/jira/browse/CB-8706) remove unnecessary capabilities from xml
|
||||
* [CB-8747](https://issues.apache.org/jira/browse/CB-8747) updated dependency, added peer dependency
|
||||
* [CB-8683](https://issues.apache.org/jira/browse/CB-8683) updated blackberry specific references of org.apache.cordova.camera to cordova-plugin-camera
|
||||
* [CB-8782](https://issues.apache.org/jira/browse/CB-8782) Updated the docs to talk about the allowEdit quirks, it's not 100% working, but better than it was
|
||||
* [CB-8782](https://issues.apache.org/jira/browse/CB-8782) Fixed the flow so that we save the cropped image and use it, not the original non-cropped. Crop only supports G+ Photos Crop, other crops may not work, depending on the OEM
|
||||
* [CB-8740](https://issues.apache.org/jira/browse/CB-8740) Removing FileHelper call that was failing on Samsung Galaxy S3, now that we have a real path, we only need to update the MediaStore, not pull from it in this case
|
||||
* [CB-8740](https://issues.apache.org/jira/browse/CB-8740) Partial fix for Save Image to Gallery error found in MobileSpec
|
||||
* [CB-8683](https://issues.apache.org/jira/browse/CB-8683) changed plugin-id to pacakge-name
|
||||
* [CB-8653](https://issues.apache.org/jira/browse/CB-8653) properly updated translated docs to use new id
|
||||
* [CB-8653](https://issues.apache.org/jira/browse/CB-8653) updated translated docs to use new id
|
||||
* [CB-8351](https://issues.apache.org/jira/browse/CB-8351) Fix custom implementation of integerValueForKey (close #79)
|
||||
* Fix cordova-paramedic path change, build with TRAVIS_BUILD_DIR, use npm to install paramedic
|
||||
* docs: added 'Windows' to supported platforms
|
||||
* [CB-8653](https://issues.apache.org/jira/browse/CB-8653) Updated Readme
|
||||
* [CB-8659](https://issues.apache.org/jira/browse/CB-8659) ios: 4.0.x Compatibility: Remove use of deprecated headers
|
||||
* [CB-8646](https://issues.apache.org/jira/browse/CB-8646) Incremented plugin version.
|
||||
* [CB-8646](https://issues.apache.org/jira/browse/CB-8646) Updated version and RELEASENOTES.md for release 0.3.6
|
||||
* added missing apache header
|
||||
* Fix localize key for Videos. This closes #58
|
||||
* [CB-8235](https://issues.apache.org/jira/browse/CB-8235) android: Fix crash when selecting images from DropBox with spaces in path (close #65)
|
||||
* add try ... catch for getting image orientation
|
||||
* [CB-8599](https://issues.apache.org/jira/browse/CB-8599) fix threading issue with cameraPicker (fixes #72)
|
||||
* [CB-8559](https://issues.apache.org/jira/browse/CB-8559) Integrate TravisCI
|
||||
* [CB-8438](https://issues.apache.org/jira/browse/CB-8438) cordova-plugin-camera documentation translation: cordova-plugin-camera
|
||||
* [CB-8538](https://issues.apache.org/jira/browse/CB-8538) Added package.json file
|
||||
* [CB-8429](https://issues.apache.org/jira/browse/CB-8429) Incremented plugin version.
|
||||
* [CB-8429](https://issues.apache.org/jira/browse/CB-8429) Updated version and RELEASENOTES.md for release 0.3.5
|
||||
* [CB-8351](https://issues.apache.org/jira/browse/CB-8351) ios: Stop using now-deprecated [NSData base64EncodedString]
|
||||
* [CB-8351](https://issues.apache.org/jira/browse/CB-8351) ios: Stop using now-deprecated integerValueForKey: class extension
|
||||
* [CB-8351](https://issues.apache.org/jira/browse/CB-8351) Unbreak build from previous commit
|
||||
* [CB-8351](https://issues.apache.org/jira/browse/CB-8351) Use argumentForIndex rather than NSArray extension
|
||||
* [CB-8032](https://issues.apache.org/jira/browse/CB-8032) - Camera Plugin - Add nativeURL external method support for CDVFileSystem->makeEntryForPath:isDirectory: (closes #57)
|
||||
* [CB-7938](https://issues.apache.org/jira/browse/CB-7938) - Added XCTest unit tests project, with stubs (adapted from SplashScreen unit test setup) (closes #60)
|
||||
* [CB-7937](https://issues.apache.org/jira/browse/CB-7937) - Re-factor iOS Camera plugin so that it is testable (closes #52)
|
||||
* [CB-8110](https://issues.apache.org/jira/browse/CB-8110) Incremented plugin version.
|
||||
* [CB-8110](https://issues.apache.org/jira/browse/CB-8110) Updated version and RELEASENOTES.md for release 0.3.4
|
||||
* [CB-7977](https://issues.apache.org/jira/browse/CB-7977) Mention deviceready in plugin docs
|
||||
* [CB-7979](https://issues.apache.org/jira/browse/CB-7979) Each plugin doc should have a ## Installation section
|
||||
* Fix memory leak of image data in imagePickerControllerReturnImageResult
|
||||
* Pass uri to crop instead of pulling the low resolution image out of the intent return (close #43)
|
||||
* Add orientation support for PNG to Android (closes #45)
|
||||
* [CB-7700](https://issues.apache.org/jira/browse/CB-7700) cordova-plugin-camera documentation translation: cordova-plugin-camera
|
||||
* Incremented plugin version.
|
||||
* Updated version and RELEASENOTES.md for release 0.3.3
|
||||
* [CB-7600](https://issues.apache.org/jira/browse/CB-7600) Adds informative message to error callback in manual test.
|
||||
* [CB-7571](https://issues.apache.org/jira/browse/CB-7571) Bump version of nested plugin to match parent plugin
|
||||
* [CB-7571](https://issues.apache.org/jira/browse/CB-7571) Incremented plugin version.
|
||||
* [CB-7571](https://issues.apache.org/jira/browse/CB-7571) Updated version and RELEASENOTES.md for release 0.3.2
|
||||
* [CB-7551](https://issues.apache.org/jira/browse/CB-7551) - [Camera][iOS 8] Scaled images show a white line
|
||||
* [CB-7558](https://issues.apache.org/jira/browse/CB-7558) - hasPendingOperation flag in Camera plugin's takePicture should be reversed to fix memory errors
|
||||
* [CB-7557](https://issues.apache.org/jira/browse/CB-7557) - Camera plugin tests is missing a File dependency
|
||||
* [CB-7423](https://issues.apache.org/jira/browse/CB-7423) do cleanup after copyImage manual test
|
||||
* [CB-7471](https://issues.apache.org/jira/browse/CB-7471) cordova-plugin-camera documentation translation: cordova-plugin-camera
|
||||
* [CB-7413](https://issues.apache.org/jira/browse/CB-7413) Resolve 'ms-appdata' URIs with File plugin
|
||||
* Fixed minor bugs with the browser
|
||||
* [CB-7433](https://issues.apache.org/jira/browse/CB-7433) Adds missing window reference to prevent manual tests failure on Android and iOS
|
||||
* [CB-7249](https://issues.apache.org/jira/browse/CB-7249) cordova-plugin-camera documentation translation: cordova-plugin-camera
|
||||
* [CB-4003](https://issues.apache.org/jira/browse/CB-4003) - Add config option to not use location information in Camera plugin (and default to not use it)
|
||||
* [CB-7461](https://issues.apache.org/jira/browse/CB-7461) - Geolocation fails in Camera plugin in iOS 8
|
||||
* [CB-7378](https://issues.apache.org/jira/browse/CB-7378) Use single Proxy for both windows8 and windows.
|
||||
* [CB-7378](https://issues.apache.org/jira/browse/CB-7378) Adds support for windows platform
|
||||
* [CB-7433](https://issues.apache.org/jira/browse/CB-7433) Fixes manual tests failure on windows
|
||||
* [CB-6958](https://issues.apache.org/jira/browse/CB-6958) Get the correct default for "quality" in the test
|
||||
* add documentation for manual tests
|
||||
* [CB-7249](https://issues.apache.org/jira/browse/CB-7249) cordova-plugin-camera documentation translation: cordova-plugin-camera
|
||||
* [CB-4003](https://issues.apache.org/jira/browse/CB-4003) - Add config option to not use location information in Camera plugin (and default to not use it)
|
||||
* [CB-7461](https://issues.apache.org/jira/browse/CB-7461) - Geolocation fails in Camera plugin in iOS 8
|
||||
* [CB-7433](https://issues.apache.org/jira/browse/CB-7433) Fixes manual tests failure on windows
|
||||
* [CB-7378](https://issues.apache.org/jira/browse/CB-7378) Use single Proxy for both windows8 and windows.
|
||||
* [CB-7378](https://issues.apache.org/jira/browse/CB-7378) Adds support for windows platform
|
||||
* [CB-6958](https://issues.apache.org/jira/browse/CB-6958) Get the correct default for "quality" in the test
|
||||
* add documentation for manual tests
|
||||
* Updated docs for browser
|
||||
* Added support for the browser
|
||||
* [CB-7286](https://issues.apache.org/jira/browse/CB-7286) [BlackBerry10] Use getUserMedia if camera card is unavailable
|
||||
* [CB-7180](https://issues.apache.org/jira/browse/CB-7180) - Update Camera plugin to support generic plugin webView UIView (which can be either a UIWebView or WKWebView)
|
||||
* Renamed test dir, added nested plugin.xml
|
||||
* [CB-6958](https://issues.apache.org/jira/browse/CB-6958) added manual tests
|
||||
* [CB-6958.](https://issues.apache.org/jira/browse/CB-6958.) Port camera tests to plugin-test-framework
|
||||
* [CB-7244](https://issues.apache.org/jira/browse/CB-7244) Incremented plugin version.
|
||||
* [CB-7244](https://issues.apache.org/jira/browse/CB-7244) Updated version and RELEASENOTES.md for release 0.3.1
|
||||
* CB-7249cordova-plugin-camera documentation translation: cordova-plugin-camera
|
||||
* update CameraProxy.js
|
||||
* [CB-7187](https://issues.apache.org/jira/browse/CB-7187) ios: Add explicit dependency on CoreLocation.framework
|
||||
* CB-7110cordova-plugin-camera documentation translation: cordova-plugin-camera
|
||||
* [BlackBerry10] Doc correction - sourceType is supported
|
||||
* CB-6127lisa7cordova-plugin-consolecordova-plugin-camera documentation translation: cordova-plugin-camera
|
||||
* [CB-7071](https://issues.apache.org/jira/browse/CB-7071) android: Fix callback firing before CROP intent is sent when allowEdit=true
|
||||
* Tweak docs to not use []'s for optional arg since that's JS array notation
|
||||
* [CB-6875](https://issues.apache.org/jira/browse/CB-6875) android: Handle exception when SDCard is not mounted
|
||||
* ios: Delete postImage (dead code)
|
||||
* Prevent NPE on processResiultFromGallery when intent comes null
|
||||
* Remove iOS doc reference to non-existing navigator.fileMgr API
|
||||
* Docs updated with some default values
|
||||
* Removes File plugin dependency from windows8 code.
|
||||
* Use WinJS functionality to resize image instead of File plugin functionality
|
||||
* [CB-6877](https://issues.apache.org/jira/browse/CB-6877) Incremented plugin version.
|
||||
* [CB-6877](https://issues.apache.org/jira/browse/CB-6877) Updated version and RELEASENOTES.md for release 0.3.0
|
||||
* [CB-2083](https://issues.apache.org/jira/browse/CB-2083) documented saveToPhotoAlbum quirk on WP8
|
||||
* [CB-5895](https://issues.apache.org/jira/browse/CB-5895) documented saveToPhotoAlbum quirk on WP8
|
||||
* Remove deprecated symbols for iOS < 6
|
||||
* documentation translation: cordova-plugin-camera
|
||||
* Lisa testing pulling in plugins for plugin: cordova-plugin-camera
|
||||
* Lisa testing pulling in plugins for plugin: cordova-plugin-camera
|
||||
* Lisa testing pulling in plugins for plugin: cordova-plugin-camera
|
||||
* Lisa testing pulling in plugins for plugin: cordova-plugin-camera
|
||||
* ubuntu: use application directory for images
|
||||
* [CB-6795](https://issues.apache.org/jira/browse/CB-6795) Add license
|
||||
* documentation translation: cordova-plugin-camera
|
||||
* Lisa testing pulling in plugins for plugin: cordova-plugin-camera
|
||||
* Lisa testing pulling in plugins for plugin: cordova-plugin-camera
|
||||
* Little fix in code formatting
|
||||
* [CB-6613](https://issues.apache.org/jira/browse/CB-6613) Use WinJS functionality to get base64-encoded content of image instead of File plugin functionality
|
||||
* [CB-6612](https://issues.apache.org/jira/browse/CB-6612) camera.getPicture now always returns encoded JPEG image
|
||||
* Removed invalid note from [CB-5398](https://issues.apache.org/jira/browse/CB-5398)
|
||||
* [CB-6576](https://issues.apache.org/jira/browse/CB-6576) - Returns a specific error message when app has no access to library.
|
||||
* [CB-6491](https://issues.apache.org/jira/browse/CB-6491) add CONTRIBUTING.md
|
||||
* [CB-6546](https://issues.apache.org/jira/browse/CB-6546) android: Fix a couple bugs with allowEdit pull request
|
||||
* [CB-6546](https://issues.apache.org/jira/browse/CB-6546) android: Add support for allowEdit Camera option
|
||||
* [CB-6452](https://issues.apache.org/jira/browse/CB-6452) Incremented plugin version on dev branch.
|
||||
* [CB-6452](https://issues.apache.org/jira/browse/CB-6452) Updated version and RELEASENOTES.md for release 0.2.9
|
||||
* [CB-6460](https://issues.apache.org/jira/browse/CB-6460) Update license headers
|
||||
* [CB-6422](https://issues.apache.org/jira/browse/CB-6422) [windows8] use cordova/exec/proxy
|
||||
* WP8 When only targetWidth or targetHeight is provided, use it as the only bound
|
||||
* Remove rotation test value
|
||||
* cleanup, finalize implementations/consolidations
|
||||
* combining callbacks, removing lots of dupe code
|
||||
* Fix camera issues, cropping, memory leaks CB-4027, CB-5102, CB-2737, [CB-2387](https://issues.apache.org/jira/browse/CB-2387)
|
||||
* [CB-6212](https://issues.apache.org/jira/browse/CB-6212) iOS: fix warnings compiled under arm64 64-bit
|
||||
* Fix typo error in docs
|
||||
* [CB-6212](https://issues.apache.org/jira/browse/CB-6212) iOS: fix warnings compiled under arm64 64-bit
|
||||
* Add rim xml namespaces declaration
|
||||
* Add NOTICE file
|
||||
* [CB-6114](https://issues.apache.org/jira/browse/CB-6114) Incremented plugin version on dev branch.
|
||||
* [CB-6114](https://issues.apache.org/jira/browse/CB-6114) Updated version and RELEASENOTES.md for release 0.2.8
|
||||
* Add NOTICE file
|
||||
* [CB-6114](https://issues.apache.org/jira/browse/CB-6114) Updated version and RELEASENOTES.md for release 0.2.8
|
||||
* [CB-1826](https://issues.apache.org/jira/browse/CB-1826) Android: Guard against content provider not supplying orientation
|
||||
* [CB-1826](https://issues.apache.org/jira/browse/CB-1826) Catch OOM on gallery image resize
|
||||
* Refactor onActivityResult
|
||||
* [CB-5980](https://issues.apache.org/jira/browse/CB-5980) Incremented plugin version on dev branch.
|
||||
* Lisa testing pulling in plugins for plugin: cordova-plugin-camera
|
||||
* Lisa testing pulling in plugins for plugin: cordova-plugin-camera
|
||||
* [CB-5980](https://issues.apache.org/jira/browse/CB-5980) Updated version and RELEASENOTES.md for release 0.2.7
|
||||
* remove unrequired FFOS file
|
||||
* reapply new version of FFOS config in plugin.xml
|
||||
* remove 2nd FFOS platform config in plugin.xml
|
||||
* typo
|
||||
* [CB-4919](https://issues.apache.org/jira/browse/CB-4919) firefox os quirks added and supported platforms list is updated
|
||||
* getPicture via web activities
|
||||
* Documented quirk for [CB-5335](https://issues.apache.org/jira/browse/CB-5335) + [CB-5206](https://issues.apache.org/jira/browse/CB-5206) for WP7+8
|
||||
* reference the correct firefoxos implementation
|
||||
* Delete stale test/ directory
|
||||
* [BlackBerry10] Add permission to access_shared
|
||||
* [CB-5719](https://issues.apache.org/jira/browse/CB-5719) Incremented plugin version on dev branch.
|
||||
* Documented quirk for [CB-5335](https://issues.apache.org/jira/browse/CB-5335) + [CB-5206](https://issues.apache.org/jira/browse/CB-5206) for WP7+8
|
||||
* [CB-5719](https://issues.apache.org/jira/browse/CB-5719) Updated version and RELEASENOTES.md for release 0.2.6
|
||||
* [CB-5658](https://issues.apache.org/jira/browse/CB-5658) Update license comment formatting of doc/index.md
|
||||
* [CB-5658](https://issues.apache.org/jira/browse/CB-5658) Add doc.index.md for Camera plugin
|
||||
* [CB-5658](https://issues.apache.org/jira/browse/CB-5658) Delete stale snapshot of plugin docs
|
||||
* [CB-2442](https://issues.apache.org/jira/browse/CB-2442) [CB-2419](https://issues.apache.org/jira/browse/CB-2419) Use Windows.Storage.ApplicationData.current.localFolder, instead of writing to app package.
|
||||
* [BlackBerry10] Adding platform level permissions
|
||||
* [CB-5599](https://issues.apache.org/jira/browse/CB-5599) Android: Catch and ignore OutOfMemoryError in getRotatedBitmap()
|
||||
* [CB-5565](https://issues.apache.org/jira/browse/CB-5565) Incremented plugin version on dev branch.
|
||||
* [CB-5565](https://issues.apache.org/jira/browse/CB-5565) Updated version and RELEASENOTES.md for release 0.2.5
|
||||
* fix camera for firefox os
|
||||
* getPicture via web activities
|
||||
* [ubuntu] specify policy_group
|
||||
* add ubuntu platform
|
||||
* 1. User Agent detection now detects AmazonWebView. 2. Change to use amazon-fireos as the platform if user agent string contains 'cordova-amazon-fireos'
|
||||
* Added amazon-fireos platform.
|
||||
* [CB-5188](https://issues.apache.org/jira/browse/CB-5188)
|
||||
* [CB-5188](https://issues.apache.org/jira/browse/CB-5188) Updated version and RELEASENOTES.md for release 0.2.4
|
||||
* [CB-5128](https://issues.apache.org/jira/browse/CB-5128) added repo + issue tag to plugin.xml for camera plugin
|
||||
* [CB-4958](https://issues.apache.org/jira/browse/CB-4958) - iOS - Camera plugin should not show the status bar
|
||||
* [CB-4919](https://issues.apache.org/jira/browse/CB-4919) updated plugin.xml for FxOS
|
||||
* [CB-4915](https://issues.apache.org/jira/browse/CB-4915) Incremented plugin version on dev branch.
|
||||
* [CB-4915](https://issues.apache.org/jira/browse/CB-4915) Updated version and RELEASENOTES.md for release 0.2.3
|
||||
* [CB-4889](https://issues.apache.org/jira/browse/CB-4889) bumping&resetting version
|
||||
* [CB-4889](https://issues.apache.org/jira/browse/CB-4889) forgot index.html
|
||||
* [CB-4889](https://issues.apache.org/jira/browse/CB-4889) renaming core inside cameraProxy
|
||||
* [Windows8] commandProxy has moved
|
||||
* [Windows8] commandProxy has moved
|
||||
* added Camera API for FirefoxOS
|
||||
* Rename CHANGELOG.md -> RELEASENOTES.md
|
||||
* [CB-4823](https://issues.apache.org/jira/browse/CB-4823) Fix XCode 5 camera plugin warnings
|
||||
* Fix compiler warnings
|
||||
* [CB-4765](https://issues.apache.org/jira/browse/CB-4765) Move ExifHelper.java into Camera Plugin
|
||||
* [CB-4764](https://issues.apache.org/jira/browse/CB-4764) Remove reference to DirectoryManager from CameraLauncher
|
||||
* [CB-4763](https://issues.apache.org/jira/browse/CB-4763) Use a copy of FileHelper.java within camera-plugin.
|
||||
* [CB-4752](https://issues.apache.org/jira/browse/CB-4752) Incremented plugin version on dev branch.
|
||||
* [CB-4633](https://issues.apache.org/jira/browse/CB-4633) We really should close cursors. It's just the right thing to do.
|
||||
* No longer causes a stack trace, but it doesn't cause the error to be called.
|
||||
* [CB-4889](https://issues.apache.org/jira/browse/CB-4889) renaming org.apache.cordova.core.camera to org.apache.cordova.camera
|
||||
* No longer causes a stack trace, but it doesn't cause the error to be called.
|
||||
* [CB-4432](https://issues.apache.org/jira/browse/CB-4432) copyright notice change
|
||||
* [CB-4752](https://issues.apache.org/jira/browse/CB-4752) Updated version and changelog
|
||||
* [CB-4656](https://issues.apache.org/jira/browse/CB-4656) Don't add line-breaks to base64-encoded images.
|
||||
* [CB-4432](https://issues.apache.org/jira/browse/CB-4432) copyright notice change
|
||||
* [CB-4595](https://issues.apache.org/jira/browse/CB-4595) updated version
|
||||
* reverted name element to be human readable
|
||||
* [CB-4417](https://issues.apache.org/jira/browse/CB-4417) Move cordova-plugin-camera to its own Java package.
|
||||
* updated namespace, name tag and readme
|
||||
* cleanup whitespace
|
||||
* [CB-3482](https://issues.apache.org/jira/browse/CB-3482) Allow image metadata to be saved to album on iOS
|
||||
* [CB-3453](https://issues.apache.org/jira/browse/CB-3453) Save original picture to photo library
|
||||
* [CB-3482](https://issues.apache.org/jira/browse/CB-3482) Allow image metadata to be saved to album on iOS
|
||||
* [CB-3453](https://issues.apache.org/jira/browse/CB-3453) Save original picture to photo library
|
||||
* [plugin.xml] adding android namespace
|
||||
* [plugin.xml] standardizing license + meta
|
||||
* [license] adding apache license file
|
||||
* updating plugin.xml with registry data
|
||||
* [Windows8] added support for Windows8
|
||||
* [CB-4366](https://issues.apache.org/jira/browse/CB-4366) Explicit MobileCoreServices.framework dependency should be specified for some core plugins
|
||||
* [CB-4367](https://issues.apache.org/jira/browse/CB-4367) Explicit AssetsLibrary.framework dependency should be specified for some core plugins
|
||||
* [CB-4368](https://issues.apache.org/jira/browse/CB-4368) Explicit CoreGraphics.framework dependency should be specified for some core plugins
|
||||
* [CB-4365](https://issues.apache.org/jira/browse/CB-4365) Explicit CoreLocation.framework dependency should be specified for some core plugins
|
||||
* [CB-4361](https://issues.apache.org/jira/browse/CB-4361) Camera plugin needs to specify ImageIO.framework dependency in plugin.xml
|
||||
* [wp] capabilities fix, access to mediaLib for saving photos
|
||||
|
||||
### 2.3.0 (Sep 08, 2016)
|
||||
* [CB-11795](https://issues.apache.org/jira/browse/CB-11795) Add 'protective' entry to cordovaDependencies
|
||||
* [CB-11661](https://issues.apache.org/jira/browse/CB-11661) Add mandatory **iOS 10** privacy description
|
||||
* [CB-11714](https://issues.apache.org/jira/browse/CB-11714) **windows** added more explicit content-type when converting to target data on canvas
|
||||
* [CB-11295](https://issues.apache.org/jira/browse/CB-11295) Add **WP8.1** quirk when choosing image from `photoalbum`
|
||||
* [CB-10067](https://issues.apache.org/jira/browse/CB-10067) Update `PictureSourceType` JSDoc to reflect `README` update
|
||||
* [CB-9070](https://issues.apache.org/jira/browse/CB-9070) Update `CameraPopoverHandle` docs to reflect `README` update
|
||||
* Plugin uses `Android Log class` and not `Cordova LOG class`
|
||||
* [CB-11631](https://issues.apache.org/jira/browse/CB-11631) Appium tests: A working fix for a flaky `selection canceled` failure
|
||||
* [CB-11709](https://issues.apache.org/jira/browse/CB-11709) Tests should use `resolveLocalFileSystemURL()` instead of deprecated `resolveFileSystemURI()`
|
||||
* [CB-11695](https://issues.apache.org/jira/browse/CB-11695) Increased session creation timeout for Appium tests
|
||||
* [CB-11656](https://issues.apache.org/jira/browse/CB-11656) (**Android**) Appium tests: Fixed side menu opening on some more resolutions
|
||||
* [CB-11376](https://issues.apache.org/jira/browse/CB-11376) (**ios**): fix `CameraUsesGeolocation` error
|
||||
* [CB-10067](https://issues.apache.org/jira/browse/CB-10067) (**ios**) clarifications on `PictureSourceType`
|
||||
* [CB-11410](https://issues.apache.org/jira/browse/CB-11410) (**ios**) fix `cameraPopoverHandle.setPosition`
|
||||
* [CB-9070](https://issues.apache.org/jira/browse/CB-9070) (**ios**) Fixed `CameraPopoverHandle` documentation
|
||||
* [CB-11447](https://issues.apache.org/jira/browse/CB-11447) Respect output format when retrieving images from gallery
|
||||
* [CB-11447](https://issues.apache.org/jira/browse/CB-11447) Resolve **iOS** tests failures due to **iOS** quirks
|
||||
* [CB-11553](https://issues.apache.org/jira/browse/CB-11553) Pend failing Appium tests on Sauce Labs for the time being (reverted from commit b69571724035f41642f3ee612c5b66e1f0c4386c)
|
||||
* [CB-11553](https://issues.apache.org/jira/browse/CB-11553) Pend failing Appium tests on Sauce Labs for the time being
|
||||
* [CB-11498](https://issues.apache.org/jira/browse/CB-11498) [**Android**] Appium tests should not fail when there is no camera
|
||||
* Add badges for paramedic builds on Jenkins
|
||||
* [CB-11296](https://issues.apache.org/jira/browse/CB-11296) Appium: Better element clicking and session error handling
|
||||
* [CB-11232](https://issues.apache.org/jira/browse/CB-11232) Appium tests: fixed element tapping on **iOS 9**
|
||||
* [CB-11183](https://issues.apache.org/jira/browse/CB-11183) Appium tests: Added image verification
|
||||
* fixed some bad formatting that hid `HTML` tags and added link to sample
|
||||
* Set **android** quality default value to 50 on the java code
|
||||
* Moving message in PR template to a comment
|
||||
* Add pull request template. This closes #213
|
||||
* [CB-11228](https://issues.apache.org/jira/browse/CB-11228) **browser**: Add classes for styling purposes
|
||||
* [CB-10139](https://issues.apache.org/jira/browse/CB-10139) **browser**: Respect target width and height
|
||||
* [CB-11227](https://issues.apache.org/jira/browse/CB-11227) **browser**: Fix incorrect `mime type`
|
||||
* [CB-11162](https://issues.apache.org/jira/browse/CB-11162) Appium tests: retry spec on failure
|
||||
* [CB-4078](https://issues.apache.org/jira/browse/CB-4078) Fix for `orientation/scaling` on **Android 4.4+** devices
|
||||
* [CB-11165](https://issues.apache.org/jira/browse/CB-11165) removed peer dependency
|
||||
* [CB-11147](https://issues.apache.org/jira/browse/CB-11147) Appium tests: generate descriptive spec names
|
||||
* [CB-10996](https://issues.apache.org/jira/browse/CB-10996) Adding front matter to `README.md`
|
||||
* [CB-11128](https://issues.apache.org/jira/browse/CB-11128) Appum tests: Fixed some of the flaky failures
|
||||
* [CB-11003](https://issues.apache.org/jira/browse/CB-11003) Added Sample section to the Camera plugin README
|
||||
|
||||
### 2.2.0 (Apr 15, 2016)
|
||||
* CB-10873 Avoid crash due to usage of uninitialized variable when writing geolocation data to image destination. Properly handle 'CameraUsesGeolocation' option by properly setting geolocation data in EXIF header in all cases
|
||||
* CB-11073 Appium tests stability improvements
|
||||
* [CB-10873](https://issues.apache.org/jira/browse/CB-10873) Avoid crash due to usage of uninitialized variable when writing geolocation data to image destination. Properly handle 'CameraUsesGeolocation' option by properly setting geolocation data in EXIF header in all cases
|
||||
* [CB-11073](https://issues.apache.org/jira/browse/CB-11073) Appium tests stability improvements
|
||||
* Replace `PermissionHelper.java` with `cordova-plugin-compat`
|
||||
* Making focus handler work only for **windows 10** phone
|
||||
* CB-10865 Run **ios** native tests on **Travis**
|
||||
* CB-10120 Fixing use of constants and `PermissionHelper`
|
||||
* CB-10120 Fix missing CAMERA permission for **Android M**
|
||||
* CB-10756 Adding sterner warnings about `DATA_URL`
|
||||
* CB-10460 `getRealPath` return null in some cases
|
||||
* [CB-10865](https://issues.apache.org/jira/browse/CB-10865) Run **ios** native tests on **Travis**
|
||||
* [CB-10120](https://issues.apache.org/jira/browse/CB-10120) Fixing use of constants and `PermissionHelper`
|
||||
* [CB-10120](https://issues.apache.org/jira/browse/CB-10120) Fix missing CAMERA permission for **Android M**
|
||||
* [CB-10756](https://issues.apache.org/jira/browse/CB-10756) Adding sterner warnings about `DATA_URL`
|
||||
* [CB-10460](https://issues.apache.org/jira/browse/CB-10460) `getRealPath` return null in some cases
|
||||
|
||||
### 2.1.1 (Mar 09, 2016)
|
||||
* [CB-10825](https://issues.apache.org/jira/browse/CB-10825) **Android** should request READ permission for gallery source
|
||||
@@ -59,10 +523,10 @@
|
||||
|
||||
### 2.1.0 (Jan 15, 2016)
|
||||
* added `.ratignore`
|
||||
* CB-10319 **Android** Adding reflective helper methods for permission requests
|
||||
* CB-9189 **Android** Implementing `save/restore` API to handle Activity destruction
|
||||
* CB-10241 App Crash cause by Camera Plugin **iOS 7**
|
||||
* CB-8940 Setting `z-index` values to maximum for UI buttons.
|
||||
* [CB-10319](https://issues.apache.org/jira/browse/CB-10319) **Android** Adding reflective helper methods for permission requests
|
||||
* [CB-9189](https://issues.apache.org/jira/browse/CB-9189) **Android** Implementing `save/restore` API to handle Activity destruction
|
||||
* [CB-10241](https://issues.apache.org/jira/browse/CB-10241) App Crash cause by Camera Plugin **iOS 7**
|
||||
* [CB-8940](https://issues.apache.org/jira/browse/CB-8940) Setting `z-index` values to maximum for UI buttons.
|
||||
|
||||
### 2.0.0 (Nov 18, 2015)
|
||||
* [CB-10035](https://issues.apache.org/jira/browse/CB-10035) Updated `RELEASENOTES` to be newest to oldest
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*jshint node: true, jasmine: true */
|
||||
/* global navigator, Q */
|
||||
|
||||
/*
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
@@ -52,6 +52,12 @@ describe('Camera tests Android.', function () {
|
||||
var screenHeight = DEFAULT_SCREEN_HEIGHT;
|
||||
// promise count to use in promise ID
|
||||
var promiseCount = 0;
|
||||
// determine if Appium session is created successfully
|
||||
var appiumSessionStarted = false;
|
||||
// determine if camera is present on the device/emulator
|
||||
var cameraAvailable = false;
|
||||
// a path to the image we add to the gallery before test run
|
||||
var fillerImagePath;
|
||||
|
||||
function getNextPromiseId() {
|
||||
promiseCount += 1;
|
||||
@@ -72,24 +78,19 @@ describe('Camera tests Android.', function () {
|
||||
});
|
||||
}
|
||||
|
||||
// generates test specs by combining all the specified options
|
||||
// combinines specified options in all possible variations
|
||||
// you can add more options to test more scenarios
|
||||
function generateSpecs() {
|
||||
function generateOptions() {
|
||||
var sourceTypes = [
|
||||
cameraConstants.PictureSourceType.CAMERA,
|
||||
cameraConstants.PictureSourceType.PHOTOLIBRARY
|
||||
],
|
||||
destinationTypes = cameraConstants.DestinationType,
|
||||
encodingTypes = [
|
||||
cameraConstants.EncodingType.JPEG,
|
||||
cameraConstants.EncodingType.PNG
|
||||
],
|
||||
allowEditOptions = [
|
||||
true,
|
||||
false
|
||||
];
|
||||
var destinationTypes = cameraConstants.DestinationType;
|
||||
var encodingTypes = cameraConstants.EncodingType;
|
||||
var allowEditOptions = [ true, false ];
|
||||
var correctOrientationOptions = [ true, false ];
|
||||
|
||||
return cameraHelper.generateSpecs(sourceTypes, destinationTypes, encodingTypes, allowEditOptions);
|
||||
return cameraHelper.generateSpecs(sourceTypes, destinationTypes, encodingTypes, allowEditOptions, correctOrientationOptions);
|
||||
}
|
||||
|
||||
// invokes Camera.getPicture() with the specified options
|
||||
@@ -114,36 +115,53 @@ describe('Camera tests Android.', function () {
|
||||
options.sourceType === cameraConstants.PictureSourceType.SAVEDPHOTOALBUM)) {
|
||||
var tapTile = new wd.TouchAction();
|
||||
var swipeRight = new wd.TouchAction();
|
||||
tapTile.tap({x: Math.round(screenWidth / 4), y: Math.round(screenHeight / 5)});
|
||||
swipeRight.press({x: 10, y: 100})
|
||||
tapTile
|
||||
.tap({
|
||||
x: Math.round(screenWidth / 4),
|
||||
y: Math.round(screenHeight / 4)
|
||||
});
|
||||
swipeRight
|
||||
.press({x: 10, y: 150})
|
||||
.wait(300)
|
||||
.moveTo({x: Math.round(screenWidth / 2), y: 100})
|
||||
.release();
|
||||
.moveTo({x: Math.round(screenWidth - (screenWidth / 8)), y: 0})
|
||||
.wait(1500)
|
||||
.release()
|
||||
.wait(1000);
|
||||
if (options.allowEdit) {
|
||||
return driver
|
||||
// always wait before performing touchAction
|
||||
.sleep(7000)
|
||||
.performTouchAction(tapTile);
|
||||
}
|
||||
return driver
|
||||
.waitForElementByXPath('//android.widget.TextView[@text="Gallery"]', 20000)
|
||||
.elementByXPath('//android.widget.TextView[@text="Gallery"]')
|
||||
.elementByXPath('//android.widget.TextView[@text="Gallery"]')
|
||||
.elementByXPath('//android.widget.TextView[@text="Gallery"]')
|
||||
.elementByXPath('//android.widget.TextView[@text="Gallery"]')
|
||||
.fail(function () {
|
||||
return driver
|
||||
.performTouchAction(swipeRight)
|
||||
.waitForElementByXPath('//android.widget.TextView[@text="Gallery"]', 20000)
|
||||
.elementByXPath('//android.widget.TextView[@text="Gallery"]')
|
||||
.elementByXPath('//android.widget.TextView[@text="Gallery"]')
|
||||
.elementByXPath('//android.widget.TextView[@text="Gallery"]')
|
||||
.elementByXPath('//android.widget.TextView[@text="Gallery"]');
|
||||
})
|
||||
.then(function (element) {
|
||||
return element
|
||||
.click()
|
||||
// we need to sleep here to give a sidebar some time to close
|
||||
// if we don't sleep here, sometimes we would click on a sidebar
|
||||
// in the next step
|
||||
.sleep(3000);
|
||||
}, function () {
|
||||
// the gallery is already opened, just go on:
|
||||
return driver;
|
||||
})
|
||||
.click()
|
||||
// always wait before performing touchAction
|
||||
.sleep(7000)
|
||||
.performTouchAction(tapTile);
|
||||
}
|
||||
// taking a picture from camera
|
||||
return driver
|
||||
.waitForElementByXPath('//android.widget.ImageView[contains(@resource-id,\'shutter\')]', MINUTE)
|
||||
.waitForElementByXPath('//android.widget.ImageView[contains(@resource-id,\'shutter\')]', MINUTE / 2)
|
||||
.elementByXPath('//android.widget.ImageView[contains(@resource-id,\'shutter\')]')
|
||||
.elementByXPath('//android.widget.ImageView[contains(@resource-id,\'shutter\')]')
|
||||
.click()
|
||||
.waitForElementByXPath('//android.widget.ImageView[contains(@resource-id,\'done\')]', MINUTE)
|
||||
.waitForElementByXPath('//android.widget.ImageView[contains(@resource-id,\'done\')]', MINUTE / 2)
|
||||
.elementByXPath('//android.widget.ImageView[contains(@resource-id,\'done\')]')
|
||||
.elementByXPath('//android.widget.ImageView[contains(@resource-id,\'done\')]')
|
||||
.click();
|
||||
})
|
||||
.then(function () {
|
||||
@@ -156,47 +174,39 @@ describe('Camera tests Android.', function () {
|
||||
.click();
|
||||
}
|
||||
})
|
||||
.fail(fail);
|
||||
.fail(function (failure) {
|
||||
throw failure;
|
||||
});
|
||||
}
|
||||
|
||||
// checks if the picture was successfully taken
|
||||
// if shouldLoad is falsy, ensures that the error callback was called
|
||||
function checkPicture(shouldLoad) {
|
||||
function checkPicture(shouldLoad, options) {
|
||||
if (!options) {
|
||||
options = {};
|
||||
}
|
||||
return driver
|
||||
.context(webviewContext)
|
||||
.setAsyncScriptTimeout(MINUTE)
|
||||
.executeAsync(cameraHelper.checkPicture, [getCurrentPromiseId()])
|
||||
.setAsyncScriptTimeout(MINUTE / 2)
|
||||
.executeAsync(cameraHelper.checkPicture, [getCurrentPromiseId(), options])
|
||||
.then(function (result) {
|
||||
if (shouldLoad) {
|
||||
expect(result.length).toBeGreaterThan(0);
|
||||
if (result.indexOf('ERROR') >= 0) {
|
||||
return fail(result);
|
||||
if (result !== 'OK') {
|
||||
fail(result);
|
||||
}
|
||||
} else {
|
||||
if (result.indexOf('ERROR') === -1) {
|
||||
return fail('Unexpected success callback with result: ' + result);
|
||||
}
|
||||
expect(result.indexOf('ERROR')).toBe(0);
|
||||
} else if (result.indexOf('ERROR') === -1) {
|
||||
throw 'Unexpected success callback with result: ' + result;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function runCombinedSpec(spec) {
|
||||
return driver
|
||||
.then(function () {
|
||||
return getPicture(spec.options);
|
||||
})
|
||||
.then(function () {
|
||||
return checkPicture(true);
|
||||
})
|
||||
.fail(saveScreenshotAndFail);
|
||||
}
|
||||
|
||||
// deletes the latest image from the gallery
|
||||
function deleteImage() {
|
||||
var holdTile = new wd.TouchAction();
|
||||
holdTile.press({x: Math.round(screenWidth / 4), y: Math.round(screenHeight / 5)}).wait(1000).release();
|
||||
return driver
|
||||
// always wait before performing touchAction
|
||||
.sleep(7000)
|
||||
.performTouchAction(holdTile)
|
||||
.elementByXPath('//android.widget.TextView[@text="Delete"]')
|
||||
.then(function (element) {
|
||||
@@ -212,32 +222,93 @@ describe('Camera tests Android.', function () {
|
||||
|
||||
function getDriver() {
|
||||
driver = wdHelper.getDriver('Android');
|
||||
return wdHelper.getWebviewContext(driver)
|
||||
return driver.getWebviewContext()
|
||||
.then(function(context) {
|
||||
webviewContext = context;
|
||||
return driver.context(webviewContext);
|
||||
})
|
||||
.waitForDeviceReady()
|
||||
.injectLibraries()
|
||||
.deleteFillerImage(fillerImagePath)
|
||||
.then(function () {
|
||||
return wdHelper.waitForDeviceReady(driver);
|
||||
fillerImagePath = null;
|
||||
})
|
||||
.then(function () {
|
||||
return wdHelper.injectLibraries(driver);
|
||||
.addFillerImage()
|
||||
.then(function (result) {
|
||||
if (result && result.indexOf('ERROR:') === 0) {
|
||||
throw new Error(result);
|
||||
} else {
|
||||
fillerImagePath = result;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function recreateSession() {
|
||||
return driver
|
||||
.quit()
|
||||
.finally(function () {
|
||||
return getDriver();
|
||||
});
|
||||
}
|
||||
|
||||
function tryRunSpec(spec) {
|
||||
return driver
|
||||
.then(spec)
|
||||
.fail(function () {
|
||||
return recreateSession()
|
||||
.then(spec)
|
||||
.fail(function() {
|
||||
return recreateSession()
|
||||
.then(spec);
|
||||
});
|
||||
})
|
||||
.fail(saveScreenshotAndFail);
|
||||
}
|
||||
|
||||
// produces a generic spec function which
|
||||
// takes a picture with specified options
|
||||
// and then verifies it
|
||||
function generateSpec(options) {
|
||||
return function () {
|
||||
return driver
|
||||
.then(function () {
|
||||
return getPicture(options);
|
||||
})
|
||||
.then(function () {
|
||||
return checkPicture(true, options);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function checkSession(done) {
|
||||
if (!appiumSessionStarted) {
|
||||
fail('Failed to start a session');
|
||||
done();
|
||||
}
|
||||
}
|
||||
|
||||
function checkCamera(pending) {
|
||||
if (!cameraAvailable) {
|
||||
pending('This test requires camera');
|
||||
}
|
||||
}
|
||||
|
||||
it('camera.ui.util configuring driver and starting a session', function (done) {
|
||||
getDriver()
|
||||
.fail(fail)
|
||||
.then(function () {
|
||||
appiumSessionStarted = true;
|
||||
}, fail)
|
||||
.done(done);
|
||||
}, 5 * MINUTE);
|
||||
}, 10 * MINUTE);
|
||||
|
||||
it('camera.ui.util determine screen dimensions', function (done) {
|
||||
return driver
|
||||
checkSession(done);
|
||||
driver
|
||||
.context(webviewContext)
|
||||
.execute(function () {
|
||||
return {
|
||||
'width': window.innerWidth,
|
||||
'height': window.innerHeight
|
||||
'width': screen.availWidth,
|
||||
'height': screen.availHeight
|
||||
};
|
||||
}, [])
|
||||
.then(function (size) {
|
||||
@@ -247,131 +318,287 @@ describe('Camera tests Android.', function () {
|
||||
.done(done);
|
||||
}, MINUTE);
|
||||
|
||||
it('camera.ui.util determine camera availability', function (done) {
|
||||
checkSession(done);
|
||||
var opts = {
|
||||
sourceType: cameraConstants.PictureSourceType.CAMERA,
|
||||
saveToPhotoAlbum: false
|
||||
};
|
||||
|
||||
return driver
|
||||
.then(function () {
|
||||
return getPicture(opts);
|
||||
})
|
||||
.then(function () {
|
||||
cameraAvailable = true;
|
||||
}, function () {
|
||||
return recreateSession();
|
||||
})
|
||||
.done(done);
|
||||
}, 5 * MINUTE);
|
||||
|
||||
describe('Specs.', function () {
|
||||
// getPicture() with saveToPhotoLibrary = true
|
||||
it('camera.ui.spec.1 Saving the picture to photo library', function (done) {
|
||||
var options = {
|
||||
it('camera.ui.spec.1 Saving a picture to the photo library', function (done) {
|
||||
checkSession(done);
|
||||
checkCamera(pending);
|
||||
var spec = generateSpec({
|
||||
quality: 50,
|
||||
allowEdit: false,
|
||||
sourceType: cameraConstants.PictureSourceType.CAMERA,
|
||||
saveToPhotoAlbum: true
|
||||
};
|
||||
driver
|
||||
.then(function () {
|
||||
return getPicture(options);
|
||||
})
|
||||
});
|
||||
|
||||
tryRunSpec(spec)
|
||||
.then(function () {
|
||||
isTestPictureSaved = true;
|
||||
return checkPicture(true);
|
||||
})
|
||||
.fail(saveScreenshotAndFail)
|
||||
.done(done);
|
||||
}, 3 * MINUTE);
|
||||
}, 10 * MINUTE);
|
||||
|
||||
// getPicture() with mediaType: VIDEO, sourceType: PHOTOLIBRARY
|
||||
it('camera.ui.spec.2 Selecting only videos', function (done) {
|
||||
var options = { sourceType: cameraConstants.PictureSourceType.PHOTOLIBRARY,
|
||||
mediaType: cameraConstants.MediaType.VIDEO };
|
||||
driver
|
||||
.then(function () {
|
||||
return getPicture(options, true);
|
||||
})
|
||||
.context('NATIVE_APP')
|
||||
.then(function () {
|
||||
// try to find "Gallery" menu item
|
||||
// if there's none, the gallery should be already opened
|
||||
return driver
|
||||
.elementByXPath('//android.widget.TextView[@text="Gallery"]')
|
||||
.then(function (element) {
|
||||
return element.click();
|
||||
}, function () {
|
||||
return driver;
|
||||
});
|
||||
})
|
||||
.then(function () {
|
||||
// if the gallery is opened on the videos page,
|
||||
// there should be a "Choose video" caption
|
||||
return driver
|
||||
.elementByXPath('//*[@text="Choose video"]')
|
||||
.fail(function () {
|
||||
throw 'Couldn\'t find "Choose video" element.';
|
||||
});
|
||||
})
|
||||
.deviceKeyEvent(BACK_BUTTON)
|
||||
.elementByXPath('//android.widget.TextView[@text="Gallery"]')
|
||||
.deviceKeyEvent(BACK_BUTTON)
|
||||
.finally(function () {
|
||||
return driver
|
||||
.elementById('action_bar_title')
|
||||
.then(function () {
|
||||
// success means we're still in native app
|
||||
return driver
|
||||
.deviceKeyEvent(BACK_BUTTON);
|
||||
}, function () {
|
||||
// error means we're already in webview
|
||||
return driver;
|
||||
});
|
||||
})
|
||||
.fail(saveScreenshotAndFail)
|
||||
.done(done);
|
||||
}, 3 * MINUTE);
|
||||
checkSession(done);
|
||||
var spec = function () {
|
||||
var options = { sourceType: cameraConstants.PictureSourceType.PHOTOLIBRARY,
|
||||
mediaType: cameraConstants.MediaType.VIDEO };
|
||||
return driver
|
||||
.then(function () {
|
||||
return getPicture(options, true);
|
||||
})
|
||||
.context('NATIVE_APP')
|
||||
.then(function () {
|
||||
// try to find "Gallery" menu item
|
||||
// if there's none, the gallery should be already opened
|
||||
return driver
|
||||
.waitForElementByXPath('//android.widget.TextView[@text="Gallery"]', 20000)
|
||||
.elementByXPath('//android.widget.TextView[@text="Gallery"]')
|
||||
.elementByXPath('//android.widget.TextView[@text="Gallery"]')
|
||||
.then(function (element) {
|
||||
return element.click();
|
||||
}, function () {
|
||||
return driver;
|
||||
});
|
||||
})
|
||||
.then(function () {
|
||||
// if the gallery is opened on the videos page,
|
||||
// there should be a "Choose video" caption
|
||||
return driver
|
||||
.elementByXPath('//*[@text="Choose video"]')
|
||||
.fail(function () {
|
||||
throw 'Couldn\'t find "Choose video" element.';
|
||||
});
|
||||
})
|
||||
.deviceKeyEvent(BACK_BUTTON)
|
||||
.elementByXPath('//android.widget.TextView[@text="Gallery"]')
|
||||
.deviceKeyEvent(BACK_BUTTON)
|
||||
.finally(function () {
|
||||
return driver
|
||||
.elementById('action_bar_title')
|
||||
.then(function () {
|
||||
// success means we're still in native app
|
||||
return driver
|
||||
.deviceKeyEvent(BACK_BUTTON)
|
||||
// give native app some time to close
|
||||
.sleep(2000)
|
||||
// try again! because every ~30th build
|
||||
// on Sauce Labs this backbutton doesn't work
|
||||
.elementById('action_bar_title')
|
||||
.then(function () {
|
||||
// success means we're still in native app
|
||||
return driver
|
||||
.deviceKeyEvent(BACK_BUTTON);
|
||||
}, function () {
|
||||
// error means we're already in webview
|
||||
return driver;
|
||||
});
|
||||
}, function () {
|
||||
// error means we're already in webview
|
||||
return driver;
|
||||
});
|
||||
});
|
||||
};
|
||||
tryRunSpec(spec).done(done);
|
||||
}, 10 * MINUTE);
|
||||
|
||||
// getPicture(), then dismiss
|
||||
// wait for the error callback to be called
|
||||
it('camera.ui.spec.3 Dismissing the camera', function (done) {
|
||||
var options = { quality: 50,
|
||||
allowEdit: true,
|
||||
sourceType: cameraConstants.PictureSourceType.CAMERA,
|
||||
destinationType: cameraConstants.DestinationType.FILE_URI };
|
||||
driver
|
||||
.then(function () {
|
||||
return getPicture(options, true);
|
||||
})
|
||||
.context("NATIVE_APP")
|
||||
.waitForElementByXPath('//android.widget.ImageView[contains(@resource-id,\'cancel\')]', MINUTE / 2)
|
||||
.click()
|
||||
.then(function () {
|
||||
return checkPicture(false);
|
||||
})
|
||||
.fail(saveScreenshotAndFail)
|
||||
.done(done);
|
||||
}, 3 * MINUTE);
|
||||
checkSession(done);
|
||||
checkCamera(pending);
|
||||
var spec = function () {
|
||||
var options = {
|
||||
quality: 50,
|
||||
allowEdit: true,
|
||||
sourceType: cameraConstants.PictureSourceType.CAMERA,
|
||||
destinationType: cameraConstants.DestinationType.FILE_URI
|
||||
};
|
||||
return driver
|
||||
.then(function () {
|
||||
return getPicture(options, true);
|
||||
})
|
||||
.context("NATIVE_APP")
|
||||
.waitForElementByXPath('//android.widget.ImageView[contains(@resource-id,\'cancel\')]', MINUTE / 2)
|
||||
.elementByXPath('//android.widget.ImageView[contains(@resource-id,\'cancel\')]')
|
||||
.elementByXPath('//android.widget.ImageView[contains(@resource-id,\'cancel\')]')
|
||||
.click()
|
||||
.then(function () {
|
||||
return checkPicture(false);
|
||||
});
|
||||
};
|
||||
|
||||
tryRunSpec(spec).done(done);
|
||||
}, 10 * MINUTE);
|
||||
|
||||
// getPicture(), then take picture but dismiss the edit
|
||||
// wait for the error callback to be called
|
||||
it('camera.ui.spec.4 Dismissing the edit', function (done) {
|
||||
var options = { quality: 50,
|
||||
allowEdit: true,
|
||||
sourceType: cameraConstants.PictureSourceType.CAMERA,
|
||||
destinationType: cameraConstants.DestinationType.FILE_URI };
|
||||
driver
|
||||
.then(function () {
|
||||
return getPicture(options, true);
|
||||
})
|
||||
.context('NATIVE_APP')
|
||||
.waitForElementByXPath('//android.widget.ImageView[contains(@resource-id,\'shutter\')]', MINUTE / 2)
|
||||
.click()
|
||||
.waitForElementByXPath('//android.widget.ImageView[contains(@resource-id,\'done\')]', MINUTE / 2)
|
||||
.click()
|
||||
.waitForElementByXPath('//*[contains(@resource-id,\'discard\')]', MINUTE / 2)
|
||||
.click()
|
||||
.then(function () {
|
||||
return checkPicture(false);
|
||||
})
|
||||
.fail(saveScreenshotAndFail)
|
||||
.done(done);
|
||||
}, 3 * MINUTE);
|
||||
checkSession(done);
|
||||
checkCamera(pending);
|
||||
var spec = function () {
|
||||
var options = {
|
||||
quality: 50,
|
||||
allowEdit: true,
|
||||
sourceType: cameraConstants.PictureSourceType.CAMERA,
|
||||
destinationType: cameraConstants.DestinationType.FILE_URI
|
||||
};
|
||||
return driver
|
||||
.then(function () {
|
||||
return getPicture(options, true);
|
||||
})
|
||||
.context('NATIVE_APP')
|
||||
.waitForElementByXPath('//android.widget.ImageView[contains(@resource-id,\'shutter\')]', MINUTE / 2)
|
||||
.elementByXPath('//android.widget.ImageView[contains(@resource-id,\'shutter\')]')
|
||||
.elementByXPath('//android.widget.ImageView[contains(@resource-id,\'shutter\')]')
|
||||
.click()
|
||||
.waitForElementByXPath('//android.widget.ImageView[contains(@resource-id,\'done\')]', MINUTE / 2)
|
||||
.elementByXPath('//android.widget.ImageView[contains(@resource-id,\'done\')]')
|
||||
.elementByXPath('//android.widget.ImageView[contains(@resource-id,\'done\')]')
|
||||
.click()
|
||||
.waitForElementByXPath('//*[contains(@resource-id,\'discard\')]', MINUTE / 2)
|
||||
.elementByXPath('//*[contains(@resource-id,\'discard\')]')
|
||||
.elementByXPath('//*[contains(@resource-id,\'discard\')]')
|
||||
.click()
|
||||
.then(function () {
|
||||
return checkPicture(false);
|
||||
});
|
||||
};
|
||||
|
||||
tryRunSpec(spec).done(done);
|
||||
}, 10 * MINUTE);
|
||||
|
||||
it('camera.ui.spec.5 Verifying target image size, sourceType=CAMERA', function (done) {
|
||||
checkSession(done);
|
||||
checkCamera(pending);
|
||||
var spec = generateSpec({
|
||||
quality: 50,
|
||||
allowEdit: false,
|
||||
sourceType: cameraConstants.PictureSourceType.CAMERA,
|
||||
saveToPhotoAlbum: false,
|
||||
targetWidth: 210,
|
||||
targetHeight: 210
|
||||
});
|
||||
|
||||
tryRunSpec(spec).done(done);
|
||||
}, 10 * MINUTE);
|
||||
|
||||
it('camera.ui.spec.6 Verifying target image size, sourceType=PHOTOLIBRARY', function (done) {
|
||||
checkSession(done);
|
||||
var spec = generateSpec({
|
||||
quality: 50,
|
||||
allowEdit: false,
|
||||
sourceType: cameraConstants.PictureSourceType.PHOTOLIBRARY,
|
||||
saveToPhotoAlbum: false,
|
||||
targetWidth: 210,
|
||||
targetHeight: 210
|
||||
});
|
||||
|
||||
tryRunSpec(spec).done(done);
|
||||
}, 10 * MINUTE);
|
||||
|
||||
it('camera.ui.spec.7 Verifying target image size, sourceType=CAMERA, DestinationType=NATIVE_URI', function (done) {
|
||||
checkSession(done);
|
||||
checkCamera(pending);
|
||||
var spec = generateSpec({
|
||||
quality: 50,
|
||||
allowEdit: false,
|
||||
sourceType: cameraConstants.PictureSourceType.CAMERA,
|
||||
destinationType: cameraConstants.DestinationType.NATIVE_URI,
|
||||
saveToPhotoAlbum: false,
|
||||
targetWidth: 210,
|
||||
targetHeight: 210
|
||||
});
|
||||
|
||||
tryRunSpec(spec).done(done);
|
||||
}, 10 * MINUTE);
|
||||
|
||||
it('camera.ui.spec.8 Verifying target image size, sourceType=PHOTOLIBRARY, DestinationType=NATIVE_URI', function (done) {
|
||||
checkSession(done);
|
||||
var spec = generateSpec({
|
||||
quality: 50,
|
||||
allowEdit: false,
|
||||
sourceType: cameraConstants.PictureSourceType.PHOTOLIBRARY,
|
||||
destinationType: cameraConstants.DestinationType.NATIVE_URI,
|
||||
saveToPhotoAlbum: false,
|
||||
targetWidth: 210,
|
||||
targetHeight: 210
|
||||
});
|
||||
|
||||
tryRunSpec(spec).done(done);
|
||||
}, 10 * MINUTE);
|
||||
|
||||
it('camera.ui.spec.9 Verifying target image size, sourceType=CAMERA, DestinationType=NATIVE_URI, quality=100', function (done) {
|
||||
checkSession(done);
|
||||
checkCamera(pending);
|
||||
var spec = generateSpec({
|
||||
quality: 100,
|
||||
allowEdit: true,
|
||||
sourceType: cameraConstants.PictureSourceType.CAMERA,
|
||||
destinationType: cameraConstants.DestinationType.NATIVE_URI,
|
||||
saveToPhotoAlbum: false,
|
||||
targetWidth: 305,
|
||||
targetHeight: 305
|
||||
});
|
||||
|
||||
tryRunSpec(spec).done(done);
|
||||
}, 10 * MINUTE);
|
||||
|
||||
it('camera.ui.spec.10 Verifying target image size, sourceType=PHOTOLIBRARY, DestinationType=NATIVE_URI, quality=100', function (done) {
|
||||
checkSession(done);
|
||||
var spec = generateSpec({
|
||||
quality: 100,
|
||||
allowEdit: true,
|
||||
sourceType: cameraConstants.PictureSourceType.PHOTOLIBRARY,
|
||||
destinationType: cameraConstants.DestinationType.NATIVE_URI,
|
||||
saveToPhotoAlbum: false,
|
||||
targetWidth: 305,
|
||||
targetHeight: 305
|
||||
});
|
||||
|
||||
tryRunSpec(spec).done(done);
|
||||
}, 10 * MINUTE);
|
||||
|
||||
// combine various options for getPicture()
|
||||
generateSpecs().forEach(function (spec) {
|
||||
it('camera.ui.spec.5.' + spec.id + ' Combining options', function (done) {
|
||||
runCombinedSpec(spec)
|
||||
.done(done);
|
||||
}, 3 * MINUTE);
|
||||
generateOptions().forEach(function (spec) {
|
||||
it('camera.ui.spec.11.' + spec.id + ' Combining options. ' + spec.description, function (done) {
|
||||
checkSession(done);
|
||||
if (spec.options.sourceType == cameraConstants.PictureSourceType.CAMERA) {
|
||||
checkCamera(pending);
|
||||
}
|
||||
var s = generateSpec(spec.options);
|
||||
tryRunSpec(s).done(done);
|
||||
}, 10 * MINUTE);
|
||||
});
|
||||
|
||||
it('camera.ui.util Delete filler picture from device library', function (done) {
|
||||
driver
|
||||
.context(webviewContext)
|
||||
.deleteFillerImage(fillerImagePath)
|
||||
.done(done);
|
||||
}, MINUTE);
|
||||
|
||||
it('camera.ui.util Delete test image from device library', function (done) {
|
||||
it('camera.ui.util Delete taken picture from device library', function (done) {
|
||||
checkSession(done);
|
||||
if (!isTestPictureSaved) {
|
||||
// couldn't save test picture earlier, so nothing to delete here
|
||||
done();
|
||||
@@ -379,7 +606,7 @@ describe('Camera tests Android.', function () {
|
||||
}
|
||||
// delete exactly one latest picture
|
||||
// this should be the picture we've taken in the first spec
|
||||
return driver
|
||||
driver
|
||||
.context('NATIVE_APP')
|
||||
.deviceKeyEvent(BACK_BUTTON)
|
||||
.sleep(1000)
|
||||
@@ -404,8 +631,9 @@ describe('Camera tests Android.', function () {
|
||||
});
|
||||
|
||||
it('camera.ui.util Destroy the session', function (done) {
|
||||
checkSession(done);
|
||||
driver
|
||||
.quit()
|
||||
.done(done);
|
||||
}, MINUTE);
|
||||
}, 5 * MINUTE);
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*jshint node: true */
|
||||
/* global Q */
|
||||
/* global Q, resolveLocalFileSystemURL, Camera, cordova */
|
||||
/*
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
@@ -25,11 +25,35 @@
|
||||
|
||||
var cameraConstants = require('../../www/CameraConstants');
|
||||
|
||||
module.exports.generateSpecs = function (sourceTypes, destinationTypes, encodingTypes, allowEditOptions) {
|
||||
function findKeyByValue(set, value) {
|
||||
for (var k in set) {
|
||||
if (set.hasOwnProperty(k)) {
|
||||
if (set[k] == value) {
|
||||
return k;
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getDescription(spec) {
|
||||
var desc = '';
|
||||
|
||||
desc += 'sourceType: ' + findKeyByValue(cameraConstants.PictureSourceType, spec.options.sourceType);
|
||||
desc += ', destinationType: ' + findKeyByValue(cameraConstants.DestinationType, spec.options.destinationType);
|
||||
desc += ', encodingType: ' + findKeyByValue(cameraConstants.EncodingType, spec.options.encodingType);
|
||||
desc += ', allowEdit: ' + spec.options.allowEdit.toString();
|
||||
desc += ', correctOrientation: ' + spec.options.correctOrientation.toString();
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
module.exports.generateSpecs = function (sourceTypes, destinationTypes, encodingTypes, allowEditOptions, correctOrientationOptions) {
|
||||
var destinationType,
|
||||
sourceType,
|
||||
encodingType,
|
||||
allowEdit,
|
||||
correctOrientation,
|
||||
specs = [],
|
||||
id = 1;
|
||||
for (destinationType in destinationTypes) {
|
||||
@@ -40,9 +64,12 @@ module.exports.generateSpecs = function (sourceTypes, destinationTypes, encoding
|
||||
if (encodingTypes.hasOwnProperty(encodingType)) {
|
||||
for (allowEdit in allowEditOptions) {
|
||||
if (allowEditOptions.hasOwnProperty(allowEdit)) {
|
||||
// if taking picture from photolibrary, don't vary 'correctOrientation' option
|
||||
if (sourceTypes[sourceType] === cameraConstants.PictureSourceType.PHOTOLIBRARY) {
|
||||
specs.push({
|
||||
for (correctOrientation in correctOrientationOptions) {
|
||||
// if taking picture from photolibrary, don't vary 'correctOrientation' option
|
||||
if ((sourceTypes[sourceType] === cameraConstants.PictureSourceType.PHOTOLIBRARY ||
|
||||
sourceTypes[sourceType] === cameraConstants.PictureSourceType.SAVEDPHOTOALBUM) &&
|
||||
correctOrientation === true) { continue; }
|
||||
var spec = {
|
||||
'id': id++,
|
||||
'options': {
|
||||
'destinationType': destinationTypes[destinationType],
|
||||
@@ -50,30 +77,11 @@ module.exports.generateSpecs = function (sourceTypes, destinationTypes, encoding
|
||||
'encodingType': encodingTypes[encodingType],
|
||||
'allowEdit': allowEditOptions[allowEdit],
|
||||
'saveToPhotoAlbum': false,
|
||||
'correctOrientation': correctOrientationOptions[correctOrientation]
|
||||
}
|
||||
});
|
||||
} else {
|
||||
specs.push({
|
||||
'id': id++,
|
||||
'options': {
|
||||
'destinationType': destinationTypes[destinationType],
|
||||
'sourceType': sourceTypes[sourceType],
|
||||
'encodingType': encodingTypes[encodingType],
|
||||
'correctOrientation': true,
|
||||
'allowEdit': allowEditOptions[allowEdit],
|
||||
'saveToPhotoAlbum': false,
|
||||
}
|
||||
}, {
|
||||
'id': id++,
|
||||
'options': {
|
||||
'destinationType': destinationTypes[destinationType],
|
||||
'sourceType': sourceTypes[sourceType],
|
||||
'encodingType': encodingTypes[encodingType],
|
||||
'correctOrientation': false,
|
||||
'allowEdit': allowEditOptions[allowEdit],
|
||||
'saveToPhotoAlbum': false,
|
||||
}
|
||||
});
|
||||
};
|
||||
spec.description = getDescription(spec);
|
||||
specs.push(spec);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -86,7 +94,13 @@ module.exports.generateSpecs = function (sourceTypes, destinationTypes, encoding
|
||||
return specs;
|
||||
};
|
||||
|
||||
// calls getPicture() and saves the result in promise
|
||||
// note that this function is executed in the context of tested app
|
||||
// and not in the context of tests
|
||||
module.exports.getPicture = function (opts, pid) {
|
||||
if (navigator._appiumPromises[pid - 1]) {
|
||||
navigator._appiumPromises[pid - 1] = null;
|
||||
}
|
||||
navigator._appiumPromises[pid] = Q.defer();
|
||||
navigator.camera.getPicture(function (result) {
|
||||
navigator._appiumPromises[pid].resolve(result);
|
||||
@@ -95,11 +109,197 @@ module.exports.getPicture = function (opts, pid) {
|
||||
}, opts);
|
||||
};
|
||||
|
||||
module.exports.checkPicture = function (pid, cb) {
|
||||
// verifies taken picture when the promise is resolved,
|
||||
// calls a callback with 'OK' if everything is good,
|
||||
// calls a callback with 'ERROR: <error message>' if something is wrong
|
||||
// note that this function is executed in the context of tested app
|
||||
// and not in the context of tests
|
||||
module.exports.checkPicture = function (pid, options, cb) {
|
||||
var isIos = cordova.platformId === "ios";
|
||||
var isAndroid = cordova.platformId === "android";
|
||||
// skip image type check if it's unmodified on Android:
|
||||
// https://github.com/apache/cordova-plugin-camera/#android-quirks-1
|
||||
var skipFileTypeCheckAndroid = isAndroid && options.quality === 100 &&
|
||||
!options.targetWidth && !options.targetHeight &&
|
||||
!options.correctOrientation;
|
||||
|
||||
// Skip image type check if destination is NATIVE_URI and source - device's photoalbum
|
||||
// https://github.com/apache/cordova-plugin-camera/#ios-quirks-1
|
||||
var skipFileTypeCheckiOS = isIos && options.destinationType === Camera.DestinationType.NATIVE_URI &&
|
||||
(options.sourceType === Camera.PictureSourceType.PHOTOLIBRARY ||
|
||||
options.sourceType === Camera.PictureSourceType.SAVEDPHOTOALBUM);
|
||||
|
||||
var skipFileTypeCheck = skipFileTypeCheckAndroid || skipFileTypeCheckiOS;
|
||||
|
||||
var desiredType = 'JPEG';
|
||||
var mimeType = 'image/jpeg';
|
||||
if (options.encodingType === Camera.EncodingType.PNG) {
|
||||
desiredType = 'PNG';
|
||||
mimeType = 'image/png';
|
||||
}
|
||||
|
||||
function errorCallback(msg) {
|
||||
if (msg.hasOwnProperty('message')) {
|
||||
msg = msg.message;
|
||||
}
|
||||
cb('ERROR: ' + msg);
|
||||
}
|
||||
|
||||
// verifies the image we get from plugin
|
||||
function verifyResult(result) {
|
||||
if (result.length === 0) {
|
||||
errorCallback('The result is empty.');
|
||||
return;
|
||||
} else if (isIos && options.destinationType === Camera.DestinationType.NATIVE_URI && result.indexOf('assets-library:') !== 0) {
|
||||
errorCallback('Expected "' + result.substring(0, 150) + '"to start with "assets-library:"');
|
||||
return;
|
||||
} else if (isIos && options.destinationType === Camera.DestinationType.FILE_URI && result.indexOf('file:') !== 0) {
|
||||
errorCallback('Expected "' + result.substring(0, 150) + '"to start with "file:"');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
window.atob(result);
|
||||
// if we got here it is a base64 string (DATA_URL)
|
||||
result = "data:" + mimeType + ";base64," + result;
|
||||
} catch (e) {
|
||||
// not DATA_URL
|
||||
if (options.destinationType === Camera.DestinationType.DATA_URL) {
|
||||
errorCallback('Expected ' + result.substring(0, 150) + 'not to be DATA_URL');
|
||||
return;
|
||||
}
|
||||
}
|
||||
try {
|
||||
if (result.indexOf('file:') === 0 ||
|
||||
result.indexOf('content:') === 0 ||
|
||||
result.indexOf('assets-library:') === 0) {
|
||||
|
||||
if (!window.resolveLocalFileSystemURL) {
|
||||
errorCallback('Cannot read file. Please install cordova-plugin-file to fix this.');
|
||||
return;
|
||||
}
|
||||
resolveLocalFileSystemURL(result, function (entry) {
|
||||
if (skipFileTypeCheck) {
|
||||
displayFile(entry);
|
||||
} else {
|
||||
verifyFile(entry);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
displayImage(result);
|
||||
}
|
||||
} catch (e) {
|
||||
errorCallback(e);
|
||||
}
|
||||
}
|
||||
|
||||
// verifies that the file type matches the requested type
|
||||
function verifyFile(entry) {
|
||||
try {
|
||||
var reader = new FileReader();
|
||||
reader.onloadend = function(e) {
|
||||
var arr = (new Uint8Array(e.target.result)).subarray(0, 4);
|
||||
var header = '';
|
||||
for(var i = 0; i < arr.length; i++) {
|
||||
header += arr[i].toString(16);
|
||||
}
|
||||
var actualType = 'unknown';
|
||||
|
||||
switch (header) {
|
||||
case "89504e47":
|
||||
actualType = 'PNG';
|
||||
break;
|
||||
case 'ffd8ffe0':
|
||||
case 'ffd8ffe1':
|
||||
case 'ffd8ffe2':
|
||||
actualType = 'JPEG';
|
||||
break;
|
||||
}
|
||||
|
||||
if (actualType === desiredType) {
|
||||
displayFile(entry);
|
||||
} else {
|
||||
errorCallback('File type mismatch. Expected ' + desiredType + ', got ' + actualType);
|
||||
}
|
||||
};
|
||||
reader.onerror = function (e) {
|
||||
errorCallback(e);
|
||||
};
|
||||
entry.file(function (file) {
|
||||
reader.readAsArrayBuffer(file);
|
||||
}, function (e) {
|
||||
errorCallback(e);
|
||||
});
|
||||
} catch (e) {
|
||||
errorCallback(e);
|
||||
}
|
||||
}
|
||||
|
||||
// reads the file, then displays the image
|
||||
function displayFile(entry) {
|
||||
function onFileReceived(file) {
|
||||
var reader = new FileReader();
|
||||
reader.onerror = function (e) {
|
||||
errorCallback(e);
|
||||
};
|
||||
reader.onloadend = function (evt) {
|
||||
displayImage(evt.target.result);
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
|
||||
entry.file(onFileReceived, function (e) {
|
||||
errorCallback(e);
|
||||
});
|
||||
}
|
||||
|
||||
function displayImage(image) {
|
||||
try {
|
||||
var imgEl = document.getElementById('camera_test_image');
|
||||
if (!imgEl) {
|
||||
imgEl = document.createElement('img');
|
||||
imgEl.id = 'camera_test_image';
|
||||
document.body.appendChild(imgEl);
|
||||
}
|
||||
var timedOut = false;
|
||||
var loadTimeout = setTimeout(function () {
|
||||
timedOut = true;
|
||||
imgEl.src = '';
|
||||
errorCallback('The image did not load: ' + image.substring(0, 150));
|
||||
}, 10000);
|
||||
var done = function (status) {
|
||||
if (!timedOut) {
|
||||
clearTimeout(loadTimeout);
|
||||
imgEl.src = '';
|
||||
cb(status);
|
||||
}
|
||||
};
|
||||
imgEl.onload = function () {
|
||||
try {
|
||||
// aspect ratio is preserved so only one dimension should match
|
||||
if ((typeof options.targetWidth === 'number' && imgEl.naturalWidth !== options.targetWidth) &&
|
||||
(typeof options.targetHeight === 'number' && imgEl.naturalHeight !== options.targetHeight))
|
||||
{
|
||||
done('ERROR: Wrong image size: ' + imgEl.naturalWidth + 'x' + imgEl.naturalHeight +
|
||||
'. Requested size: ' + options.targetWidth + 'x' + options.targetHeight);
|
||||
} else {
|
||||
done('OK');
|
||||
}
|
||||
} catch (e) {
|
||||
errorCallback(e);
|
||||
}
|
||||
};
|
||||
imgEl.src = image;
|
||||
} catch (e) {
|
||||
errorCallback(e);
|
||||
}
|
||||
}
|
||||
|
||||
navigator._appiumPromises[pid].promise
|
||||
.then(function (result) {
|
||||
cb(result);
|
||||
}, function (err) {
|
||||
cb('ERROR: ' + err);
|
||||
verifyResult(result);
|
||||
})
|
||||
.fail(function (e) {
|
||||
errorCallback(e);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*jshint node: true, jasmine: true */
|
||||
/* global navigator, Q */
|
||||
|
||||
/*
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
@@ -30,7 +30,6 @@
|
||||
|
||||
var wdHelper = global.WD_HELPER;
|
||||
var screenshotHelper = global.SCREENSHOT_HELPER;
|
||||
var wd = wdHelper.getWD();
|
||||
var isDevice = global.DEVICE;
|
||||
var cameraConstants = require('../../www/CameraConstants');
|
||||
var cameraHelper = require('../helpers/cameraHelper');
|
||||
@@ -44,6 +43,8 @@ describe('Camera tests iOS.', function () {
|
||||
var webviewContext = DEFAULT_WEBVIEW_CONTEXT;
|
||||
// promise count to use in promise ID
|
||||
var promiseCount = 0;
|
||||
// going to set this to false if session is created successfully
|
||||
var failedToStart = true;
|
||||
|
||||
function getNextPromiseId() {
|
||||
promiseCount += 1;
|
||||
@@ -66,22 +67,14 @@ describe('Camera tests iOS.', function () {
|
||||
|
||||
// generates test specs by combining all the specified options
|
||||
// you can add more options to test more scenarios
|
||||
function generateSpecs() {
|
||||
var sourceTypes = [
|
||||
cameraConstants.PictureSourceType.CAMERA,
|
||||
cameraConstants.PictureSourceType.PHOTOLIBRARY
|
||||
],
|
||||
destinationTypes = cameraConstants.DestinationType,
|
||||
encodingTypes = [
|
||||
cameraConstants.EncodingType.JPEG,
|
||||
cameraConstants.EncodingType.PNG
|
||||
],
|
||||
allowEditOptions = [
|
||||
true,
|
||||
false
|
||||
];
|
||||
function generateOptions() {
|
||||
var sourceTypes = cameraConstants.PictureSourceType;
|
||||
var destinationTypes = cameraConstants.DestinationType;
|
||||
var encodingTypes = cameraConstants.EncodingType;
|
||||
var allowEditOptions = [ true, false ];
|
||||
var correctOrientationOptions = [ true, false ];
|
||||
|
||||
return cameraHelper.generateSpecs(sourceTypes, destinationTypes, encodingTypes, allowEditOptions);
|
||||
return cameraHelper.generateSpecs(sourceTypes, destinationTypes, encodingTypes, allowEditOptions, correctOrientationOptions);
|
||||
}
|
||||
|
||||
function usePicture() {
|
||||
@@ -89,17 +82,8 @@ describe('Camera tests iOS.', function () {
|
||||
.elementByXPath('//*[@label="Use"]')
|
||||
.click()
|
||||
.fail(function () {
|
||||
return driver
|
||||
// For some reason "Choose" element is not clickable by standard Appium methods
|
||||
// So getting its position and tapping there using TouchAction
|
||||
.elementByXPath('//UIAButton[@label="Choose"]')
|
||||
.getLocation()
|
||||
.then(function (loc) {
|
||||
var tapChoose = new wd.TouchAction();
|
||||
tapChoose.tap(loc);
|
||||
return driver
|
||||
.performTouchAction(tapChoose);
|
||||
});
|
||||
// For some reason "Choose" element is not clickable by standard Appium methods
|
||||
return wdHelper.tapElementByXPath('//UIAButton[@label="Choose"]', driver);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -144,12 +128,14 @@ describe('Camera tests iOS.', function () {
|
||||
if (cancelCamera) {
|
||||
return driver
|
||||
.waitForElementByXPath('//*[@label="Cancel"]', MINUTE / 2)
|
||||
.elementByXPath('//*[@label="Cancel"]')
|
||||
.elementByXPath('//*[@label="Cancel"]')
|
||||
.click();
|
||||
}
|
||||
return driver
|
||||
.waitForElementByXPath('//*[@label="Take Picture"]', MINUTE / 2)
|
||||
.click()
|
||||
.elementByXPath('//*[@label="Use Photo"]')
|
||||
.waitForElementByXPath('//*[@label="Use Photo"]', MINUTE / 2)
|
||||
.click();
|
||||
})
|
||||
.fail(fail);
|
||||
@@ -157,33 +143,34 @@ describe('Camera tests iOS.', function () {
|
||||
|
||||
// checks if the picture was successfully taken
|
||||
// if shouldLoad is falsy, ensures that the error callback was called
|
||||
function checkPicture(shouldLoad) {
|
||||
function checkPicture(shouldLoad, options) {
|
||||
if (!options) {
|
||||
options = {};
|
||||
}
|
||||
return driver
|
||||
.context(webviewContext)
|
||||
.setAsyncScriptTimeout(MINUTE)
|
||||
.executeAsync(cameraHelper.checkPicture, [getCurrentPromiseId()])
|
||||
.setAsyncScriptTimeout(MINUTE / 2)
|
||||
.executeAsync(cameraHelper.checkPicture, [getCurrentPromiseId(), options])
|
||||
.then(function (result) {
|
||||
if (shouldLoad) {
|
||||
expect(result.length).toBeGreaterThan(0);
|
||||
if (result.indexOf('ERROR') >= 0) {
|
||||
return fail(result);
|
||||
if (result !== 'OK') {
|
||||
fail(result);
|
||||
}
|
||||
} else {
|
||||
if (result.indexOf('ERROR') === -1) {
|
||||
return fail('Unexpected success callback with result: ' + result);
|
||||
}
|
||||
expect(result.indexOf('ERROR')).toBe(0);
|
||||
} else if (result.indexOf('ERROR') === -1) {
|
||||
throw 'Unexpected success callback with result: ' + result;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function runCombinedSpec(spec) {
|
||||
// takes a picture with the specified options
|
||||
// and then verifies it
|
||||
function runSpec(options) {
|
||||
return driver
|
||||
.then(function () {
|
||||
return getPicture(spec.options);
|
||||
return getPicture(options);
|
||||
})
|
||||
.then(function () {
|
||||
return checkPicture(true);
|
||||
return checkPicture(true, options);
|
||||
})
|
||||
.fail(saveScreenshotAndFail);
|
||||
}
|
||||
@@ -203,15 +190,25 @@ describe('Camera tests iOS.', function () {
|
||||
});
|
||||
}
|
||||
|
||||
function checkSession(done) {
|
||||
if (failedToStart) {
|
||||
fail('Failed to start a session');
|
||||
done();
|
||||
}
|
||||
}
|
||||
|
||||
it('camera.ui.util configure driver and start a session', function (done) {
|
||||
getDriver()
|
||||
.fail(fail)
|
||||
.finally(done);
|
||||
}, 5 * MINUTE);
|
||||
.then(function () {
|
||||
failedToStart = false;
|
||||
}, fail)
|
||||
.done(done);
|
||||
}, 10 * MINUTE);
|
||||
|
||||
describe('Specs.', function () {
|
||||
// getPicture() with mediaType: VIDEO, sourceType: PHOTOLIBRARY
|
||||
it('camera.ui.spec.1 Selecting only videos', function (done) {
|
||||
checkSession(done);
|
||||
var options = { sourceType: cameraConstants.PictureSourceType.PHOTOLIBRARY,
|
||||
mediaType: cameraConstants.MediaType.VIDEO };
|
||||
driver
|
||||
@@ -227,11 +224,12 @@ describe('Camera tests iOS.', function () {
|
||||
// getPicture(), then dismiss
|
||||
// wait for the error callback to be called
|
||||
it('camera.ui.spec.2 Dismissing the camera', function (done) {
|
||||
// camera is not available on the iOS simulator
|
||||
checkSession(done);
|
||||
if (!isDevice) {
|
||||
pending();
|
||||
pending('Camera is not available on iOS simulator');
|
||||
}
|
||||
var options = { sourceType: cameraConstants.PictureSourceType.CAMERA };
|
||||
var options = { sourceType: cameraConstants.PictureSourceType.CAMERA,
|
||||
saveToPhotoAlbum: false };
|
||||
driver
|
||||
.then(function () {
|
||||
return getPicture(options, true);
|
||||
@@ -243,22 +241,177 @@ describe('Camera tests iOS.', function () {
|
||||
.done(done);
|
||||
}, 3 * MINUTE);
|
||||
|
||||
it('camera.ui.spec.3 Verifying target image size, sourceType=CAMERA', function (done) {
|
||||
checkSession(done);
|
||||
if (!isDevice) {
|
||||
pending('Camera is not available on iOS simulator');
|
||||
}
|
||||
var options = {
|
||||
quality: 50,
|
||||
allowEdit: false,
|
||||
sourceType: cameraConstants.PictureSourceType.CAMERA,
|
||||
saveToPhotoAlbum: false,
|
||||
targetWidth: 210,
|
||||
targetHeight: 210
|
||||
};
|
||||
|
||||
runSpec(options).done(done);
|
||||
}, 3 * MINUTE);
|
||||
|
||||
it('camera.ui.spec.4 Verifying target image size, sourceType=SAVEDPHOTOALBUM', function (done) {
|
||||
checkSession(done);
|
||||
var options = {
|
||||
quality: 50,
|
||||
allowEdit: false,
|
||||
sourceType: cameraConstants.PictureSourceType.SAVEDPHOTOALBUM,
|
||||
saveToPhotoAlbum: false,
|
||||
targetWidth: 210,
|
||||
targetHeight: 210
|
||||
};
|
||||
|
||||
runSpec(options).done(done);
|
||||
}, 3 * MINUTE);
|
||||
|
||||
it('camera.ui.spec.5 Verifying target image size, sourceType=PHOTOLIBRARY', function (done) {
|
||||
checkSession(done);
|
||||
var options = {
|
||||
quality: 50,
|
||||
allowEdit: false,
|
||||
sourceType: cameraConstants.PictureSourceType.PHOTOLIBRARY,
|
||||
saveToPhotoAlbum: false,
|
||||
targetWidth: 210,
|
||||
targetHeight: 210
|
||||
};
|
||||
|
||||
runSpec(options).done(done);
|
||||
}, 3 * MINUTE);
|
||||
|
||||
it('camera.ui.spec.6 Verifying target image size, sourceType=CAMERA, destinationType=FILE_URL', function (done) {
|
||||
// remove this line if you don't mind the tests leaving a photo saved on device
|
||||
pending('Cannot prevent iOS from saving the picture to photo library');
|
||||
|
||||
checkSession(done);
|
||||
if (!isDevice) {
|
||||
pending('Camera is not available on iOS simulator');
|
||||
}
|
||||
var options = {
|
||||
quality: 50,
|
||||
allowEdit: false,
|
||||
sourceType: cameraConstants.PictureSourceType.CAMERA,
|
||||
destinationType: cameraConstants.DestinationType.FILE_URL,
|
||||
saveToPhotoAlbum: false,
|
||||
targetWidth: 210,
|
||||
targetHeight: 210
|
||||
};
|
||||
|
||||
runSpec(options).done(done);
|
||||
}, 3 * MINUTE);
|
||||
|
||||
it('camera.ui.spec.7 Verifying target image size, sourceType=SAVEDPHOTOALBUM, destinationType=FILE_URL', function (done) {
|
||||
checkSession(done);
|
||||
var options = {
|
||||
quality: 50,
|
||||
allowEdit: false,
|
||||
sourceType: cameraConstants.PictureSourceType.SAVEDPHOTOALBUM,
|
||||
destinationType: cameraConstants.DestinationType.FILE_URL,
|
||||
saveToPhotoAlbum: false,
|
||||
targetWidth: 210,
|
||||
targetHeight: 210
|
||||
};
|
||||
|
||||
runSpec(options).done(done);
|
||||
}, 3 * MINUTE);
|
||||
|
||||
it('camera.ui.spec.8 Verifying target image size, sourceType=PHOTOLIBRARY, destinationType=FILE_URL', function (done) {
|
||||
checkSession(done);
|
||||
var options = {
|
||||
quality: 50,
|
||||
allowEdit: false,
|
||||
sourceType: cameraConstants.PictureSourceType.PHOTOLIBRARY,
|
||||
destinationType: cameraConstants.DestinationType.FILE_URL,
|
||||
saveToPhotoAlbum: false,
|
||||
targetWidth: 210,
|
||||
targetHeight: 210
|
||||
};
|
||||
|
||||
runSpec(options).done(done);
|
||||
}, 3 * MINUTE);
|
||||
|
||||
it('camera.ui.spec.9 Verifying target image size, sourceType=CAMERA, destinationType=FILE_URL, quality=100', function (done) {
|
||||
// remove this line if you don't mind the tests leaving a photo saved on device
|
||||
pending('Cannot prevent iOS from saving the picture to photo library');
|
||||
|
||||
checkSession(done);
|
||||
if (!isDevice) {
|
||||
pending('Camera is not available on iOS simulator');
|
||||
}
|
||||
var options = {
|
||||
quality: 100,
|
||||
allowEdit: false,
|
||||
sourceType: cameraConstants.PictureSourceType.CAMERA,
|
||||
destinationType: cameraConstants.DestinationType.FILE_URL,
|
||||
saveToPhotoAlbum: false,
|
||||
targetWidth: 305,
|
||||
targetHeight: 305
|
||||
};
|
||||
runSpec(options).done(done);
|
||||
}, 3 * MINUTE);
|
||||
|
||||
it('camera.ui.spec.10 Verifying target image size, sourceType=SAVEDPHOTOALBUM, destinationType=FILE_URL, quality=100', function (done) {
|
||||
checkSession(done);
|
||||
var options = {
|
||||
quality: 100,
|
||||
allowEdit: false,
|
||||
sourceType: cameraConstants.PictureSourceType.SAVEDPHOTOALBUM,
|
||||
destinationType: cameraConstants.DestinationType.FILE_URL,
|
||||
saveToPhotoAlbum: false,
|
||||
targetWidth: 305,
|
||||
targetHeight: 305
|
||||
};
|
||||
|
||||
runSpec(options).done(done);
|
||||
}, 3 * MINUTE);
|
||||
|
||||
it('camera.ui.spec.11 Verifying target image size, sourceType=PHOTOLIBRARY, destinationType=FILE_URL, quality=100', function (done) {
|
||||
checkSession(done);
|
||||
var options = {
|
||||
quality: 100,
|
||||
allowEdit: false,
|
||||
sourceType: cameraConstants.PictureSourceType.PHOTOLIBRARY,
|
||||
destinationType: cameraConstants.DestinationType.FILE_URL,
|
||||
saveToPhotoAlbum: false,
|
||||
targetWidth: 305,
|
||||
targetHeight: 305
|
||||
};
|
||||
|
||||
runSpec(options).done(done);
|
||||
}, 3 * MINUTE);
|
||||
|
||||
// combine various options for getPicture()
|
||||
generateSpecs().forEach(function (spec) {
|
||||
it('camera.ui.spec.3.' + spec.id + ' Combining options', function (done) {
|
||||
// camera is not available on iOS simulator
|
||||
generateOptions().forEach(function (spec) {
|
||||
it('camera.ui.spec.12.' + spec.id + ' Combining options. ' + spec.description, function (done) {
|
||||
checkSession(done);
|
||||
if (!isDevice && spec.options.sourceType === cameraConstants.PictureSourceType.CAMERA) {
|
||||
pending();
|
||||
pending('Camera is not available on iOS simulator');
|
||||
}
|
||||
runCombinedSpec(spec).done(done);
|
||||
|
||||
// remove this check if you don't mind the tests leaving a photo saved on device
|
||||
if (spec.options.sourceType === cameraConstants.PictureSourceType.CAMERA &&
|
||||
spec.options.destinationType === cameraConstants.DestinationType.NATIVE_URI) {
|
||||
pending('Skipping: cannot prevent iOS from saving the picture to photo library and cannot delete it. ' +
|
||||
'For more info, see iOS quirks here: https://github.com/apache/cordova-plugin-camera#ios-quirks-1');
|
||||
}
|
||||
|
||||
runSpec(spec.options).done(done);
|
||||
}, 3 * MINUTE);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('camera.ui.util.4 Destroy the session', function (done) {
|
||||
it('camera.ui.util Destroy the session', function (done) {
|
||||
checkSession(done);
|
||||
driver
|
||||
.quit()
|
||||
.done(done);
|
||||
}, MINUTE);
|
||||
}, 5 * MINUTE);
|
||||
});
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
---
|
||||
title: Camera
|
||||
description: Take pictures with the device camera.
|
||||
---
|
||||
{{>cdv-license~}}
|
||||
|
||||
[](https://travis-ci.org/apache/cordova-plugin-camera)
|
||||
|Android|iOS| Windows 8.1 Store | Windows 8.1 Phone | Windows 10 Store | Travis CI |
|
||||
|:-:|:-:|:-:|:-:|:-:|:-:|
|
||||
|[](http://cordova-ci.cloudapp.net:8080/job/cordova-periodic-build/PLATFORM=android,PLUGIN=cordova-plugin-camera/)|[](http://cordova-ci.cloudapp.net:8080/job/cordova-periodic-build/PLATFORM=ios,PLUGIN=cordova-plugin-camera/)|[](http://cordova-ci.cloudapp.net:8080/job/cordova-periodic-build/PLATFORM=windows-8.1-store,PLUGIN=cordova-plugin-camera/)|[](http://cordova-ci.cloudapp.net:8080/job/cordova-periodic-build/PLATFORM=windows-8.1-phone,PLUGIN=cordova-plugin-camera/)|[](http://cordova-ci.cloudapp.net:8080/job/cordova-periodic-build/PLATFORM=windows-10-store,PLUGIN=cordova-plugin-camera/)|[](https://travis-ci.org/apache/cordova-plugin-camera)
|
||||
|
||||
# cordova-plugin-camera
|
||||
|
||||
@@ -9,9 +15,30 @@ the system's image library.
|
||||
|
||||
{{>cdv-header device-ready-warning-obj='navigator.camera' npmName='cordova-plugin-camera' cprName='org.apache.cordova.camera' pluginName='Plugin Camera' repoUrl='https://github.com/apache/cordova-plugin-camera' }}
|
||||
|
||||
|
||||
### iOS Quirks
|
||||
|
||||
Since iOS 10 it's mandatory to add a `NSCameraUsageDescription` and `NSPhotoLibraryUsageDescription` in the info.plist.
|
||||
|
||||
- `NSCameraUsageDescription` describes the reason that the app accesses the user’s camera.
|
||||
- `NSPhotoLibraryUsageDescription` describes the reason the app accesses the user's photo library.
|
||||
|
||||
When the system prompts the user to allow access, this string is displayed as part of the dialog box.
|
||||
|
||||
To add this entry you can pass the following variables on plugin install.
|
||||
|
||||
- `CAMERA_USAGE_DESCRIPTION` for `NSCameraUsageDescription`
|
||||
- `PHOTOLIBRARY_USAGE_DESCRIPTION` for `NSPhotoLibraryUsageDescription`
|
||||
|
||||
Example:
|
||||
|
||||
cordova plugin add cordova-plugin-camera --variable CAMERA_USAGE_DESCRIPTION="your usage message" --variable PHOTOLIBRARY_USAGE_DESCRIPTION="your usage message"
|
||||
|
||||
If you don't pass the variable, the plugin will add an empty string as value.
|
||||
|
||||
---
|
||||
|
||||
# API Reference
|
||||
# API Reference <a name="reference"></a>
|
||||
|
||||
{{#orphans~}}
|
||||
{{>member-index}}
|
||||
@@ -116,6 +143,16 @@ displays:
|
||||
Invoking the native camera application while the device is connected
|
||||
via Zune does not work, and triggers an error callback.
|
||||
|
||||
#### Windows quirks
|
||||
|
||||
On Windows Phone 8.1 using `SAVEDPHOTOALBUM` or `PHOTOLIBRARY` as a source type causes application to suspend until file picker returns the selected image and
|
||||
then restore with start page as defined in app's `config.xml`. In case when `camera.getPicture` was called from different page, this will lead to reloading
|
||||
start page from scratch and success and error callbacks will never be called.
|
||||
|
||||
To avoid this we suggest using SPA pattern or call `camera.getPicture` only from your app's start page.
|
||||
|
||||
More information about Windows Phone 8.1 picker APIs is here: [How to continue your Windows Phone app after calling a file picker](https://msdn.microsoft.com/en-us/library/windows/apps/dn720490.aspx)
|
||||
|
||||
#### Tizen Quirks
|
||||
|
||||
Tizen only supports a `destinationType` of
|
||||
@@ -181,6 +218,8 @@ Tizen only supports a `destinationType` of
|
||||
|
||||
- When using `destinationType.NATIVE_URI` and `sourceType.CAMERA`, photos are saved in the saved photo album regardless on the value of `saveToPhotoAlbum` parameter.
|
||||
|
||||
- When using `destinationType.NATIVE_URI` and `sourceType.PHOTOLIBRARY` or `sourceType.SAVEDPHOTOALBUM`, all editing options are ignored and link is returned to original picture.
|
||||
|
||||
#### Tizen Quirks
|
||||
|
||||
- options not supported
|
||||
@@ -203,3 +242,202 @@ Tizen only supports a `destinationType` of
|
||||
[web_activities]: https://hacks.mozilla.org/2013/01/introducing-web-activities/
|
||||
[wp8_bug]: https://issues.apache.org/jira/browse/CB-2083
|
||||
[msdn_wp8_docs]: http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh394006.aspx
|
||||
|
||||
## Sample: Take Pictures, Select Pictures from the Picture Library, and Get Thumbnails <a name="sample"></a>
|
||||
|
||||
The Camera plugin allows you to do things like open the device's Camera app and take a picture, or open the file picker and select one. The code snippets in this section demonstrate different tasks including:
|
||||
|
||||
* Open the Camera app and [take a Picture](#takePicture)
|
||||
* Take a picture and [return thumbnails](#getThumbnails) (resized picture)
|
||||
* Take a picture and [generate a FileEntry object](#convert)
|
||||
* [Select a file](#selectFile) from the picture library
|
||||
* Select a JPEG image and [return thumbnails](#getFileThumbnails) (resized image)
|
||||
* Select an image and [generate a FileEntry object](#convert)
|
||||
|
||||
## Take a Picture <a name="takePicture"></a>
|
||||
|
||||
Before you can take a picture, you need to set some Camera plugin options to pass into the Camera plugin's `getPicture` function. Here is a common set of recommendations. In this example, you create the object that you will use for the Camera options, and set the `sourceType` dynamically to support both the Camera app and the file picker.
|
||||
|
||||
```js
|
||||
function setOptions(srcType) {
|
||||
var options = {
|
||||
// Some common settings are 20, 50, and 100
|
||||
quality: 50,
|
||||
destinationType: Camera.DestinationType.FILE_URI,
|
||||
// In this app, dynamically set the picture source, Camera or photo gallery
|
||||
sourceType: srcType,
|
||||
encodingType: Camera.EncodingType.JPEG,
|
||||
mediaType: Camera.MediaType.PICTURE,
|
||||
allowEdit: true,
|
||||
correctOrientation: true //Corrects Android orientation quirks
|
||||
}
|
||||
return options;
|
||||
}
|
||||
```
|
||||
|
||||
Typically, you want to use a FILE_URI instead of a DATA_URL to avoid most memory issues. JPEG is the recommended encoding type for Android.
|
||||
|
||||
You take a picture by passing in the options object to `getPicture`, which takes a CameraOptions object as the third argument. When you call `setOptions`, pass `Camera.PictureSourceType.CAMERA` as the picture source.
|
||||
|
||||
```js
|
||||
function openCamera(selection) {
|
||||
|
||||
var srcType = Camera.PictureSourceType.CAMERA;
|
||||
var options = setOptions(srcType);
|
||||
var func = createNewFileEntry;
|
||||
|
||||
navigator.camera.getPicture(function cameraSuccess(imageUri) {
|
||||
|
||||
displayImage(imageUri);
|
||||
// You may choose to copy the picture, save it somewhere, or upload.
|
||||
func(imageUri);
|
||||
|
||||
}, function cameraError(error) {
|
||||
console.debug("Unable to obtain picture: " + error, "app");
|
||||
|
||||
}, options);
|
||||
}
|
||||
```
|
||||
|
||||
Once you take the picture, you can display it or do something else. In this example, call the app's `displayImage` function from the preceding code.
|
||||
|
||||
```js
|
||||
function displayImage(imgUri) {
|
||||
|
||||
var elem = document.getElementById('imageFile');
|
||||
elem.src = imgUri;
|
||||
}
|
||||
```
|
||||
|
||||
To display the image on some platforms, you might need to include the main part of the URI in the Content-Security-Policy `<meta>` element in index.html. For example, on Windows 10, you can include `ms-appdata:` in your `<meta>` element. Here is an example.
|
||||
|
||||
```html
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: ms-appdata: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *">
|
||||
```
|
||||
|
||||
## Take a Picture and Return Thumbnails (Resize the Picture) <a name="getThumbnails"></a>
|
||||
|
||||
To get smaller images, you can return a resized image by passing both `targetHeight` and `targetWidth` values with your CameraOptions object. In this example, you resize the returned image to fit in a 100px by 100px box (the aspect ratio is maintained, so 100px is either the height or width, whichever is greater in the source).
|
||||
|
||||
```js
|
||||
function openCamera(selection) {
|
||||
|
||||
var srcType = Camera.PictureSourceType.CAMERA;
|
||||
var options = setOptions(srcType);
|
||||
var func = createNewFileEntry;
|
||||
|
||||
if (selection == "camera-thmb") {
|
||||
options.targetHeight = 100;
|
||||
options.targetWidth = 100;
|
||||
}
|
||||
|
||||
navigator.camera.getPicture(function cameraSuccess(imageUri) {
|
||||
|
||||
// Do something
|
||||
|
||||
}, function cameraError(error) {
|
||||
console.debug("Unable to obtain picture: " + error, "app");
|
||||
|
||||
}, options);
|
||||
}
|
||||
```
|
||||
|
||||
## 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.
|
||||
|
||||
```js
|
||||
function openFilePicker(selection) {
|
||||
|
||||
var srcType = Camera.PictureSourceType.SAVEDPHOTOALBUM;
|
||||
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);
|
||||
}
|
||||
```
|
||||
|
||||
## Select an Image and Return Thumbnails (resized images) <a name="getFileThumbnails"></a>
|
||||
|
||||
Resizing a file selected with the file picker works just like resizing using the Camera app; set the `targetHeight` and `targetWidth` options.
|
||||
|
||||
```js
|
||||
function openFilePicker(selection) {
|
||||
|
||||
var srcType = Camera.PictureSourceType.SAVEDPHOTOALBUM;
|
||||
var options = setOptions(srcType);
|
||||
var func = createNewFileEntry;
|
||||
|
||||
if (selection == "picker-thmb") {
|
||||
// To downscale a selected image,
|
||||
// Camera.EncodingType (e.g., JPEG) must match the selected image type.
|
||||
options.targetHeight = 100;
|
||||
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);
|
||||
}
|
||||
```
|
||||
|
||||
## Take a picture and get a FileEntry Object <a name="convert"></a>
|
||||
|
||||
If you want to do something like copy the image to another location, or upload it somewhere using the FileTransfer plugin, you need to get a FileEntry object for the returned picture. To do that, call `window.resolveLocalFileSystemURL` on the file URI returned by the Camera app. If you need to use a FileEntry object, set the `destinationType` to `Camera.DestinationType.FILE_URI` in your CameraOptions object (this is also the default value).
|
||||
|
||||
>*Note* You need the [File plugin](https://www.npmjs.com/package/cordova-plugin-file) to call `window.resolveLocalFileSystemURL`.
|
||||
|
||||
Here is the call to `window.resolveLocalFileSystemURL`. The image URI is passed to this function from the success callback of `getPicture`. The success handler of `resolveLocalFileSystemURL` receives the FileEntry object.
|
||||
|
||||
```js
|
||||
function getFileEntry(imgUri) {
|
||||
window.resolveLocalFileSystemURL(imgUri, function success(fileEntry) {
|
||||
|
||||
// Do something with the FileEntry object, like write to it, upload it, etc.
|
||||
// writeFile(fileEntry, imgUri);
|
||||
console.log("got file: " + fileEntry.fullPath);
|
||||
// displayFileData(fileEntry.nativeURL, "Native URL");
|
||||
|
||||
}, function () {
|
||||
// If don't get the FileEntry (which may happen when testing
|
||||
// on some emulators), copy to a new FileEntry.
|
||||
createNewFileEntry(imgUri);
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
In the example shown in the preceding code, you call the app's `createNewFileEntry` function if you don't get a valid FileEntry object. The image URI returned from the Camera app should result in a valid FileEntry, but platform behavior on some emulators may be different for files returned from the file picker.
|
||||
|
||||
>*Note* To see an example of writing to a FileEntry, see the [File plugin README](https://www.npmjs.com/package/cordova-plugin-file).
|
||||
|
||||
The code shown here creates a file in your app's cache (in sandboxed storage) named `tempFile.jpeg`. With the new FileEntry object, you can copy the image to the file or do something else like upload it.
|
||||
|
||||
```js
|
||||
function createNewFileEntry(imgUri) {
|
||||
window.resolveLocalFileSystemURL(cordova.file.cacheDirectory, function success(dirEntry) {
|
||||
|
||||
// JPEG file
|
||||
dirEntry.getFile("tempFile.jpeg", { create: true, exclusive: false }, function (fileEntry) {
|
||||
|
||||
// Do something with it, like write to it, upload it, etc.
|
||||
// writeFile(fileEntry, imgUri);
|
||||
console.log("got file: " + fileEntry.fullPath);
|
||||
// displayFileData(fileEntry.fullPath, "File copied to");
|
||||
|
||||
}, onErrorCreateFile);
|
||||
|
||||
}, onErrorResolveUrl);
|
||||
}
|
||||
```
|
||||
|
||||
12
package.json
12
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cordova-plugin-camera",
|
||||
"version": "2.2.0",
|
||||
"version": "2.3.1",
|
||||
"description": "Cordova Camera Plugin",
|
||||
"cordova": {
|
||||
"id": "cordova-plugin-camera",
|
||||
@@ -38,9 +38,6 @@
|
||||
"cordova-browser",
|
||||
"cordova-windows"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"cordova-plugin-file": ">=2.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"precommit": "npm run gen-docs && git add README.md",
|
||||
"gen-docs": "jsdoc2md --template \"jsdoc2md/TEMPLATE.md\" \"www/**/*.js\" --plugin \"dmd-plugin-cordova-plugin\" > README.md",
|
||||
@@ -49,6 +46,13 @@
|
||||
},
|
||||
"author": "Apache Software Foundation",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"cordovaDependencies": {
|
||||
"3.0.0": {
|
||||
"cordova": ">100"
|
||||
}
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"dmd-plugin-cordova-plugin": "^0.1.0",
|
||||
"husky": "^0.10.1",
|
||||
|
||||
33
plugin.xml
33
plugin.xml
@@ -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"
|
||||
version="2.2.0">
|
||||
version="2.3.1">
|
||||
<name>Camera</name>
|
||||
<description>Cordova Camera Plugin</description>
|
||||
<license>Apache 2.0</license>
|
||||
@@ -30,7 +30,7 @@
|
||||
<repo>https://git-wip-us.apache.org/repos/asf/cordova-plugin-camera.git</repo>
|
||||
<issue>https://issues.apache.org/jira/browse/CB/component/12320645</issue>
|
||||
|
||||
<dependency id="cordova-plugin-compat" version="^1.0.0" />
|
||||
<dependency id="cordova-plugin-compat" version="^1.1.0" />
|
||||
|
||||
<js-module src="www/CameraConstants.js" name="Camera">
|
||||
<clobbers target="Camera" />
|
||||
@@ -69,16 +69,31 @@
|
||||
<config-file target="AndroidManifest.xml" parent="/*">
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
</config-file>
|
||||
<config-file target="AndroidManifest.xml" parent="application">
|
||||
<provider
|
||||
android:name="android.support.v4.content.FileProvider"
|
||||
android:authorities="${applicationId}.provider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true" >
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/provider_paths"/>
|
||||
</provider>
|
||||
</config-file>
|
||||
|
||||
<source-file src="src/android/CameraLauncher.java" target-dir="src/org/apache/cordova/camera" />
|
||||
<source-file src="src/android/CordovaUri.java" target-dir="src/org/apache/cordova/camera" />
|
||||
<source-file src="src/android/FileHelper.java" target-dir="src/org/apache/cordova/camera" />
|
||||
<source-file src="src/android/ExifHelper.java" target-dir="src/org/apache/cordova/camera" />
|
||||
<source-file src="src/android/xml/provider_paths.xml" target-dir="res/xml" />
|
||||
|
||||
<js-module src="www/CameraPopoverHandle.js" name="CameraPopoverHandle">
|
||||
<clobbers target="CameraPopoverHandle" />
|
||||
</js-module>
|
||||
</js-module>
|
||||
|
||||
</platform>
|
||||
<framework src="com.android.support:support-v4:24.1.1+" />
|
||||
|
||||
</platform>
|
||||
|
||||
<!-- amazon-fireos -->
|
||||
<platform name="amazon-fireos">
|
||||
@@ -150,6 +165,16 @@
|
||||
<framework src="CoreGraphics.framework" />
|
||||
<framework src="AVFoundation.framework" />
|
||||
|
||||
<preference name="CAMERA_USAGE_DESCRIPTION" default=" " />
|
||||
<config-file target="*-Info.plist" parent="NSCameraUsageDescription">
|
||||
<string>$CAMERA_USAGE_DESCRIPTION</string>
|
||||
</config-file>
|
||||
|
||||
<preference name="PHOTOLIBRARY_USAGE_DESCRIPTION" default=" " />
|
||||
<config-file target="*-Info.plist" parent="NSPhotoLibraryUsageDescription">
|
||||
<string>$PHOTOLIBRARY_USAGE_DESCRIPTION</string>
|
||||
</config-file>
|
||||
|
||||
<config-file target="*-Info.plist" parent="NSLocationWhenInUseUsageDescription">
|
||||
<string></string>
|
||||
</config-file>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
104
src/android/CordovaUri.java
Normal file
104
src/android/CordovaUri.java
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
package org.apache.cordova.camera;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.support.v4.content.FileProvider;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/*
|
||||
* This class exists because Andorid FilesProvider doesn't work on Android 4.4.4 and below and throws
|
||||
* weird errors. I'm not sure why writing to shared cache directories is somehow verboten, but it is
|
||||
* and this error is irritating for a Compatibility library to have.
|
||||
*
|
||||
*/
|
||||
|
||||
public class CordovaUri {
|
||||
|
||||
private Uri androidUri;
|
||||
private String fileName;
|
||||
private Uri fileUri;
|
||||
|
||||
/*
|
||||
* We always expect a FileProvider string to be passed in for the file that we create
|
||||
*
|
||||
*/
|
||||
CordovaUri (Uri inputUri)
|
||||
{
|
||||
//Determine whether the file is a content or file URI
|
||||
if(inputUri.getScheme().equals("content"))
|
||||
{
|
||||
androidUri = inputUri;
|
||||
fileName = getFileNameFromUri(androidUri);
|
||||
fileUri = Uri.parse("file://" + fileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
fileUri = inputUri;
|
||||
fileName = FileHelper.stripFileProtocol(inputUri.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public Uri getFileUri()
|
||||
{
|
||||
return fileUri;
|
||||
}
|
||||
|
||||
public String getFilePath()
|
||||
{
|
||||
return fileName;
|
||||
}
|
||||
|
||||
/*
|
||||
* This only gets called by takePicture
|
||||
*/
|
||||
|
||||
public Uri getCorrectUri()
|
||||
{
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
||||
return androidUri;
|
||||
else
|
||||
return fileUri;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is dirty, but it does the job.
|
||||
*
|
||||
* Since the FilesProvider doesn't really provide you a way of getting a URL from the file,
|
||||
* and since we actually need the Camera to create the file for us most of the time, we don't
|
||||
* actually write the file, just generate the location based on a timestamp, we need to get it
|
||||
* back from the Intent.
|
||||
*
|
||||
* However, the FilesProvider preserves the path, so we can at least write to it from here, since
|
||||
* we own the context in this case.
|
||||
*/
|
||||
|
||||
private String getFileNameFromUri(Uri uri) {
|
||||
String fullUri = uri.toString();
|
||||
String partial_path = fullUri.split("external_files")[1];
|
||||
File external_storage = Environment.getExternalStorageDirectory();
|
||||
String path = external_storage.getAbsolutePath() + partial_path;
|
||||
return path;
|
||||
|
||||
}
|
||||
}
|
||||
21
src/android/xml/provider_paths.xml
Normal file
21
src/android/xml/provider_paths.xml
Normal file
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<paths xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<external-path name="external_files" path="."/>
|
||||
</paths>
|
||||
@@ -23,11 +23,12 @@ var HIGHEST_POSSIBLE_Z_INDEX = 2147483647;
|
||||
|
||||
function takePicture(success, error, opts) {
|
||||
if (opts && opts[2] === 1) {
|
||||
capture(success, error);
|
||||
capture(success, error, opts);
|
||||
} else {
|
||||
var input = document.createElement('input');
|
||||
input.style.position = 'relative';
|
||||
input.style.zIndex = HIGHEST_POSSIBLE_Z_INDEX;
|
||||
input.className = 'cordova-camera-select';
|
||||
input.type = 'file';
|
||||
input.name = 'files[]';
|
||||
|
||||
@@ -48,28 +49,36 @@ function takePicture(success, error, opts) {
|
||||
}
|
||||
}
|
||||
|
||||
function capture(success, errorCallback) {
|
||||
function capture(success, errorCallback, opts) {
|
||||
var localMediaStream;
|
||||
var targetWidth = opts[3];
|
||||
var targetHeight = opts[4];
|
||||
|
||||
targetWidth = targetWidth == -1?320:targetWidth;
|
||||
targetHeight = targetHeight == -1?240:targetHeight;
|
||||
|
||||
var video = document.createElement('video');
|
||||
var button = document.createElement('button');
|
||||
var parent = document.createElement('div');
|
||||
parent.style.position = 'relative';
|
||||
parent.style.zIndex = HIGHEST_POSSIBLE_Z_INDEX;
|
||||
parent.className = 'cordova-camera-capture';
|
||||
parent.appendChild(video);
|
||||
parent.appendChild(button);
|
||||
|
||||
video.width = 320;
|
||||
video.height = 240;
|
||||
video.width = targetWidth;
|
||||
video.height = targetHeight;
|
||||
button.innerHTML = 'Capture!';
|
||||
|
||||
button.onclick = function() {
|
||||
// create a canvas and capture a frame from video stream
|
||||
var canvas = document.createElement('canvas');
|
||||
canvas.getContext('2d').drawImage(video, 0, 0, 320, 240);
|
||||
canvas.width = targetWidth;
|
||||
canvas.height = targetHeight;
|
||||
canvas.getContext('2d').drawImage(video, 0, 0, targetWidth, targetHeight);
|
||||
|
||||
// convert image stored in canvas to base64 encoded image
|
||||
var imageData = canvas.toDataURL('img/png');
|
||||
var imageData = canvas.toDataURL('image/png');
|
||||
imageData = imageData.replace('data:image/png;base64,', '');
|
||||
|
||||
// stop video stream, remove video and button.
|
||||
|
||||
@@ -240,9 +240,13 @@ static NSString* toBase64(NSData* data) {
|
||||
|
||||
- (void)repositionPopover:(CDVInvokedUrlCommand*)command
|
||||
{
|
||||
NSDictionary* options = [command argumentAtIndex:0 withDefault:nil];
|
||||
if (([[self pickerController] pickerPopoverController] != nil) && [[[self pickerController] pickerPopoverController] isPopoverVisible]) {
|
||||
|
||||
[self displayPopover:options];
|
||||
[[[self pickerController] pickerPopoverController] dismissPopoverAnimated:NO];
|
||||
|
||||
NSDictionary* options = [command argumentAtIndex:0 withDefault:nil];
|
||||
[self displayPopover:options];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSInteger)integerValueForKey:(NSDictionary*)dict key:(NSString*)key defaultValue:(NSInteger)defaultValue
|
||||
@@ -520,9 +524,11 @@ static NSString* toBase64(NSData* data) {
|
||||
NSString* mediaType = [info objectForKey:UIImagePickerControllerMediaType];
|
||||
if ([mediaType isEqualToString:(NSString*)kUTTypeImage]) {
|
||||
[weakSelf resultForImage:cameraPicker.pictureOptions info:info completion:^(CDVPluginResult* res) {
|
||||
[weakSelf.commandDelegate sendPluginResult:res callbackId:cameraPicker.callbackId];
|
||||
weakSelf.hasPendingOperation = NO;
|
||||
weakSelf.pickerController = nil;
|
||||
if (![self usesGeolocation] || picker.sourceType != UIImagePickerControllerSourceTypeCamera) {
|
||||
[weakSelf.commandDelegate sendPluginResult:res callbackId:cameraPicker.callbackId];
|
||||
weakSelf.hasPendingOperation = NO;
|
||||
weakSelf.pickerController = nil;
|
||||
}
|
||||
}];
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -79,10 +79,14 @@ var HIGHEST_POSSIBLE_Z_INDEX = 2147483647;
|
||||
// Resize method
|
||||
function resizeImage(successCallback, errorCallback, file, targetWidth, targetHeight, encodingType) {
|
||||
var tempPhotoFileName = "";
|
||||
var targetContentType = "";
|
||||
|
||||
if (encodingType == Camera.EncodingType.PNG) {
|
||||
tempPhotoFileName = "camera_cordova_temp_return.png";
|
||||
targetContentType = "image/png";
|
||||
} else {
|
||||
tempPhotoFileName = "camera_cordova_temp_return.jpg";
|
||||
targetContentType = "image/jpeg";
|
||||
}
|
||||
|
||||
var storageFolder = getAppData().localFolder;
|
||||
@@ -108,7 +112,7 @@ function resizeImage(successCallback, errorCallback, file, targetWidth, targetHe
|
||||
|
||||
canvas.getContext("2d").drawImage(this, 0, 0, imageWidth, imageHeight);
|
||||
|
||||
var fileContent = canvas.toDataURL(file.contentType).split(',')[1];
|
||||
var fileContent = canvas.toDataURL(targetContentType).split(',')[1];
|
||||
|
||||
var storageFolder = getAppData().localFolder;
|
||||
|
||||
@@ -745,7 +749,7 @@ function takePictureFromCameraWindows(successCallback, errorCallback, args) {
|
||||
cameraCaptureUI.photoSettings.maxResolution = maxRes;
|
||||
|
||||
var cameraPicture;
|
||||
|
||||
|
||||
// define focus handler for windows phone 10.0
|
||||
var savePhotoOnFocus = function () {
|
||||
window.removeEventListener("focus", savePhotoOnFocus);
|
||||
@@ -760,7 +764,7 @@ function takePictureFromCameraWindows(successCallback, errorCallback, args) {
|
||||
};
|
||||
|
||||
// if windows phone 10, add and delete focus eventHandler to capture the focus back from cameraUI to app
|
||||
if (navigator.appVersion.indexOf('Windows Phone 10.0') >= 0) {
|
||||
if (navigator.appVersion.indexOf('Windows Phone 10.0') >= 0) {
|
||||
window.addEventListener("focus", savePhotoOnFocus);
|
||||
}
|
||||
|
||||
|
||||
@@ -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="2.2.0">
|
||||
version="2.3.1">
|
||||
<name>Cordova Camera Plugin Tests</name>
|
||||
<license>Apache 2.0</license>
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/* globals Camera, resolveLocalFileSystemURI, FileEntry, CameraPopoverOptions, FileTransfer, FileUploadOptions, LocalFileSystem, MSApp */
|
||||
/* globals Camera, resolveLocalFileSystemURL, FileEntry, CameraPopoverOptions, FileTransfer, FileUploadOptions, LocalFileSystem, MSApp */
|
||||
/* jshint jasmine: true */
|
||||
|
||||
exports.defineAutoTests = function () {
|
||||
@@ -142,11 +142,11 @@ exports.defineManualTests = function (contentEl, createActionButton) {
|
||||
setPicture(data);
|
||||
// TODO: Fix resolveLocalFileSystemURI to work with native-uri.
|
||||
if (pictureUrl.indexOf('file:') === 0 || pictureUrl.indexOf('content:') === 0 || pictureUrl.indexOf('ms-appdata:') === 0 || pictureUrl.indexOf('assets-library:') === 0) {
|
||||
resolveLocalFileSystemURI(data, function (e) {
|
||||
resolveLocalFileSystemURL(data, function (e) {
|
||||
fileEntry = e;
|
||||
logCallback('resolveLocalFileSystemURI()', true)(e.toURL());
|
||||
logCallback('resolveLocalFileSystemURL()', true)(e.toURL());
|
||||
readFile();
|
||||
}, logCallback('resolveLocalFileSystemURI()', false));
|
||||
}, logCallback('resolveLocalFileSystemURL()', false));
|
||||
} else if (pictureUrl.indexOf('data:image/jpeg;base64') === 0) {
|
||||
// do nothing
|
||||
} else {
|
||||
@@ -251,7 +251,7 @@ exports.defineManualTests = function (contentEl, createActionButton) {
|
||||
|
||||
//cleanup
|
||||
//rename moved file back to original name so other tests can reference image
|
||||
resolveLocalFileSystemURI(destDirEntry.nativeURL+'moved_file.png', function(fileEntry) {
|
||||
resolveLocalFileSystemURL(destDirEntry.nativeURL+'moved_file.png', function(fileEntry) {
|
||||
fileEntry.moveTo(destDirEntry, origName, logCallback('FileEntry.moveTo', true), logCallback('FileEntry.moveTo', false));
|
||||
console.log('Cleanup: successfully renamed file back to original name');
|
||||
}, function () {
|
||||
@@ -259,7 +259,7 @@ exports.defineManualTests = function (contentEl, createActionButton) {
|
||||
});
|
||||
|
||||
//remove copied file
|
||||
resolveLocalFileSystemURI(destDirEntry.nativeURL+'copied_file.png', function(fileEntry) {
|
||||
resolveLocalFileSystemURL(destDirEntry.nativeURL+'copied_file.png', function(fileEntry) {
|
||||
fileEntry.remove(logCallback('FileEntry.remove', true), logCallback('FileEntry.remove', false));
|
||||
console.log('Cleanup: successfully removed copied file');
|
||||
}, function () {
|
||||
|
||||
@@ -89,26 +89,20 @@ for (var key in Camera) {
|
||||
*
|
||||
* If `Camera.sourceType` is `Camera.PictureSourceType.PHOTOLIBRARY` or
|
||||
* `Camera.PictureSourceType.SAVEDPHOTOALBUM`, then a dialog displays
|
||||
* that allows users to select an existing image. The
|
||||
* `camera.getPicture` function returns a [`CameraPopoverHandle`]{@link module:CameraPopoverHandle} object,
|
||||
* which can be used to reposition the image selection dialog, for
|
||||
* example, when the device orientation changes.
|
||||
* that allows users to select an existing image.
|
||||
*
|
||||
* The return value is sent to the [`cameraSuccess`]{@link module:camera.onSuccess} callback function, in
|
||||
* one of the following formats, depending on the specified
|
||||
* `cameraOptions`:
|
||||
*
|
||||
* - A `String` containing the Base64-encoded photo image.
|
||||
*
|
||||
* - A `String` representing the image file location on local storage (default).
|
||||
*
|
||||
* You can do whatever you want with the encoded image or URI, for
|
||||
* example:
|
||||
*
|
||||
* - Render the image in an `<img>` tag, as in the example below
|
||||
*
|
||||
* - Save the data locally (`LocalStorage`, [Lawnchair](http://brianleroux.github.com/lawnchair/), etc.)
|
||||
*
|
||||
* - Post the data to a remote server
|
||||
*
|
||||
* __NOTE__: Photo resolution on newer devices is quite good. Photos
|
||||
|
||||
@@ -24,6 +24,13 @@
|
||||
*/
|
||||
module.exports = {
|
||||
/**
|
||||
* @description
|
||||
* Defines the output format of `Camera.getPicture` call.
|
||||
* _Note:_ On iOS passing `DestinationType.NATIVE_URI` along with
|
||||
* `PictureSourceType.PHOTOLIBRARY` or `PictureSourceType.SAVEDPHOTOALBUM` will
|
||||
* disable any image modifications (resize, quality change, cropping, etc.) due
|
||||
* to implementation specific.
|
||||
*
|
||||
* @enum {number}
|
||||
*/
|
||||
DestinationType:{
|
||||
@@ -55,14 +62,20 @@ module.exports = {
|
||||
ALLMEDIA : 2
|
||||
},
|
||||
/**
|
||||
* @description
|
||||
* Defines the output format of `Camera.getPicture` call.
|
||||
* _Note:_ On iOS passing `PictureSourceType.PHOTOLIBRARY` or `PictureSourceType.SAVEDPHOTOALBUM`
|
||||
* along with `DestinationType.NATIVE_URI` will disable any image modifications (resize, quality
|
||||
* change, cropping, etc.) due to implementation specific.
|
||||
*
|
||||
* @enum {number}
|
||||
*/
|
||||
PictureSourceType:{
|
||||
/** Choose image from picture library (same as SAVEDPHOTOALBUM for Android) */
|
||||
/** Choose image from the device's photo library (same as SAVEDPHOTOALBUM for Android) */
|
||||
PHOTOLIBRARY : 0,
|
||||
/** Take picture from camera */
|
||||
CAMERA : 1,
|
||||
/** Choose image from picture library (same as PHOTOLIBRARY for Android) */
|
||||
/** Choose image only from the device's Camera Roll album (same as PHOTOLIBRARY for Android) */
|
||||
SAVEDPHOTOALBUM : 2
|
||||
},
|
||||
/**
|
||||
|
||||
@@ -33,7 +33,7 @@ var exec = require('cordova/exec');
|
||||
* - iOS
|
||||
*
|
||||
* @example
|
||||
* var cameraPopoverHandle = navigator.camera.getPicture(onSuccess, onFail,
|
||||
* navigator.camera.getPicture(onSuccess, onFail,
|
||||
* {
|
||||
* destinationType: Camera.DestinationType.FILE_URI,
|
||||
* sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
|
||||
@@ -42,13 +42,19 @@ var exec = require('cordova/exec');
|
||||
*
|
||||
* // 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);
|
||||
* cameraPopoverHandle.setPosition(cameraPopoverOptions);
|
||||
* }
|
||||
* @module CameraPopoverHandle
|
||||
*/
|
||||
var CameraPopoverHandle = function() {
|
||||
/** Set the position of the popover.
|
||||
/**
|
||||
* 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) {
|
||||
|
||||
Reference in New Issue
Block a user