mirror of
https://github.com/apache/cordova-plugin-camera.git
synced 2026-02-03 00:06:46 +08:00
Compare commits
65 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
869f02da1a | ||
|
|
e9db20e381 | ||
|
|
c7971d9f63 | ||
|
|
3112e5fb15 | ||
|
|
c56a255fe8 | ||
|
|
0227cdcf14 | ||
|
|
75bf807261 | ||
|
|
abfbbd35d5 | ||
|
|
59cf76d1da | ||
|
|
4ee90a84f3 | ||
|
|
5587bec320 | ||
|
|
d523142cf2 | ||
|
|
0f6435ec73 | ||
|
|
e81e02b21f | ||
|
|
1e20a9bd07 | ||
|
|
d356030070 | ||
|
|
7bc311fba9 | ||
|
|
e419a74546 | ||
|
|
9a47f5c791 | ||
|
|
66d3f03270 | ||
|
|
731c10f5b2 | ||
|
|
f704689200 | ||
|
|
2bad1fd81c | ||
|
|
b43c78b419 | ||
|
|
db2ffedecc | ||
|
|
0d13b71d33 | ||
|
|
8975171d7a | ||
|
|
2d1ee66a2b | ||
|
|
ebe0517a24 | ||
|
|
43d6591d9e | ||
|
|
64d8c5108a | ||
|
|
11769962bd | ||
|
|
140e8861e3 | ||
|
|
5ae56cf8f0 | ||
|
|
e2e04ba3d8 | ||
|
|
4584f15d9f | ||
|
|
0111e93448 | ||
|
|
0333d001c7 | ||
|
|
45496213b3 | ||
|
|
3f42591363 | ||
|
|
e2ecd7fe91 | ||
|
|
eb7fc333ee | ||
|
|
fd155d9705 | ||
|
|
2bf5b9347e | ||
|
|
efb633969e | ||
|
|
973bbbbac7 | ||
|
|
358522c0b5 | ||
|
|
8766956abb | ||
|
|
d89c25cd82 | ||
|
|
ba4f77468f | ||
|
|
adf15799d9 | ||
|
|
e9aba07926 | ||
|
|
df14414203 | ||
|
|
2a750f0fa1 | ||
|
|
06ac9b3dc9 | ||
|
|
bfa38fed2c | ||
|
|
7611960ef2 | ||
|
|
f4067e22d9 | ||
|
|
f33ade83e4 | ||
|
|
6f25420ce7 | ||
|
|
6feaa95559 | ||
|
|
c887c229f0 | ||
|
|
6900fbaefa | ||
|
|
a9436b1a18 | ||
|
|
db4b4b947d |
@@ -12,12 +12,17 @@ image:
|
||||
- Visual Studio 2017
|
||||
|
||||
environment:
|
||||
nodejs_version: "6"
|
||||
|
||||
matrix:
|
||||
- PLATFORM: windows-10-store
|
||||
- nodejs_version: "10"
|
||||
- nodejs_version: "12"
|
||||
- nodejs_version: "14"
|
||||
|
||||
platform:
|
||||
- x86
|
||||
- x64
|
||||
|
||||
install:
|
||||
- ps: Install-Product node $env:nodejs_version
|
||||
- node --version
|
||||
- npm install -g github:apache/cordova-paramedic
|
||||
- npm install -g cordova
|
||||
@@ -25,4 +30,4 @@ install:
|
||||
build: off
|
||||
|
||||
test_script:
|
||||
- cordova-paramedic --config pr\%PLATFORM% --plugin . --justBuild
|
||||
- cordova-paramedic --config pr\windows-10-store --plugin . --justBuild
|
||||
|
||||
46
.asf.yaml
Normal file
46
.asf.yaml
Normal file
@@ -0,0 +1,46 @@
|
||||
# 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.
|
||||
|
||||
github:
|
||||
description: Apache Cordova Plugin camera
|
||||
homepage: https://cordova.apache.org/
|
||||
|
||||
labels:
|
||||
- cordova
|
||||
- mobile
|
||||
- javascript
|
||||
- nodejs
|
||||
- hacktoberfest
|
||||
- java
|
||||
- objective-c
|
||||
- cordova-plugin
|
||||
|
||||
features:
|
||||
wiki: false
|
||||
issues: true
|
||||
projects: true
|
||||
|
||||
enabled_merge_buttons:
|
||||
squash: true
|
||||
merge: false
|
||||
rebase: false
|
||||
|
||||
notifications:
|
||||
commits: commits@cordova.apache.org
|
||||
issues: issues@cordova.apache.org
|
||||
pullrequests_status: issues@cordova.apache.org
|
||||
pullrequests_comment: issues@cordova.apache.org
|
||||
@@ -1,10 +1,23 @@
|
||||
# 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.
|
||||
|
||||
root: true
|
||||
extends: semistandard
|
||||
rules:
|
||||
indent:
|
||||
- error
|
||||
- 4
|
||||
camelcase: off
|
||||
padded-blocks: off
|
||||
operator-linebreak: off
|
||||
no-throw-literal: off
|
||||
extends: '@cordova/eslint-config/browser'
|
||||
|
||||
overrides:
|
||||
- files: [tests/**/*.js]
|
||||
extends: '@cordova/eslint-config/node-tests'
|
||||
|
||||
57
.github/workflows/ci.yml
vendored
Normal file
57
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
# 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.
|
||||
|
||||
name: Node CI
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: NodeJS ${{ matrix.node-version }} on ${{ matrix.os }}
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [10.x, 12.x, 14.x, 16.x]
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
- name: set up JDK 1.8
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 1.8
|
||||
|
||||
- name: Environment Information
|
||||
run: |
|
||||
node --version
|
||||
npm --version
|
||||
gradle --version
|
||||
|
||||
- name: npm install and test
|
||||
run: |
|
||||
npm i
|
||||
npm t
|
||||
env:
|
||||
CI: true
|
||||
13
.github/workflows/release-notify.yml
vendored
Normal file
13
.github/workflows/release-notify.yml
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
name: Close issue asking for release
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
|
||||
jobs:
|
||||
action-test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: niklasmerz/release-notify@master
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
3
.npmignore
Normal file
3
.npmignore
Normal file
@@ -0,0 +1,3 @@
|
||||
.*
|
||||
appveyor.yml
|
||||
tests
|
||||
34
.travis.yml
34
.travis.yml
@@ -1,4 +1,4 @@
|
||||
# This Travis configuration file is built after a Cordova Paramedic
|
||||
# This Travis configuration file is built after a Cordova Paramedic
|
||||
# specific template with minimal modifications and adaptations:
|
||||
# https://github.com/apache/cordova-paramedic/blob/master/.travis.yml
|
||||
|
||||
@@ -12,18 +12,18 @@ addons:
|
||||
env:
|
||||
global:
|
||||
- SAUCE_USERNAME=snay
|
||||
- TRAVIS_NODE_VERSION=8
|
||||
- ANDROID_API_LEVEL=28
|
||||
- ANDROID_BUILD_TOOLS_VERSION=28.0.3
|
||||
- TRAVIS_NODE_VERSION=12
|
||||
- ANDROID_API_LEVEL=29
|
||||
- ANDROID_BUILD_TOOLS_VERSION=29.0.2
|
||||
|
||||
language: node_js
|
||||
node_js: 8
|
||||
node_js: 14
|
||||
|
||||
# yaml anchor/alias: https://medium.com/@tommyvn/travis-yml-dry-with-anchors-8b6a3ac1b027
|
||||
|
||||
_ios: &_ios
|
||||
os: osx
|
||||
osx_image: xcode10.2
|
||||
osx_image: xcode11.6
|
||||
|
||||
_android: &_android
|
||||
language: android
|
||||
@@ -35,15 +35,16 @@ _android: &_android
|
||||
- build-tools-$ANDROID_BUILD_TOOLS_VERSION
|
||||
- android-$ANDROID_API_LEVEL
|
||||
licenses:
|
||||
- 'android-sdk-preview-license-.+'
|
||||
- 'android-sdk-license-.+'
|
||||
- 'google-gdk-license-.+'
|
||||
- "android-sdk-preview-license-.+"
|
||||
- "android-sdk-license-.+"
|
||||
- "google-gdk-license-.+"
|
||||
|
||||
matrix:
|
||||
include:
|
||||
# additional tests
|
||||
- env: ADDITIONAL_TESTS_DIR=./tests/ios
|
||||
language: objective-c
|
||||
os: osx
|
||||
osx_image: xcode11.5
|
||||
|
||||
# local tests, without saucelabs
|
||||
- env: PLATFORM=local/browser
|
||||
@@ -81,13 +82,13 @@ matrix:
|
||||
|
||||
before_install:
|
||||
# manually install Node for `language: android`
|
||||
- if [[ "$PLATFORM" =~ android ]]; then nvm install $TRAVIS_NODE_VERSION; fi
|
||||
- if [[ "$PLATFORM" =~ android ]]; then nvm install $TRAVIS_NODE_VERSION; fi
|
||||
- node --version
|
||||
- if [[ "$PLATFORM" =~ android ]]; then gradle --version; fi
|
||||
- if [[ "$PLATFORM" =~ ios ]]; then npm install -g ios-deploy; fi
|
||||
- npm install -g cordova
|
||||
# install paramedic if not running on paramedic repo
|
||||
- if ! [[ "$TRAVIS_REPO_SLUG" =~ cordova-paramedic ]]; then npm install -g github:apache/cordova-paramedic; fi
|
||||
- if ! [[ "$TRAVIS_REPO_SLUG" =~ cordova-paramedic ]]; then npm install -g github:apache/cordova-paramedic; fi
|
||||
|
||||
install:
|
||||
- npm install
|
||||
@@ -106,11 +107,12 @@ before_script:
|
||||
PARAMEDIC_COMMAND="cordova-paramedic"
|
||||
fi
|
||||
- PARAMEDIC_BUILDNAME=travis-$TRAVIS_REPO_SLUG-$TRAVIS_JOB_NUMBER
|
||||
|
||||
|
||||
script:
|
||||
- $TEST_COMMAND
|
||||
- if [[ "$ADDITIONAL_TESTS_DIR" != "" ]];
|
||||
- |
|
||||
if [[ "$ADDITIONAL_TESTS_DIR" != "" ]];
|
||||
then cd $ADDITIONAL_TESTS_DIR && npm install && npm test;
|
||||
else
|
||||
$PARAMEDIC_COMMAND --config ./pr/$PLATFORM --plugin $PARAMEDIC_PLUGIN_TO_TEST --buildName $PARAMEDIC_BUILDNAME;
|
||||
else
|
||||
$PARAMEDIC_COMMAND --config ./pr/$PLATFORM --plugin $PARAMEDIC_PLUGIN_TO_TEST --buildName $PARAMEDIC_BUILDNAME;
|
||||
fi
|
||||
|
||||
@@ -25,13 +25,13 @@ Anyone can contribute to Cordova. And we need your contributions.
|
||||
|
||||
There are multiple ways to contribute: report bugs, improve the docs, and
|
||||
contribute code.
|
||||
|
||||
For instructions on this, start with the
|
||||
|
||||
For instructions on this, start with the
|
||||
[contribution overview](http://cordova.apache.org/contribute/).
|
||||
|
||||
The details are explained there, but the important items are:
|
||||
- Sign and submit an Apache ICLA (Contributor License Agreement).
|
||||
- Have a Jira issue open that corresponds to your contribution.
|
||||
- Check for Github issues that corresponds to your contribution and link or create them if necessary.
|
||||
- Run the tests so your patch doesn't break existing functionality.
|
||||
|
||||
We look forward to your contributions!
|
||||
|
||||
|
||||
24
README.md
24
README.md
@@ -276,19 +276,14 @@ Optional parameters to customize the camera settings.
|
||||
|
||||
### 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**
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| DATA_URL | <code>number</code> | <code>0</code> | Return base64 encoded string. DATA_URL can be very memory intensive and cause app crashes or out of memory errors. Use FILE_URI or NATIVE_URI if possible |
|
||||
| DATA_URL | <code>number</code> | <code>0</code> | Return base64 encoded string. DATA_URL can be very memory intensive and cause app crashes or out of memory errors. Use FILE_URI if possible |
|
||||
| FILE_URI | <code>number</code> | <code>1</code> | Return file uri (content://media/external/images/media/2 for Android) |
|
||||
| NATIVE_URI | <code>number</code> | <code>2</code> | Return native uri (eg. asset-library://... for iOS) |
|
||||
|
||||
<a name="module_Camera.EncodingType"></a>
|
||||
|
||||
@@ -317,9 +312,6 @@ to implementation specific.
|
||||
|
||||
### 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**
|
||||
@@ -435,7 +427,7 @@ Take a photo and retrieve it as a Base64-encoded image:
|
||||
* Warning: Using DATA_URL is not recommended! The DATA_URL destination
|
||||
* type is very memory intensive, even with a low quality setting. Using it
|
||||
* can result in out of memory errors and application crashes. Use FILE_URI
|
||||
* or NATIVE_URI instead.
|
||||
* instead.
|
||||
*/
|
||||
navigator.camera.getPicture(onSuccess, onFail, { quality: 25,
|
||||
destinationType: Camera.DestinationType.DATA_URL
|
||||
@@ -482,11 +474,6 @@ displays:
|
||||
// do your thing here!
|
||||
}, 0);
|
||||
|
||||
#### Windows Phone 7 Quirks
|
||||
|
||||
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
|
||||
@@ -503,7 +490,7 @@ More information about Windows Phone 8.1 picker APIs is here: [How to continue y
|
||||
|
||||
- Any `cameraDirection` value results in a back-facing photo. (= You can only use the back camera)
|
||||
|
||||
- **`allowEdit` is unpredictable on Android and it should not be used!** The Android implementation of this plugin tries to find and use an application on the user's device to do image cropping. The plugin has no control over what application the user selects to perform the image cropping and it is very possible that the user could choose an incompatible option and cause the plugin to fail. This sometimes works because most devices come with an application that handles cropping in a way that is compatible with this plugin (Google Plus Photos), but it is unwise to rely on that being the case. If image editing is essential to your application, consider seeking a third party library or plugin that provides its own image editing utility for a more robust solution.
|
||||
- **`allowEdit` is unpredictable on Android and it should not be used!** The Android implementation of this plugin tries to find and use an application on the user's device to do image cropping. The plugin has no control over what application the user selects to perform the image cropping and it is very possible that the user could choose an incompatible option and cause the plugin to fail. This sometimes works because most devices come with an application that handles cropping in a way that is compatible with this plugin (Google Photos), but it is unwise to rely on that being the case. If image editing is essential to your application, consider seeking a third party library or plugin that provides its own image editing utility for a more robust solution.
|
||||
|
||||
- `Camera.PictureSourceType.PHOTOLIBRARY` and `Camera.PictureSourceType.SAVEDPHOTOALBUM` both display the same photo album.
|
||||
|
||||
@@ -513,9 +500,6 @@ More information about Windows Phone 8.1 picker APIs is here: [How to continue y
|
||||
|
||||
- When using `destinationType.FILE_URI`, photos are saved in the application's temporary directory. The contents of the application's temporary directory is deleted when the application ends.
|
||||
|
||||
- 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.
|
||||
|
||||
[android_lifecycle]: http://cordova.apache.org/docs/en/dev/guide/platforms/android/lifecycle.html
|
||||
|
||||
@@ -545,7 +529,7 @@ function setOptions(srcType) {
|
||||
encodingType: Camera.EncodingType.JPEG,
|
||||
mediaType: Camera.MediaType.PICTURE,
|
||||
allowEdit: true,
|
||||
correctOrientation: true //Corrects Android orientation quirks
|
||||
correctOrientation: true
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,73 @@
|
||||
-->
|
||||
# Release Notes
|
||||
|
||||
### 6.0.0 (Aug 19, 2021)
|
||||
|
||||
**Feature:**
|
||||
|
||||
* [GH-751](https://github.com/apache/cordova-plugin-camera/pull/751) feat(android)!: support **AndroidX**
|
||||
* [GH-750](https://github.com/apache/cordova-plugin-camera/pull/750) feat(android): bump `cordova-android` requirements for `10.x`
|
||||
* [GH-731](https://github.com/apache/cordova-plugin-camera/pull/731) feat(android): encode `heic` format to `EncodingType` for webview display [#711](https://github.com/apache/cordova-plugin-camera/issues/711)
|
||||
* [GH-684](https://github.com/apache/cordova-plugin-camera/pull/684) feat(android): `sdk-30` package visibility support
|
||||
|
||||
**Fix:**
|
||||
|
||||
* [GH-687](https://github.com/apache/cordova-plugin-camera/pull/687) fix(android): return exception message (where it exists)
|
||||
* [GH-585](https://github.com/apache/cordova-plugin-camera/pull/585) fix(android): file path correction if `Uri` authority is `FileProvider`
|
||||
|
||||
**Chore & CI:**
|
||||
|
||||
* [GH-749](https://github.com/apache/cordova-plugin-camera/pull/749) chore: bump plugin version for next major
|
||||
* [GH-654](https://github.com/apache/cordova-plugin-camera/pull/654) chore: add release notify action
|
||||
* [GH-745](https://github.com/apache/cordova-plugin-camera/pull/745) ci(gh-action): added workflow to run tests
|
||||
|
||||
### 5.0.3 (Aug 04, 2021)
|
||||
|
||||
* [GH-754](https://github.com/apache/cordova-plugin-camera/pull/754) chore: rebuilt `package-lock.json`
|
||||
* [GH-748](https://github.com/apache/cordova-plugin-camera/pull/748) fix: incorrect version in `package-lock`
|
||||
* [GH-747](https://github.com/apache/cordova-plugin-camera/pull/747) chore: set the 5.x versions locked to `cordova-android` `<10.0.0`
|
||||
* [GH-729](https://github.com/apache/cordova-plugin-camera/pull/729) chore(asf): Update GitHub repo metadata
|
||||
|
||||
### 5.0.2 (May 11, 2021)
|
||||
* [GH-728](https://github.com/apache/cordova-plugin-camera/pull/728) plugin release preparation - audit fix
|
||||
* [GH-700](https://github.com/apache/cordova-plugin-camera/pull/700) Bugfix [issue 665](https://github.com/apache/cordova-plugin-camera/issues/665) - app crashes after taking a picture due to a bug in the camera plugin when app is resumed
|
||||
* [GH-691](https://github.com/apache/cordova-plugin-camera/pull/691) ci: add node-14.x to workflow (#691)
|
||||
|
||||
### 5.0.1 (Nov 04, 2020)
|
||||
|
||||
* [GH-686](https://github.com/apache/cordova-plugin-camera/pull/686) chore(android): add missing apache license header
|
||||
* [GH-685](https://github.com/apache/cordova-plugin-camera/pull/685) fix(ios): correctly append exif on **iOS** 14
|
||||
* [GH-669](https://github.com/apache/cordova-plugin-camera/pull/669) fix(android): save to photo gallery - fixes issues [#341](https://github.com/apache/cordova-plugin-camera/pull/341) & [#577](https://github.com/apache/cordova-plugin-camera/pull/577)
|
||||
* [GH-672](https://github.com/apache/cordova-plugin-camera/pull/672) chore: Fix JIRA links in RELEASENOTES.md
|
||||
* [GH-664](https://github.com/apache/cordova-plugin-camera/pull/664) chore: Update RELEASENOTES
|
||||
|
||||
### 5.0.0 (Sep 14, 2020)
|
||||
|
||||
* [GH-648](https://github.com/apache/cordova-plugin-camera/pull/648) ci(travis): update osx xcode image
|
||||
* [GH-637](https://github.com/apache/cordova-plugin-camera/pull/637) breaking: remove `NATIVE_URI` DestinationType
|
||||
* [GH-628](https://github.com/apache/cordova-plugin-camera/pull/628) breaking: bump project requirements
|
||||
* [GH-634](https://github.com/apache/cordova-plugin-camera/pull/634) chore: remove deprecated `file-transfer` plugin
|
||||
* [GH-632](https://github.com/apache/cordova-plugin-camera/pull/632) fix(android): return error if file url is null
|
||||
* [GH-510](https://github.com/apache/cordova-plugin-camera/pull/510) fix(android): use provider prefix to avoid conflicts other plugin providers
|
||||
* [GH-617](https://github.com/apache/cordova-plugin-camera/pull/617) breaking(android): stop using `CordovaUri` helper class
|
||||
* [GH-630](https://github.com/apache/cordova-plugin-camera/pull/630) chore: add `package-lock.json`
|
||||
* [GH-631](https://github.com/apache/cordova-plugin-camera/pull/631) chore(package): use short notation
|
||||
* [GH-629](https://github.com/apache/cordova-plugin-camera/pull/629) feat: migrate to `@cordova/eslint-config@3.x`
|
||||
* [GH-626](https://github.com/apache/cordova-plugin-camera/pull/626) ci: fix additional tests
|
||||
* [GH-627](https://github.com/apache/cordova-plugin-camera/pull/627) breaking: bump version 5.0.0-dev
|
||||
* [GH-612](https://github.com/apache/cordova-plugin-camera/pull/612) fix(ios): `tempFilePath` called twice if using `CameraUsesGeolocation`
|
||||
* [GH-588](https://github.com/apache/cordova-plugin-camera/pull/588) Cache images in device storage, devices have enough space now.
|
||||
* [GH-508](https://github.com/apache/cordova-plugin-camera/pull/508) docs(readme): app renamed to Google Photos
|
||||
* chore(asf): update git notification settings
|
||||
* [GH-580](https://github.com/apache/cordova-plugin-camera/pull/580) fix(ios): return copy of video when picking from gallery on **iOS** 13
|
||||
* Update CONTRIBUTING.md
|
||||
* [GH-551](https://github.com/apache/cordova-plugin-camera/pull/551) Fix UI API called on a background thread
|
||||
* [GH-576](https://github.com/apache/cordova-plugin-camera/pull/576) ci: updates Node.js versions
|
||||
* [GH-575](https://github.com/apache/cordova-plugin-camera/pull/575) chore(npm): adds ignore list
|
||||
* [GH-513](https://github.com/apache/cordova-plugin-camera/pull/513) docs(README): remove confusing comment
|
||||
* [GH-512](https://github.com/apache/cordova-plugin-camera/pull/512) docs(README): remove orphan **Windows** phone 7 note
|
||||
* [GH-306](https://github.com/apache/cordova-plugin-camera/pull/306) ImagePicker returning same image
|
||||
|
||||
### 4.1.0 (Jun 27, 2019)
|
||||
|
||||
- docs: remove outdated test docs translations ([`06dc38f`](https://github.com/apache/cordova-plugin-camera/commit/06dc38f))
|
||||
@@ -35,23 +102,23 @@
|
||||
- fix(ios): fixes UIImagePickerController cancel handling for iOS11+ ([#377](https://github.com/apache/cordova-plugin-camera/issues/377)) ([`24c8b6c`](https://github.com/apache/cordova-plugin-camera/commit/24c8b6c))
|
||||
- docs: Remove deprecated platforms from docs ([#394](https://github.com/apache/cordova-plugin-camera/issues/394)) ([`7ddb3df`](https://github.com/apache/cordova-plugin-camera/commit/7ddb3df))
|
||||
- fix(android): return DATA_URL for ALLMEDIA if it's an image ([#382](https://github.com/apache/cordova-plugin-camera/issues/382)) ([`60e7795`](https://github.com/apache/cordova-plugin-camera/commit/60e7795))
|
||||
- refactor(ios): [CB-13813](https://issues.apache.org/jira/browse/13813): Remove old iOS code ([#381](https://github.com/apache/cordova-plugin-camera/issues/381)) ([`ce77aab`](https://github.com/apache/cordova-plugin-camera/commit/ce77aab))
|
||||
- feat(ios): [CB-13865](https://issues.apache.org/jira/browse/13865): (Ipad) Making popover Window Size configurable using popoverOptions - imagePicker ([#314](https://github.com/apache/cordova-plugin-camera/issues/314)) ([`cd72047`](https://github.com/apache/cordova-plugin-camera/commit/cd72047))
|
||||
- chore(types): [CB-13837](https://issues.apache.org/jira/browse/13837): fix TypeScript Definition for CameraPopoverOptions ([#379](https://github.com/apache/cordova-plugin-camera/issues/379)) ([`86b0bf2`](https://github.com/apache/cordova-plugin-camera/commit/86b0bf2))
|
||||
- refactor(ios): [CB-13813](https://issues.apache.org/jira/browse/CB-13813): Remove old iOS code ([#381](https://github.com/apache/cordova-plugin-camera/issues/381)) ([`ce77aab`](https://github.com/apache/cordova-plugin-camera/commit/ce77aab))
|
||||
- feat(ios): [CB-13865](https://issues.apache.org/jira/browse/CB-13865): (Ipad) Making popover Window Size configurable using popoverOptions - imagePicker ([#314](https://github.com/apache/cordova-plugin-camera/issues/314)) ([`cd72047`](https://github.com/apache/cordova-plugin-camera/commit/cd72047))
|
||||
- chore(types): [CB-13837](https://issues.apache.org/jira/browse/CB-13837): fix TypeScript Definition for CameraPopoverOptions ([#379](https://github.com/apache/cordova-plugin-camera/issues/379)) ([`86b0bf2`](https://github.com/apache/cordova-plugin-camera/commit/86b0bf2))
|
||||
- docs(android): clarify android quirk of cameraDirection ([`a5a3d88`](https://github.com/apache/cordova-plugin-camera/commit/a5a3d88), [`bfbe4a1`](https://github.com/apache/cordova-plugin-camera/commit/bfbe4a1))
|
||||
- chore(release): Bump minor version ([#370](https://github.com/apache/cordova-plugin-camera/issues/370)) ([`eed4433`](https://github.com/apache/cordova-plugin-camera/commit/eed4433))
|
||||
- build: Remove automatic README generation ([#365](https://github.com/apache/cordova-plugin-camera/issues/365)) ([`07e8574`](https://github.com/apache/cordova-plugin-camera/commit/07e8574))
|
||||
- docs: remove JIRA link ([`bcb26fb`](https://github.com/apache/cordova-plugin-camera/commit/bcb26fb))
|
||||
- ci(travis): also accept terms for android sdk `android-27` ([`a346212`](https://github.com/apache/cordova-plugin-camera/commit/a346212))
|
||||
- docs: remove outdated docs translations that haven't been touched for 3 years ([`403682b`](https://github.com/apache/cordova-plugin-camera/commit/403682b))
|
||||
- fix(android): [CB-14097](https://issues.apache.org/jira/browse/14097): Fix crash when selecting some files with getPicture ([#322](https://github.com/apache/cordova-plugin-camera/issues/322)) ([`5c23b65`](https://github.com/apache/cordova-plugin-camera/commit/5c23b65))
|
||||
- fix(browser): [CB-13384](https://issues.apache.org/jira/browse/13384): Added deprecation of video.src compatibility ([#288](https://github.com/apache/cordova-plugin-camera/issues/288)) ([`5163d38`](https://github.com/apache/cordova-plugin-camera/commit/5163d38))
|
||||
- fix(android): [CB-14097](https://issues.apache.org/jira/browse/CB-14097): Fix crash when selecting some files with getPicture ([#322](https://github.com/apache/cordova-plugin-camera/issues/322)) ([`5c23b65`](https://github.com/apache/cordova-plugin-camera/commit/5c23b65))
|
||||
- fix(browser): [CB-13384](https://issues.apache.org/jira/browse/CB-13384): Added deprecation of video.src compatibility ([#288](https://github.com/apache/cordova-plugin-camera/issues/288)) ([`5163d38`](https://github.com/apache/cordova-plugin-camera/commit/5163d38))
|
||||
- fix(browser): Remove audio flag from getUserMedia ([#284](https://github.com/apache/cordova-plugin-camera/issues/284)) ([`36343a8`](https://github.com/apache/cordova-plugin-camera/commit/36343a8))
|
||||
- docs: replace warning emoji with warning unicode ([#317](https://github.com/apache/cordova-plugin-camera/issues/317)) ([`ead7d5e`](https://github.com/apache/cordova-plugin-camera/commit/ead7d5e))
|
||||
- feat(android): Update engines to use variables ([#323](https://github.com/apache/cordova-plugin-camera/issues/323)) ([`6899c5e`](https://github.com/apache/cordova-plugin-camera/commit/6899c5e))
|
||||
- feat(android): [CB-14017](https://issues.apache.org/jira/browse/14017): Make com.android.support:support-v4 version configurable ([#318](https://github.com/apache/cordova-plugin-camera/issues/318)) ([`e334656`](https://github.com/apache/cordova-plugin-camera/commit/e334656))
|
||||
- refactor(android): [CB-14047](https://issues.apache.org/jira/browse/14047): CameraLauncher: Replacing Repeated String literals with final variables ([#319](https://github.com/apache/cordova-plugin-camera/issues/319)) ([`5ec121b`](https://github.com/apache/cordova-plugin-camera/commit/5ec121b))
|
||||
- fix(windows): [CB-11714](https://issues.apache.org/jira/browse/11714): added extra check for content-type in savePhoto() without options.targetWidth/Height ([#242](https://github.com/apache/cordova-plugin-camera/issues/242)) ([`a201722`](https://github.com/apache/cordova-plugin-camera/commit/a201722), [`dc73954`](https://github.com/apache/cordova-plugin-camera/commit/dc73954), [`dca4b9c`](https://github.com/apache/cordova-plugin-camera/commit/dca4b9c), [`c1b9772`](https://github.com/apache/cordova-plugin-camera/commit/c1b9772), [`eb57b02`](https://github.com/apache/cordova-plugin-camera/commit/eb57b02))
|
||||
- feat(android): [CB-14017](https://issues.apache.org/jira/browse/CB-14017): Make com.android.support:support-v4 version configurable ([#318](https://github.com/apache/cordova-plugin-camera/issues/318)) ([`e334656`](https://github.com/apache/cordova-plugin-camera/commit/e334656))
|
||||
- refactor(android): [CB-14047](https://issues.apache.org/jira/browse/CB-14047): CameraLauncher: Replacing Repeated String literals with final variables ([#319](https://github.com/apache/cordova-plugin-camera/issues/319)) ([`5ec121b`](https://github.com/apache/cordova-plugin-camera/commit/5ec121b))
|
||||
- fix(windows): [CB-11714](https://issues.apache.org/jira/browse/CB-11714): added extra check for content-type in savePhoto() without options.targetWidth/Height ([#242](https://github.com/apache/cordova-plugin-camera/issues/242)) ([`a201722`](https://github.com/apache/cordova-plugin-camera/commit/a201722), [`dc73954`](https://github.com/apache/cordova-plugin-camera/commit/dc73954), [`dca4b9c`](https://github.com/apache/cordova-plugin-camera/commit/dca4b9c), [`c1b9772`](https://github.com/apache/cordova-plugin-camera/commit/c1b9772), [`eb57b02`](https://github.com/apache/cordova-plugin-camera/commit/eb57b02))
|
||||
|
||||
|
||||
### 4.0.3 (Apr 12, 2018)
|
||||
|
||||
1837
package-lock.json
generated
Normal file
1837
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
38
package.json
38
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cordova-plugin-camera",
|
||||
"version": "4.1.0",
|
||||
"version": "6.0.0",
|
||||
"description": "Cordova Camera Plugin",
|
||||
"types": "./types/index.d.ts",
|
||||
"cordova": {
|
||||
@@ -13,13 +13,8 @@
|
||||
"osx"
|
||||
]
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/apache/cordova-plugin-camera"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/apache/cordova-plugin-camera/issues"
|
||||
},
|
||||
"repository": "github:apache/cordova-plugin-camera",
|
||||
"bugs": "https://github.com/apache/cordova-plugin-camera/issues",
|
||||
"keywords": [
|
||||
"cordova",
|
||||
"camera",
|
||||
@@ -31,8 +26,8 @@
|
||||
"cordova-osx"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "npm run eslint",
|
||||
"eslint": "node node_modules/eslint/bin/eslint www && node node_modules/eslint/bin/eslint src && node node_modules/eslint/bin/eslint tests"
|
||||
"test": "npm run lint",
|
||||
"lint": "eslint ."
|
||||
},
|
||||
"author": "Apache Software Foundation",
|
||||
"license": "Apache-2.0",
|
||||
@@ -46,17 +41,26 @@
|
||||
"cordova": ">=7.1.0"
|
||||
},
|
||||
"5.0.0": {
|
||||
"cordova-android": ">=9.0.0",
|
||||
"cordova-ios": ">=5.1.0",
|
||||
"cordova": ">=9.0.0"
|
||||
},
|
||||
"5.0.4-dev": {
|
||||
"cordova-android": "<10.0.0",
|
||||
"cordova-ios": ">=5.1.0",
|
||||
"cordova": ">=9.0.0"
|
||||
},
|
||||
"6.0.0": {
|
||||
"cordova-android": ">=10.0.0",
|
||||
"cordova-ios": ">=5.1.0",
|
||||
"cordova": ">=9.0.0"
|
||||
},
|
||||
"7.0.0": {
|
||||
"cordova": ">100"
|
||||
}
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^4.3.0",
|
||||
"eslint-config-semistandard": "^11.0.0",
|
||||
"eslint-config-standard": "^10.2.1",
|
||||
"eslint-plugin-import": "^2.3.0",
|
||||
"eslint-plugin-node": "^5.0.0",
|
||||
"eslint-plugin-promise": "^3.5.0",
|
||||
"eslint-plugin-standard": "^3.0.1"
|
||||
"@cordova/eslint-config": "^3.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
42
plugin.xml
42
plugin.xml
@@ -21,7 +21,7 @@
|
||||
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
id="cordova-plugin-camera"
|
||||
version="4.1.0">
|
||||
version="6.0.0">
|
||||
<name>Camera</name>
|
||||
<description>Cordova Camera Plugin</description>
|
||||
<license>Apache 2.0</license>
|
||||
@@ -30,8 +30,9 @@
|
||||
<issue>https://github.com/apache/cordova-plugin-camera/issues</issue>
|
||||
|
||||
<engines>
|
||||
<engine name="cordova" version=">=7.1.0"/>
|
||||
<engine name="cordova-android" version=">=6.3.0" />
|
||||
<engine name="cordova" version=">=9.0.0"/>
|
||||
<engine name="cordova-android" version=">=10.0.0" />
|
||||
<engine name="cordova-ios" version=">=5.1.0" />
|
||||
</engines>
|
||||
|
||||
<js-module src="www/CameraConstants.js" name="Camera">
|
||||
@@ -59,7 +60,7 @@
|
||||
<config-file target="AndroidManifest.xml" parent="application">
|
||||
<provider
|
||||
android:name="org.apache.cordova.camera.FileProvider"
|
||||
android:authorities="${applicationId}.provider"
|
||||
android:authorities="${applicationId}.cordova.plugin.camera.provider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true" >
|
||||
<meta-data
|
||||
@@ -68,20 +69,37 @@
|
||||
</provider>
|
||||
</config-file>
|
||||
|
||||
<config-file target="AndroidManifest.xml" parent="/*">
|
||||
<queries>
|
||||
<intent>
|
||||
<action android:name="android.media.action.IMAGE_CAPTURE" />
|
||||
</intent>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.GET_CONTENT" />
|
||||
</intent>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.PICK" />
|
||||
</intent>
|
||||
<intent>
|
||||
<action android:name="com.android.camera.action.CROP" />
|
||||
<data android:scheme="content" android:mimeType="image/*"/>
|
||||
</intent>
|
||||
</queries>
|
||||
</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/FileProvider.java" target-dir="src/org/apache/cordova/camera" />
|
||||
<source-file src="src/android/GalleryPathVO.java" target-dir="src/org/apache/cordova/camera" />
|
||||
<source-file src="src/android/xml/camera_provider_paths.xml" target-dir="res/xml" />
|
||||
|
||||
<preference name="ANDROIDX_CORE_VERSION" default="1.6.+"/>
|
||||
<framework src="androidx.core:core:$ANDROIDX_CORE_VERSION" />
|
||||
|
||||
<js-module src="www/CameraPopoverHandle.js" name="CameraPopoverHandle">
|
||||
<clobbers target="CameraPopoverHandle" />
|
||||
</js-module>
|
||||
|
||||
<preference name="ANDROID_SUPPORT_V4_VERSION" default="27.+"/>
|
||||
<framework src="com.android.support:support-v4:$ANDROID_SUPPORT_V4_VERSION"/>
|
||||
|
||||
</platform>
|
||||
|
||||
<!-- ios -->
|
||||
@@ -151,12 +169,12 @@
|
||||
<js-module src="www/CameraPopoverHandle.js" name="CameraPopoverHandle">
|
||||
<clobbers target="CameraPopoverHandle" />
|
||||
</js-module>
|
||||
|
||||
|
||||
<header-file src="src/osx/CDVCamera.h" />
|
||||
<source-file src="src/osx/CDVCamera.m" />
|
||||
|
||||
|
||||
<framework src="Quartz.framework" />
|
||||
<framework src="AppKit.framework" />
|
||||
</platform>
|
||||
|
||||
|
||||
</plugin>
|
||||
|
||||
@@ -21,6 +21,7 @@ package org.apache.cordova.camera;
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
@@ -34,10 +35,11 @@ import android.media.ExifInterface;
|
||||
import android.media.MediaScannerConnection;
|
||||
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.provider.MediaStore;
|
||||
import android.support.v4.content.FileProvider;
|
||||
import androidx.core.content.FileProvider;
|
||||
import android.util.Base64;
|
||||
|
||||
import org.apache.cordova.BuildHelper;
|
||||
@@ -51,7 +53,6 @@ import org.json.JSONException;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
@@ -69,7 +70,6 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
|
||||
private static final int DATA_URL = 0; // Return base64 encoded string
|
||||
private static final int FILE_URI = 1; // Return file uri (content://media/external/images/media/2 for Android)
|
||||
private static final int NATIVE_URI = 2; // On Android, this is the same as FILE_URI
|
||||
|
||||
private static final int PHOTOLIBRARY = 0; // Choose image from picture library (same as SAVEDPHOTOALBUM for Android)
|
||||
private static final int CAMERA = 1; // Take picture from camera
|
||||
@@ -87,11 +87,13 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
private static final String PNG_EXTENSION = "." + PNG_TYPE;
|
||||
private static final String PNG_MIME_TYPE = "image/png";
|
||||
private static final String JPEG_MIME_TYPE = "image/jpeg";
|
||||
private static final String HEIC_MIME_TYPE = "image/heic";
|
||||
private static final String GET_PICTURE = "Get Picture";
|
||||
private static final String GET_VIDEO = "Get Video";
|
||||
private static final String GET_All = "Get All";
|
||||
private static final String CROPPED_URI_KEY = "croppedUri";
|
||||
private static final String IMAGE_URI_KEY = "imageUri";
|
||||
private static final String IMAGE_FILE_PATH_KEY = "imageFilePath";
|
||||
|
||||
private static final String TAKE_PICTURE_ACTION = "takePicture";
|
||||
|
||||
@@ -109,7 +111,8 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
private int mQuality; // Compression quality hint (0-100: 0=low quality & high compression, 100=compress of max quality)
|
||||
private int targetWidth; // desired width of the image
|
||||
private int targetHeight; // desired height of the image
|
||||
private CordovaUri imageUri; // Uri of captured image
|
||||
private Uri imageUri; // Uri of captured image
|
||||
private String imageFilePath; // File where the image is stored
|
||||
private int encodingType; // Type of encoding to use
|
||||
private int mediaType; // What type of media to retrieve
|
||||
private int destType; // Source type (needs to be saved for the permission handling)
|
||||
@@ -127,6 +130,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
private MediaScannerConnection conn; // Used to update gallery app with newly-written files
|
||||
private Uri scanMe; // Uri of image to be added to content store
|
||||
private Uri croppedUri;
|
||||
private String croppedFilePath;
|
||||
private ExifHelper exifData; // Exif data from source
|
||||
private String applicationId;
|
||||
|
||||
@@ -194,7 +198,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
if(!PermissionHelper.hasPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
|
||||
PermissionHelper.requestPermission(this, SAVE_TO_ALBUM_SEC, Manifest.permission.READ_EXTERNAL_STORAGE);
|
||||
} else {
|
||||
this.getImage(this.srcType, destType, encodingType);
|
||||
this.getImage(this.srcType, destType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -220,17 +224,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
private String getTempDirectoryPath() {
|
||||
File cache = null;
|
||||
|
||||
// SD Card Mounted
|
||||
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
|
||||
cache = cordova.getActivity().getExternalCacheDir();
|
||||
}
|
||||
// Use internal storage
|
||||
else {
|
||||
cache = cordova.getActivity().getCacheDir();
|
||||
}
|
||||
|
||||
File cache = cordova.getActivity().getCacheDir();
|
||||
// Create the cache directory if it doesn't exist
|
||||
cache.mkdirs();
|
||||
return cache.getAbsolutePath();
|
||||
@@ -280,9 +274,9 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
|
||||
if (takePicturePermission && saveAlbumPermission) {
|
||||
takePicture(returnType, encodingType);
|
||||
} else if (saveAlbumPermission && !takePicturePermission) {
|
||||
} else if (saveAlbumPermission) {
|
||||
PermissionHelper.requestPermission(this, TAKE_PIC_SEC, Manifest.permission.CAMERA);
|
||||
} else if (!saveAlbumPermission && takePicturePermission) {
|
||||
} else if (takePicturePermission) {
|
||||
PermissionHelper.requestPermissions(this, TAKE_PIC_SEC,
|
||||
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE});
|
||||
} else {
|
||||
@@ -300,10 +294,11 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
|
||||
// Specify file so that large image is captured and returned
|
||||
File photo = createCaptureFile(encodingType);
|
||||
this.imageUri = new CordovaUri(FileProvider.getUriForFile(cordova.getActivity(),
|
||||
applicationId + ".provider",
|
||||
photo));
|
||||
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri.getCorrectUri());
|
||||
this.imageFilePath = photo.getAbsolutePath();
|
||||
this.imageUri = FileProvider.getUriForFile(cordova.getActivity(),
|
||||
applicationId + ".cordova.plugin.camera.provider",
|
||||
photo);
|
||||
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
|
||||
//We can write to this URI, this will hopefully allow us to write files to get to the next step
|
||||
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
|
||||
|
||||
@@ -362,14 +357,14 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
*
|
||||
* @param srcType The album to get image from.
|
||||
* @param returnType Set the type of image to return.
|
||||
* @param encodingType
|
||||
*/
|
||||
// TODO: Images selected from SDCARD don't display correctly, but from CAMERA ALBUM do!
|
||||
// TODO: Images from kitkat filechooser not going into crop function
|
||||
public void getImage(int srcType, int returnType, int encodingType) {
|
||||
public void getImage(int srcType, int returnType) {
|
||||
Intent intent = new Intent();
|
||||
String title = GET_PICTURE;
|
||||
croppedUri = null;
|
||||
croppedFilePath = null;
|
||||
if (this.mediaType == PICTURE) {
|
||||
intent.setType("image/*");
|
||||
if (this.allowEdit) {
|
||||
@@ -385,8 +380,9 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
intent.putExtra("aspectX", 1);
|
||||
intent.putExtra("aspectY", 1);
|
||||
}
|
||||
File photo = createCaptureFile(JPEG);
|
||||
croppedUri = Uri.fromFile(photo);
|
||||
File croppedFile = createCaptureFile(JPEG);
|
||||
croppedFilePath = croppedFile.getAbsolutePath();
|
||||
croppedUri = Uri.fromFile(croppedFile);
|
||||
intent.putExtra(MediaStore.EXTRA_OUTPUT, croppedUri);
|
||||
} else {
|
||||
intent.setAction(Intent.ACTION_GET_CONTENT);
|
||||
@@ -411,57 +407,53 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Brings up the UI to perform crop on passed image URI
|
||||
*
|
||||
* @param picUri
|
||||
*/
|
||||
private void performCrop(Uri picUri, int destType, Intent cameraIntent) {
|
||||
try {
|
||||
Intent cropIntent = new Intent("com.android.camera.action.CROP");
|
||||
// indicate image type and Uri
|
||||
cropIntent.setDataAndType(picUri, "image/*");
|
||||
// set crop properties
|
||||
cropIntent.putExtra("crop", "true");
|
||||
|
||||
/**
|
||||
* Brings up the UI to perform crop on passed image URI
|
||||
*
|
||||
* @param picUri
|
||||
*/
|
||||
private void performCrop(Uri picUri, int destType, Intent cameraIntent) {
|
||||
try {
|
||||
Intent cropIntent = new Intent("com.android.camera.action.CROP");
|
||||
// indicate image type and Uri
|
||||
cropIntent.setDataAndType(picUri, "image/*");
|
||||
// set crop properties
|
||||
cropIntent.putExtra("crop", "true");
|
||||
// indicate output X and Y
|
||||
if (targetWidth > 0) {
|
||||
cropIntent.putExtra("outputX", targetWidth);
|
||||
}
|
||||
if (targetHeight > 0) {
|
||||
cropIntent.putExtra("outputY", targetHeight);
|
||||
}
|
||||
if (targetHeight > 0 && targetWidth > 0 && targetWidth == targetHeight) {
|
||||
cropIntent.putExtra("aspectX", 1);
|
||||
cropIntent.putExtra("aspectY", 1);
|
||||
}
|
||||
// create new file handle to get full resolution crop
|
||||
croppedFilePath = createCaptureFile(this.encodingType, System.currentTimeMillis() + "").getAbsolutePath();
|
||||
croppedUri = Uri.parse(croppedFilePath);
|
||||
cropIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
cropIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
|
||||
cropIntent.putExtra("output", croppedUri);
|
||||
|
||||
// start the activity - we handle returning in onActivityResult
|
||||
|
||||
// indicate output X and Y
|
||||
if (targetWidth > 0) {
|
||||
cropIntent.putExtra("outputX", targetWidth);
|
||||
if (this.cordova != null) {
|
||||
this.cordova.startActivityForResult((CordovaPlugin) this,
|
||||
cropIntent, CROP_CAMERA + destType);
|
||||
}
|
||||
} catch (ActivityNotFoundException anfe) {
|
||||
LOG.e(LOG_TAG, "Crop operation not supported on this device");
|
||||
try {
|
||||
processResultFromCamera(destType, cameraIntent);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
LOG.e(LOG_TAG, "Unable to write to file");
|
||||
}
|
||||
}
|
||||
if (targetHeight > 0) {
|
||||
cropIntent.putExtra("outputY", targetHeight);
|
||||
}
|
||||
if (targetHeight > 0 && targetWidth > 0 && targetWidth == targetHeight) {
|
||||
cropIntent.putExtra("aspectX", 1);
|
||||
cropIntent.putExtra("aspectY", 1);
|
||||
}
|
||||
// create new file handle to get full resolution crop
|
||||
croppedUri = Uri.fromFile(createCaptureFile(this.encodingType, System.currentTimeMillis() + ""));
|
||||
cropIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
cropIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
|
||||
cropIntent.putExtra("output", croppedUri);
|
||||
|
||||
|
||||
// start the activity - we handle returning in onActivityResult
|
||||
|
||||
if (this.cordova != null) {
|
||||
this.cordova.startActivityForResult((CordovaPlugin) this,
|
||||
cropIntent, CROP_CAMERA + destType);
|
||||
}
|
||||
} catch (ActivityNotFoundException anfe) {
|
||||
LOG.e(LOG_TAG, "Crop operation not supported on this device");
|
||||
try {
|
||||
processResultFromCamera(destType, cameraIntent);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
LOG.e(LOG_TAG, "Unable to write to file");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies all needed transformation to the image received from the camera.
|
||||
@@ -476,9 +468,8 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
ExifHelper exif = new ExifHelper();
|
||||
|
||||
String sourcePath = (this.allowEdit && this.croppedUri != null) ?
|
||||
FileHelper.stripFileProtocol(this.croppedUri.toString()) :
|
||||
this.imageUri.getFilePath();
|
||||
|
||||
this.croppedFilePath :
|
||||
this.imageFilePath;
|
||||
|
||||
if (this.encodingType == JPEG) {
|
||||
try {
|
||||
@@ -499,16 +490,18 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
// in the gallery and the modified image is saved in the temporary
|
||||
// directory
|
||||
if (this.saveToPhotoAlbum) {
|
||||
galleryUri = Uri.fromFile(new File(getPicturesPath()));
|
||||
GalleryPathVO galleryPathVO = getPicturesPath();
|
||||
galleryUri = Uri.fromFile(new File(galleryPathVO.getGalleryPath()));
|
||||
|
||||
if (this.allowEdit && this.croppedUri != null) {
|
||||
writeUncompressedImage(croppedUri, galleryUri);
|
||||
} else {
|
||||
Uri imageUri = this.imageUri.getFileUri();
|
||||
writeUncompressedImage(imageUri, galleryUri);
|
||||
if (Build.VERSION.SDK_INT <= 28) { // Between LOLLIPOP_MR1 and P, can be changed later to the constant Build.VERSION_CODES.P
|
||||
writeTakenPictureToGalleryLowerThanAndroidQ(galleryUri);
|
||||
} else { // Android Q or higher
|
||||
writeTakenPictureToGalleryStartingFromAndroidQ(galleryPathVO);
|
||||
}
|
||||
}
|
||||
|
||||
refreshGallery(galleryUri);
|
||||
}
|
||||
|
||||
// If sending base64 image back
|
||||
@@ -536,7 +529,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
}
|
||||
|
||||
// If sending filename back
|
||||
else if (destType == FILE_URI || destType == NATIVE_URI) {
|
||||
else if (destType == FILE_URI) {
|
||||
// If all this is true we shouldn't compress the image.
|
||||
if (this.targetHeight == -1 && this.targetWidth == -1 && this.mQuality == 100 &&
|
||||
!this.correctOrientation) {
|
||||
@@ -549,10 +542,10 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
Uri uri = Uri.fromFile(createCaptureFile(this.encodingType, System.currentTimeMillis() + ""));
|
||||
|
||||
if (this.allowEdit && this.croppedUri != null) {
|
||||
Uri croppedUri = Uri.fromFile(new File(getFileNameFromUri(this.croppedUri)));
|
||||
Uri croppedUri = Uri.parse(croppedFilePath);
|
||||
writeUncompressedImage(croppedUri, uri);
|
||||
} else {
|
||||
Uri imageUri = this.imageUri.getFileUri();
|
||||
Uri imageUri = this.imageUri;
|
||||
writeUncompressedImage(imageUri, uri);
|
||||
}
|
||||
|
||||
@@ -572,9 +565,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
|
||||
// Add compressed version of captured image to returned media store Uri
|
||||
OutputStream os = this.cordova.getActivity().getContentResolver().openOutputStream(uri);
|
||||
CompressFormat compressFormat = encodingType == JPEG ?
|
||||
CompressFormat.JPEG :
|
||||
CompressFormat.PNG;
|
||||
CompressFormat compressFormat = getCompressFormatForEncodingType(encodingType);
|
||||
|
||||
bitmap.compress(compressFormat, this.mQuality, os);
|
||||
os.close();
|
||||
@@ -598,56 +589,69 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
this.cleanup(FILE_URI, this.imageUri.getFileUri(), galleryUri, bitmap);
|
||||
this.cleanup(FILE_URI, this.imageUri, galleryUri, bitmap);
|
||||
bitmap = null;
|
||||
}
|
||||
|
||||
private String getPicturesPath() {
|
||||
private void writeTakenPictureToGalleryLowerThanAndroidQ(Uri galleryUri) throws IOException {
|
||||
writeUncompressedImage(imageUri, galleryUri);
|
||||
refreshGallery(galleryUri);
|
||||
}
|
||||
|
||||
private void writeTakenPictureToGalleryStartingFromAndroidQ(GalleryPathVO galleryPathVO) throws IOException {
|
||||
// Starting from Android Q, working with the ACTION_MEDIA_SCANNER_SCAN_FILE intent is deprecated
|
||||
// https://developer.android.com/reference/android/content/Intent#ACTION_MEDIA_SCANNER_SCAN_FILE
|
||||
// we must start working with the MediaStore from Android Q on.
|
||||
ContentResolver resolver = this.cordova.getActivity().getContentResolver();
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, galleryPathVO.getGalleryFileName());
|
||||
contentValues.put(MediaStore.MediaColumns.MIME_TYPE, getMimetypeForEncodingType());
|
||||
Uri galleryOutputUri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
|
||||
|
||||
InputStream fileStream = org.apache.cordova.camera.FileHelper.getInputStreamFromUriString(imageUri.toString(), cordova);
|
||||
writeUncompressedImage(fileStream, galleryOutputUri);
|
||||
}
|
||||
|
||||
private CompressFormat getCompressFormatForEncodingType(int encodingType) {
|
||||
return encodingType == JPEG ? CompressFormat.JPEG : CompressFormat.PNG;
|
||||
}
|
||||
|
||||
private GalleryPathVO getPicturesPath() {
|
||||
String timeStamp = new SimpleDateFormat(TIME_FORMAT).format(new Date());
|
||||
String imageFileName = "IMG_" + timeStamp + (this.encodingType == JPEG ? JPEG_EXTENSION : PNG_EXTENSION);
|
||||
String imageFileName = "IMG_" + timeStamp + getExtensionForEncodingType();
|
||||
File storageDir = Environment.getExternalStoragePublicDirectory(
|
||||
Environment.DIRECTORY_PICTURES);
|
||||
storageDir.mkdirs();
|
||||
String galleryPath = storageDir.getAbsolutePath() + "/" + imageFileName;
|
||||
return galleryPath;
|
||||
return new GalleryPathVO(storageDir.getAbsolutePath(), imageFileName);
|
||||
}
|
||||
|
||||
private void refreshGallery(Uri contentUri) {
|
||||
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
|
||||
// Starting from Android Q, working with the ACTION_MEDIA_SCANNER_SCAN_FILE intent is deprecated
|
||||
mediaScanIntent.setData(contentUri);
|
||||
this.cordova.getActivity().sendBroadcast(mediaScanIntent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts output image format int value to string value of mime type.
|
||||
* @param outputFormat int Output format of camera API.
|
||||
* Must be value of either JPEG or PNG constant
|
||||
* @return String String value of mime type or empty string if mime type is not supported
|
||||
*/
|
||||
private String getMimetypeForFormat(int outputFormat) {
|
||||
if (outputFormat == PNG) return PNG_MIME_TYPE;
|
||||
if (outputFormat == JPEG) return JPEG_MIME_TYPE;
|
||||
private String getMimetypeForEncodingType() {
|
||||
if (encodingType == PNG) return PNG_MIME_TYPE;
|
||||
if (encodingType == JPEG) return JPEG_MIME_TYPE;
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
private String outputModifiedBitmap(Bitmap bitmap, Uri uri) throws IOException {
|
||||
private String outputModifiedBitmap(Bitmap bitmap, Uri uri, String mimeTypeOfOriginalFile) throws IOException {
|
||||
// Some content: URIs do not map to file paths (e.g. picasa).
|
||||
String realPath = FileHelper.getRealPath(uri, this.cordova);
|
||||
String fileName = calculateModifiedBitmapOutputFileName(mimeTypeOfOriginalFile, realPath);
|
||||
|
||||
// Get filename from uri
|
||||
String fileName = realPath != null ?
|
||||
realPath.substring(realPath.lastIndexOf('/') + 1) :
|
||||
"modified." + (this.encodingType == JPEG ? JPEG_TYPE : PNG_TYPE);
|
||||
|
||||
String timeStamp = new SimpleDateFormat(TIME_FORMAT).format(new Date());
|
||||
//String fileName = "IMG_" + timeStamp + (this.encodingType == JPEG ? ".jpg" : ".png");
|
||||
String modifiedPath = getTempDirectoryPath() + "/" + fileName;
|
||||
|
||||
OutputStream os = new FileOutputStream(modifiedPath);
|
||||
CompressFormat compressFormat = this.encodingType == JPEG ?
|
||||
CompressFormat.JPEG :
|
||||
CompressFormat.PNG;
|
||||
CompressFormat compressFormat = getCompressFormatForEncodingType(this.encodingType);
|
||||
|
||||
bitmap.compress(compressFormat, this.mQuality, os);
|
||||
os.close();
|
||||
@@ -667,6 +671,23 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
return modifiedPath;
|
||||
}
|
||||
|
||||
private String calculateModifiedBitmapOutputFileName(String mimeTypeOfOriginalFile, String realPath) {
|
||||
if (realPath == null) {
|
||||
return "modified" + getExtensionForEncodingType();
|
||||
}
|
||||
String fileName = realPath.substring(realPath.lastIndexOf('/') + 1);
|
||||
if (getMimetypeForEncodingType().equals(mimeTypeOfOriginalFile)) {
|
||||
return fileName;
|
||||
}
|
||||
// if the picture is not a jpeg or png, (a .heic for example) when processed to a bitmap
|
||||
// the file extension is changed to the output format, f.e. an input file my_photo.heic could become my_photo.jpg
|
||||
return fileName.substring(fileName.lastIndexOf(".") + 1) + getExtensionForEncodingType();
|
||||
}
|
||||
|
||||
private String getExtensionForEncodingType() {
|
||||
return this.encodingType == JPEG ? JPEG_EXTENSION : PNG_EXTENSION;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Applies all needed transformation to the image received from the gallery.
|
||||
@@ -684,74 +705,90 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
return;
|
||||
}
|
||||
}
|
||||
int rotate = 0;
|
||||
|
||||
String fileLocation = FileHelper.getRealPath(uri, this.cordova);
|
||||
LOG.d(LOG_TAG, "File location is: " + fileLocation);
|
||||
|
||||
String uriString = uri.toString();
|
||||
String mimeType = FileHelper.getMimeType(uriString, this.cordova);
|
||||
String finalLocation = fileLocation != null ? fileLocation : uriString;
|
||||
String mimeTypeOfGalleryFile = FileHelper.getMimeType(uriString, this.cordova);
|
||||
|
||||
// If you ask for video or the selected file doesn't have JPEG or PNG mime type
|
||||
// there will be no attempt to resize any returned data
|
||||
if (this.mediaType == VIDEO || !(JPEG_MIME_TYPE.equalsIgnoreCase(mimeType) || PNG_MIME_TYPE.equalsIgnoreCase(mimeType))) {
|
||||
this.callbackContext.success(fileLocation);
|
||||
}
|
||||
else {
|
||||
|
||||
// This is a special case to just return the path as no scaling,
|
||||
// rotating, nor compressing needs to be done
|
||||
if (this.targetHeight == -1 && this.targetWidth == -1 &&
|
||||
(destType == FILE_URI || destType == NATIVE_URI) && !this.correctOrientation &&
|
||||
mimeType != null && mimeType.equalsIgnoreCase(getMimetypeForFormat(encodingType)))
|
||||
{
|
||||
this.callbackContext.success(uriString);
|
||||
if (finalLocation == null) {
|
||||
this.failPicture("Error retrieving result.");
|
||||
} else {
|
||||
// If you ask for video or the selected file cannot be processed
|
||||
// there will be no attempt to resize any returned data.
|
||||
if (this.mediaType == VIDEO || !isImageMimeTypeProcessable(mimeTypeOfGalleryFile)) {
|
||||
this.callbackContext.success(finalLocation);
|
||||
} else {
|
||||
Bitmap bitmap = null;
|
||||
try {
|
||||
bitmap = getScaledAndRotatedBitmap(uriString);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (bitmap == null) {
|
||||
LOG.d(LOG_TAG, "I either have a null image path or bitmap");
|
||||
this.failPicture("Unable to create bitmap!");
|
||||
return;
|
||||
}
|
||||
|
||||
// If sending base64 image back
|
||||
if (destType == DATA_URL) {
|
||||
this.processPicture(bitmap, this.encodingType);
|
||||
}
|
||||
|
||||
// If sending filename back
|
||||
else if (destType == FILE_URI || destType == NATIVE_URI) {
|
||||
// Did we modify the image?
|
||||
if ( (this.targetHeight > 0 && this.targetWidth > 0) ||
|
||||
(this.correctOrientation && this.orientationCorrected) ||
|
||||
!mimeType.equalsIgnoreCase(getMimetypeForFormat(encodingType)))
|
||||
{
|
||||
try {
|
||||
String modifiedPath = this.outputModifiedBitmap(bitmap, uri);
|
||||
// The modified image is cached by the app in order to get around this and not have to delete you
|
||||
// application cache I'm adding the current system time to the end of the file url.
|
||||
this.callbackContext.success("file://" + modifiedPath + "?" + System.currentTimeMillis());
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
this.failPicture("Error retrieving image.");
|
||||
}
|
||||
} else {
|
||||
this.callbackContext.success(fileLocation);
|
||||
// This is a special case to just return the path as no scaling,
|
||||
// rotating, nor compressing needs to be done
|
||||
if (this.targetHeight == -1 && this.targetWidth == -1 &&
|
||||
destType == FILE_URI && !this.correctOrientation &&
|
||||
getMimetypeForEncodingType().equalsIgnoreCase(mimeTypeOfGalleryFile))
|
||||
{
|
||||
this.callbackContext.success(finalLocation);
|
||||
} else {
|
||||
Bitmap bitmap = null;
|
||||
try {
|
||||
bitmap = getScaledAndRotatedBitmap(uriString);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (bitmap == null) {
|
||||
LOG.d(LOG_TAG, "I either have a null image path or bitmap");
|
||||
this.failPicture("Unable to create bitmap!");
|
||||
return;
|
||||
}
|
||||
|
||||
// If sending base64 image back
|
||||
if (destType == DATA_URL) {
|
||||
this.processPicture(bitmap, this.encodingType);
|
||||
}
|
||||
|
||||
// If sending filename back
|
||||
else if (destType == FILE_URI) {
|
||||
// Did we modify the image?
|
||||
if ( (this.targetHeight > 0 && this.targetWidth > 0) ||
|
||||
(this.correctOrientation && this.orientationCorrected) ||
|
||||
!mimeTypeOfGalleryFile.equalsIgnoreCase(getMimetypeForEncodingType()))
|
||||
{
|
||||
try {
|
||||
String modifiedPath = this.outputModifiedBitmap(bitmap, uri, mimeTypeOfGalleryFile);
|
||||
// The modified image is cached by the app in order to get around this and not have to delete you
|
||||
// application cache I'm adding the current system time to the end of the file url.
|
||||
this.callbackContext.success("file://" + modifiedPath + "?" + System.currentTimeMillis());
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
this.failPicture("Error retrieving image: "+e.getLocalizedMessage());
|
||||
}
|
||||
} else {
|
||||
this.callbackContext.success(finalLocation);
|
||||
}
|
||||
}
|
||||
if (bitmap != null) {
|
||||
bitmap.recycle();
|
||||
bitmap = null;
|
||||
}
|
||||
System.gc();
|
||||
}
|
||||
if (bitmap != null) {
|
||||
bitmap.recycle();
|
||||
bitmap = null;
|
||||
}
|
||||
System.gc();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* JPEG, PNG and HEIC mime types (images) can be scaled, decreased in quantity, corrected by orientation.
|
||||
* But f.e. an image/gif cannot be scaled, but is can be selected through the PHOTOLIBRARY.
|
||||
*
|
||||
* @param mimeType The mimeType to check
|
||||
* @return if the mimeType is a processable image mime type
|
||||
*/
|
||||
private boolean isImageMimeTypeProcessable(String mimeType) {
|
||||
return JPEG_MIME_TYPE.equalsIgnoreCase(mimeType) || PNG_MIME_TYPE.equalsIgnoreCase(mimeType)
|
||||
|| HEIC_MIME_TYPE.equalsIgnoreCase(mimeType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -799,7 +836,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
try {
|
||||
if (this.allowEdit) {
|
||||
Uri tmpFile = FileProvider.getUriForFile(cordova.getActivity(),
|
||||
applicationId + ".provider",
|
||||
applicationId + ".cordova.plugin.camera.provider",
|
||||
createCaptureFile(this.encodingType));
|
||||
performCrop(tmpFile, destType, intent);
|
||||
} else {
|
||||
@@ -807,7 +844,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
this.failPicture("Error capturing image.");
|
||||
this.failPicture("Error capturing image: "+e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -898,34 +935,11 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
private void writeUncompressedImage(Uri src, Uri dest) throws FileNotFoundException,
|
||||
IOException {
|
||||
|
||||
FileInputStream fis = new FileInputStream(FileHelper.stripFileProtocol(src.toString()));
|
||||
InputStream fis = FileHelper.getInputStreamFromUriString(src.toString(), cordova);
|
||||
writeUncompressedImage(fis, dest);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create entry in media store for image
|
||||
*
|
||||
* @return uri
|
||||
*/
|
||||
private Uri getUriFromMediaStore() {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(MediaStore.Images.Media.MIME_TYPE, JPEG_MIME_TYPE);
|
||||
Uri uri;
|
||||
try {
|
||||
uri = this.cordova.getActivity().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
|
||||
} catch (RuntimeException e) {
|
||||
LOG.d(LOG_TAG, "Can't write to external media storage.");
|
||||
try {
|
||||
uri = this.cordova.getActivity().getContentResolver().insert(MediaStore.Images.Media.INTERNAL_CONTENT_URI, values);
|
||||
} catch (RuntimeException ex) {
|
||||
LOG.d(LOG_TAG, "Can't write to internal media storage.");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a scaled and rotated bitmap based on the target width and height
|
||||
*
|
||||
@@ -974,7 +988,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
if (fileStream != null) {
|
||||
// Generate a temporary file
|
||||
String timeStamp = new SimpleDateFormat(TIME_FORMAT).format(new Date());
|
||||
String fileName = "IMG_" + timeStamp + (this.encodingType == JPEG ? JPEG_EXTENSION : PNG_EXTENSION);
|
||||
String fileName = "IMG_" + timeStamp + (getExtensionForEncodingType());
|
||||
localFile = new File(getTempDirectoryPath() + fileName);
|
||||
galleryUri = Uri.fromFile(localFile);
|
||||
writeUncompressedImage(fileStream, galleryUri);
|
||||
@@ -998,15 +1012,11 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
rotate = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
} catch (Exception e) {
|
||||
LOG.e(LOG_TAG,"Exception while getting input stream: "+ e.toString());
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
try {
|
||||
// figure out the original width and height of the image
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
@@ -1052,7 +1062,6 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
// determine the correct aspect ratio
|
||||
int[] widthHeight = calculateAspectRatio(rotatedWidth, rotatedHeight);
|
||||
|
||||
|
||||
// Load in the smallest bitmap possible that is closest to the size we want
|
||||
options.inJustDecodeBounds = false;
|
||||
options.inSampleSize = calculateSampleSize(rotatedWidth, rotatedHeight, widthHeight[0], widthHeight[1]);
|
||||
@@ -1092,8 +1101,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
}
|
||||
}
|
||||
return scaledBitmap;
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
// delete the temporary copy
|
||||
if (localFile != null) {
|
||||
localFile.delete();
|
||||
@@ -1256,9 +1264,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
*/
|
||||
public void processPicture(Bitmap bitmap, int encodingType) {
|
||||
ByteArrayOutputStream jpeg_data = new ByteArrayOutputStream();
|
||||
CompressFormat compressFormat = encodingType == JPEG ?
|
||||
CompressFormat.JPEG :
|
||||
CompressFormat.PNG;
|
||||
CompressFormat compressFormat = getCompressFormatForEncodingType(encodingType);
|
||||
|
||||
try {
|
||||
if (bitmap.compress(compressFormat, mQuality, jpeg_data)) {
|
||||
@@ -1271,7 +1277,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
code = null;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
this.failPicture("Error compressing image.");
|
||||
this.failPicture("Error compressing image: "+e.getLocalizedMessage());
|
||||
}
|
||||
jpeg_data = null;
|
||||
}
|
||||
@@ -1307,9 +1313,8 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
this.conn.disconnect();
|
||||
}
|
||||
|
||||
|
||||
public void onRequestPermissionResult(int requestCode, String[] permissions,
|
||||
int[] grantResults) throws JSONException {
|
||||
int[] grantResults) {
|
||||
for (int r : grantResults) {
|
||||
if (r == PackageManager.PERMISSION_DENIED) {
|
||||
this.callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, PERMISSION_DENIED_ERROR));
|
||||
@@ -1321,7 +1326,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
takePicture(this.destType, this.encodingType);
|
||||
break;
|
||||
case SAVE_TO_ALBUM_SEC:
|
||||
this.getImage(this.srcType, this.destType, this.encodingType);
|
||||
this.getImage(this.srcType, this.destType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1346,11 +1351,15 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
state.putBoolean("saveToPhotoAlbum", this.saveToPhotoAlbum);
|
||||
|
||||
if (this.croppedUri != null) {
|
||||
state.putString(CROPPED_URI_KEY, this.croppedUri.toString());
|
||||
state.putString(CROPPED_URI_KEY, this.croppedFilePath);
|
||||
}
|
||||
|
||||
if (this.imageUri != null) {
|
||||
state.putString(IMAGE_URI_KEY, this.imageUri.getFileUri().toString());
|
||||
state.putString(IMAGE_URI_KEY, this.imageFilePath);
|
||||
}
|
||||
|
||||
if (this.imageFilePath != null) {
|
||||
state.putString(IMAGE_FILE_PATH_KEY, this.imageFilePath);
|
||||
}
|
||||
|
||||
return state;
|
||||
@@ -1375,28 +1384,13 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
|
||||
if (state.containsKey(IMAGE_URI_KEY)) {
|
||||
//I have no idea what type of URI is being passed in
|
||||
this.imageUri = new CordovaUri(Uri.parse(state.getString(IMAGE_URI_KEY)));
|
||||
this.imageUri = Uri.parse(state.getString(IMAGE_URI_KEY));
|
||||
}
|
||||
|
||||
if (state.containsKey(IMAGE_FILE_PATH_KEY)) {
|
||||
this.imageFilePath = state.getString(IMAGE_FILE_PATH_KEY);
|
||||
}
|
||||
|
||||
this.callbackContext = callbackContext;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
/*
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,6 @@ package org.apache.cordova.camera;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.ContentUris;
|
||||
import android.content.Context;
|
||||
import android.content.CursorLoader;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
@@ -29,8 +28,8 @@ import android.provider.MediaStore;
|
||||
import android.webkit.MimeTypeMap;
|
||||
|
||||
import org.apache.cordova.CordovaInterface;
|
||||
import org.apache.cordova.LOG;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -44,29 +43,20 @@ public class FileHelper {
|
||||
* Returns the real path of the given URI string.
|
||||
* If the given URI string represents a content:// URI, the real path is retrieved from the media store.
|
||||
*
|
||||
* @param uriString the URI string of the audio/image/video
|
||||
* @param uri the URI of the audio/image/video
|
||||
* @param cordova the current application context
|
||||
* @return the full path to the file
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public static String getRealPath(Uri uri, CordovaInterface cordova) {
|
||||
String realPath = null;
|
||||
|
||||
if (Build.VERSION.SDK_INT < 11)
|
||||
realPath = FileHelper.getRealPathFromURI_BelowAPI11(cordova.getActivity(), uri);
|
||||
|
||||
// SDK >= 11
|
||||
else
|
||||
realPath = FileHelper.getRealPathFromURI_API11_And_Above(cordova.getActivity(), uri);
|
||||
|
||||
return realPath;
|
||||
return FileHelper.getRealPathFromURI(cordova.getActivity(), uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the real path of the given URI.
|
||||
* If the given URI is a content:// URI, the real path is retrieved from the media store.
|
||||
*
|
||||
* @param uri the URI of the audio/image/video
|
||||
* @param uriString the URI string from which to obtain the input stream
|
||||
* @param cordova the current application context
|
||||
* @return the full path to the file
|
||||
*/
|
||||
@@ -75,11 +65,9 @@ public class FileHelper {
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
public static String getRealPathFromURI_API11_And_Above(final Context context, final Uri uri) {
|
||||
|
||||
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
|
||||
public static String getRealPathFromURI(final Context context, final Uri uri) {
|
||||
// DocumentProvider
|
||||
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
|
||||
if (DocumentsContract.isDocumentUri(context, uri)) {
|
||||
|
||||
// ExternalStorageProvider
|
||||
if (isExternalStorageDocument(uri)) {
|
||||
@@ -143,6 +131,9 @@ public class FileHelper {
|
||||
if (isGooglePhotosUri(uri))
|
||||
return uri.getLastPathSegment();
|
||||
|
||||
if (isFileProviderUri(context, uri))
|
||||
return getFileProviderPath(context, uri);
|
||||
|
||||
return getDataColumn(context, uri, null, null);
|
||||
}
|
||||
// File
|
||||
@@ -153,22 +144,6 @@ public class FileHelper {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getRealPathFromURI_BelowAPI11(Context context, Uri contentUri) {
|
||||
String[] proj = { MediaStore.Images.Media.DATA };
|
||||
String result = null;
|
||||
|
||||
try {
|
||||
Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
|
||||
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
|
||||
cursor.moveToFirst();
|
||||
result = cursor.getString(column_index);
|
||||
|
||||
} catch (Exception e) {
|
||||
result = null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an input stream based on given URI string.
|
||||
*
|
||||
@@ -188,6 +163,7 @@ public class FileHelper {
|
||||
if (question > -1) {
|
||||
uriString = uriString.substring(0, question);
|
||||
}
|
||||
|
||||
if (uriString.startsWith("file:///android_asset/")) {
|
||||
Uri uri = Uri.parse(uriString);
|
||||
String relativePath = uri.getPath().substring(15);
|
||||
@@ -217,6 +193,7 @@ public class FileHelper {
|
||||
* @return a path without the "file://" prefix
|
||||
*/
|
||||
public static String stripFileProtocol(String uriString) {
|
||||
|
||||
if (uriString.startsWith("file://")) {
|
||||
uriString = uriString.substring(7);
|
||||
}
|
||||
@@ -236,7 +213,7 @@ public class FileHelper {
|
||||
}
|
||||
return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the mime type of the data specified by the given URI string.
|
||||
*
|
||||
@@ -244,7 +221,7 @@ public class FileHelper {
|
||||
* @return the mime type of the specified data
|
||||
*/
|
||||
public static String getMimeType(String uriString, CordovaInterface cordova) {
|
||||
String mimeType = null;
|
||||
String mimeType;
|
||||
|
||||
Uri uri = Uri.parse(uriString);
|
||||
if (uriString.startsWith("content://")) {
|
||||
@@ -327,4 +304,28 @@ public class FileHelper {
|
||||
public static boolean isGooglePhotosUri(Uri uri) {
|
||||
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param context The Application context
|
||||
* @param uri The Uri is checked by functions
|
||||
* @return Whether the Uri authority is FileProvider
|
||||
*/
|
||||
public static boolean isFileProviderUri(final Context context, final Uri uri) {
|
||||
final String packageName = context.getPackageName();
|
||||
final String authority = new StringBuilder(packageName).append(".provider").toString();
|
||||
return authority.equals(uri.getAuthority());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param context The Application context
|
||||
* @param uri The Uri is checked by functions
|
||||
* @return File path or null if file is missing
|
||||
*/
|
||||
public static String getFileProviderPath(final Context context, final Uri uri)
|
||||
{
|
||||
final File appDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
|
||||
final File file = new File(appDir, uri.getLastPathSegment());
|
||||
return file.exists() ? file.toString(): null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,4 +18,4 @@
|
||||
*/
|
||||
package org.apache.cordova.camera;
|
||||
|
||||
public class FileProvider extends android.support.v4.content.FileProvider {}
|
||||
public class FileProvider extends androidx.core.content.FileProvider {}
|
||||
|
||||
43
src/android/GalleryPathVO.java
Normal file
43
src/android/GalleryPathVO.java
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
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;
|
||||
|
||||
public class GalleryPathVO {
|
||||
private final String galleryPath;
|
||||
private String picturesDirectory;
|
||||
private String galleryFileName;
|
||||
|
||||
public GalleryPathVO(String picturesDirectory, String galleryFileName) {
|
||||
this.picturesDirectory = picturesDirectory;
|
||||
this.galleryFileName = galleryFileName;
|
||||
this.galleryPath = this.picturesDirectory + "/" + this.galleryFileName;
|
||||
}
|
||||
|
||||
public String getGalleryPath() {
|
||||
return galleryPath;
|
||||
}
|
||||
|
||||
public String getPicturesDirectory() {
|
||||
return picturesDirectory;
|
||||
}
|
||||
|
||||
public String getGalleryFileName() {
|
||||
return galleryFileName;
|
||||
}
|
||||
}
|
||||
@@ -17,5 +17,5 @@
|
||||
-->
|
||||
|
||||
<paths xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<external-path name="external_files" path="."/>
|
||||
<cache-path name="cache_files" path="." />
|
||||
</paths>
|
||||
@@ -112,7 +112,7 @@ function capture (success, errorCallback, opts) {
|
||||
};
|
||||
|
||||
if (navigator.getUserMedia) {
|
||||
navigator.getUserMedia({video: true, audio: false}, successCallback, errorCallback);
|
||||
navigator.getUserMedia({ video: true, audio: false }, successCallback, errorCallback);
|
||||
} else {
|
||||
alert('Browser does not support camera :(');
|
||||
}
|
||||
|
||||
@@ -24,8 +24,7 @@
|
||||
|
||||
enum CDVDestinationType {
|
||||
DestinationTypeDataUrl = 0,
|
||||
DestinationTypeFileUri,
|
||||
DestinationTypeNativeUri
|
||||
DestinationTypeFileUri
|
||||
};
|
||||
typedef NSUInteger CDVDestinationType;
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@ static NSString* toBase64(NSData* data) {
|
||||
[weakSelf sendNoPermissionResult:command.callbackId];
|
||||
}]];
|
||||
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Settings", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
|
||||
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
|
||||
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString] options:@{} completionHandler:nil];
|
||||
[weakSelf sendNoPermissionResult:command.callbackId];
|
||||
}]];
|
||||
[weakSelf.viewController presentViewController:alertController animated:YES completion:nil];
|
||||
@@ -185,16 +185,16 @@ static NSString* toBase64(NSData* data) {
|
||||
|
||||
- (void)showCameraPicker:(NSString*)callbackId withOptions:(CDVPictureOptions *) pictureOptions
|
||||
{
|
||||
CDVCameraPicker* cameraPicker = [CDVCameraPicker createFromPictureOptions:pictureOptions];
|
||||
self.pickerController = cameraPicker;
|
||||
|
||||
cameraPicker.delegate = self;
|
||||
cameraPicker.callbackId = callbackId;
|
||||
// we need to capture this state for memory warnings that dealloc this object
|
||||
cameraPicker.webView = self.webView;
|
||||
|
||||
// Perform UI operations on the main thread
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
CDVCameraPicker* cameraPicker = [CDVCameraPicker createFromPictureOptions:pictureOptions];
|
||||
self.pickerController = cameraPicker;
|
||||
|
||||
cameraPicker.delegate = self;
|
||||
cameraPicker.callbackId = callbackId;
|
||||
// we need to capture this state for memory warnings that dealloc this object
|
||||
cameraPicker.webView = self.webView;
|
||||
|
||||
// If a popover is already open, close it; we only want one at a time.
|
||||
if (([[self pickerController] pickerPopoverController] != nil) && [[[self pickerController] pickerPopoverController] isPopoverVisible]) {
|
||||
[[[self pickerController] pickerPopoverController] dismissPopoverAnimated:YES];
|
||||
@@ -374,7 +374,7 @@ static NSString* toBase64(NSData* data) {
|
||||
self.metadata = [[NSMutableDictionary alloc] init];
|
||||
|
||||
NSMutableDictionary* EXIFDictionary = [[controllerMetadata objectForKey:(NSString*)kCGImagePropertyExifDictionary]mutableCopy];
|
||||
if (EXIFDictionary) {
|
||||
if (EXIFDictionary) {
|
||||
[self.metadata setObject:EXIFDictionary forKey:(NSString*)kCGImagePropertyExifDictionary];
|
||||
}
|
||||
|
||||
@@ -383,6 +383,7 @@ static NSString* toBase64(NSData* data) {
|
||||
}
|
||||
[[self locationManager] startUpdatingLocation];
|
||||
}
|
||||
data = nil;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -396,14 +397,10 @@ static NSString* toBase64(NSData* data) {
|
||||
- (NSString*)tempFilePath:(NSString*)extension
|
||||
{
|
||||
NSString* docsPath = [NSTemporaryDirectory()stringByStandardizingPath];
|
||||
NSFileManager* fileMgr = [[NSFileManager alloc] init]; // recommended by Apple (vs [NSFileManager defaultManager]) to be threadsafe
|
||||
NSString* filePath;
|
||||
|
||||
// generate unique file name
|
||||
int i = 1;
|
||||
do {
|
||||
filePath = [NSString stringWithFormat:@"%@/%@%03d.%@", docsPath, CDV_PHOTO_PREFIX, i++, extension];
|
||||
} while ([fileMgr fileExistsAtPath:filePath]);
|
||||
// unique file name
|
||||
NSTimeInterval timeStamp = [[NSDate date] timeIntervalSince1970];
|
||||
NSNumber *timeStampObj = [NSNumber numberWithDouble: timeStamp];
|
||||
NSString* filePath = [NSString stringWithFormat:@"%@/%@%ld.%@", docsPath, CDV_PHOTO_PREFIX, [timeStampObj longValue], extension];
|
||||
|
||||
return filePath;
|
||||
}
|
||||
@@ -443,33 +440,16 @@ static NSString* toBase64(NSData* data) {
|
||||
UIImage* image = nil;
|
||||
|
||||
switch (options.destinationType) {
|
||||
case DestinationTypeNativeUri:
|
||||
case DestinationTypeDataUrl:
|
||||
{
|
||||
NSURL* url = [info objectForKey:UIImagePickerControllerReferenceURL];
|
||||
saveToPhotoAlbum = NO;
|
||||
// If, for example, we use sourceType = Camera, URL might be nil because image is stored in memory.
|
||||
// In this case we must save image to device before obtaining an URI.
|
||||
if (url == nil) {
|
||||
image = [self retrieveImage:info options:options];
|
||||
ALAssetsLibrary* library = [ALAssetsLibrary new];
|
||||
[library writeImageToSavedPhotosAlbum:image.CGImage orientation:(ALAssetOrientation)(image.imageOrientation) completionBlock:^(NSURL *assetURL, NSError *error) {
|
||||
CDVPluginResult* resultToReturn = nil;
|
||||
if (error) {
|
||||
resultToReturn = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsString:[error localizedDescription]];
|
||||
} else {
|
||||
NSString* nativeUri = [[self urlTransformer:assetURL] absoluteString];
|
||||
resultToReturn = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:nativeUri];
|
||||
}
|
||||
completion(resultToReturn);
|
||||
}];
|
||||
return;
|
||||
} else {
|
||||
NSString* nativeUri = [[self urlTransformer:url] absoluteString];
|
||||
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:nativeUri];
|
||||
image = [self retrieveImage:info options:options];
|
||||
NSData* data = [self processImage:image info:info options:options];
|
||||
if (data) {
|
||||
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:toBase64(data)];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DestinationTypeFileUri:
|
||||
default: // DestinationTypeFileUri
|
||||
{
|
||||
image = [self retrieveImage:info options:options];
|
||||
NSData* data = [self processImage:image info:info options:options];
|
||||
@@ -488,22 +468,10 @@ static NSString* toBase64(NSData* data) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DestinationTypeDataUrl:
|
||||
{
|
||||
image = [self retrieveImage:info options:options];
|
||||
NSData* data = [self processImage:image info:info options:options];
|
||||
if (data) {
|
||||
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:toBase64(data)];
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
if (saveToPhotoAlbum && image) {
|
||||
ALAssetsLibrary* library = [ALAssetsLibrary new];
|
||||
[library writeImageToSavedPhotosAlbum:image.CGImage orientation:(ALAssetOrientation)(image.imageOrientation) completionBlock:nil];
|
||||
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
|
||||
}
|
||||
|
||||
completion(result);
|
||||
@@ -512,9 +480,22 @@ static NSString* toBase64(NSData* data) {
|
||||
- (CDVPluginResult*)resultForVideo:(NSDictionary*)info
|
||||
{
|
||||
NSString* moviePath = [[info objectForKey:UIImagePickerControllerMediaURL] absoluteString];
|
||||
// On iOS 13 the movie path becomes inaccessible, create and return a copy
|
||||
if (IsAtLeastiOSVersion(@"13.0")) {
|
||||
moviePath = [self createTmpVideo:[[info objectForKey:UIImagePickerControllerMediaURL] path]];
|
||||
}
|
||||
return [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:moviePath];
|
||||
}
|
||||
|
||||
- (NSString *) createTmpVideo:(NSString *) moviePath {
|
||||
NSString* moviePathExtension = [moviePath pathExtension];
|
||||
NSString* copyMoviePath = [self tempFilePath:moviePathExtension];
|
||||
NSFileManager* fileMgr = [[NSFileManager alloc] init];
|
||||
NSError *error;
|
||||
[fileMgr copyItemAtPath:moviePath toPath:copyMoviePath error:&error];
|
||||
return [[NSURL fileURLWithPath:copyMoviePath] absoluteString];
|
||||
}
|
||||
|
||||
- (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info
|
||||
{
|
||||
__weak CDVCameraPicker* cameraPicker = (CDVCameraPicker*)picker;
|
||||
@@ -566,10 +547,8 @@ static NSString* toBase64(NSData* data) {
|
||||
|
||||
dispatch_block_t invoke = ^ (void) {
|
||||
CDVPluginResult* result;
|
||||
if (picker.sourceType == UIImagePickerControllerSourceTypeCamera && [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo] != ALAuthorizationStatusAuthorized) {
|
||||
if (picker.sourceType == UIImagePickerControllerSourceTypeCamera && [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo] != AVAuthorizationStatusAuthorized) {
|
||||
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"has no access to camera"];
|
||||
} else if (picker.sourceType != UIImagePickerControllerSourceTypeCamera && ! IsAtLeastiOSVersion(@"11.0") && [ALAssetsLibrary authorizationStatus] != ALAuthorizationStatusAuthorized) {
|
||||
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"has no access to assets"];
|
||||
} else {
|
||||
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"No Image Selected"];
|
||||
}
|
||||
@@ -586,15 +565,15 @@ static NSString* toBase64(NSData* data) {
|
||||
|
||||
- (CLLocationManager*)locationManager
|
||||
{
|
||||
if (locationManager != nil) {
|
||||
return locationManager;
|
||||
}
|
||||
if (locationManager != nil) {
|
||||
return locationManager;
|
||||
}
|
||||
|
||||
locationManager = [[CLLocationManager alloc] init];
|
||||
[locationManager setDesiredAccuracy:kCLLocationAccuracyNearestTenMeters];
|
||||
[locationManager setDelegate:self];
|
||||
locationManager = [[CLLocationManager alloc] init];
|
||||
[locationManager setDesiredAccuracy:kCLLocationAccuracyNearestTenMeters];
|
||||
[locationManager setDelegate:self];
|
||||
|
||||
return locationManager;
|
||||
return locationManager;
|
||||
}
|
||||
|
||||
- (void)locationManager:(CLLocationManager*)manager didUpdateToLocation:(CLLocation*)newLocation fromLocation:(CLLocation*)oldLocation
|
||||
@@ -672,19 +651,26 @@ static NSString* toBase64(NSData* data) {
|
||||
CDVPluginResult* result = nil;
|
||||
|
||||
if (self.metadata) {
|
||||
CGImageSourceRef sourceImage = CGImageSourceCreateWithData((__bridge CFDataRef)self.data, NULL);
|
||||
NSData* dataCopy = [self.data mutableCopy];
|
||||
CGImageSourceRef sourceImage = CGImageSourceCreateWithData((__bridge CFDataRef)dataCopy, NULL);
|
||||
CFStringRef sourceType = CGImageSourceGetType(sourceImage);
|
||||
|
||||
CGImageDestinationRef destinationImage = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)self.data, sourceType, 1, NULL);
|
||||
CGImageDestinationAddImageFromSource(destinationImage, sourceImage, 0, (__bridge CFDictionaryRef)self.metadata);
|
||||
CGImageDestinationFinalize(destinationImage);
|
||||
|
||||
dataCopy = nil;
|
||||
CFRelease(sourceImage);
|
||||
CFRelease(destinationImage);
|
||||
}
|
||||
|
||||
switch (options.destinationType) {
|
||||
case DestinationTypeFileUri:
|
||||
case DestinationTypeDataUrl:
|
||||
{
|
||||
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:toBase64(self.data)];
|
||||
}
|
||||
break;
|
||||
default: // DestinationTypeFileUri
|
||||
{
|
||||
NSError* err = nil;
|
||||
NSString* extension = self.pickerController.pictureOptions.encodingType == EncodingTypePNG ? @"png":@"jpg";
|
||||
@@ -699,14 +685,6 @@ static NSString* toBase64(NSData* data) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DestinationTypeDataUrl:
|
||||
{
|
||||
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:toBase64(self.data)];
|
||||
}
|
||||
break;
|
||||
case DestinationTypeNativeUri:
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
if (result) {
|
||||
@@ -719,8 +697,7 @@ static NSString* toBase64(NSData* data) {
|
||||
self.metadata = nil;
|
||||
|
||||
if (options.saveToPhotoAlbum) {
|
||||
ALAssetsLibrary *library = [ALAssetsLibrary new];
|
||||
[library writeImageDataToSavedPhotosAlbum:self.data metadata:self.metadata completionBlock:nil];
|
||||
UIImageWriteToSavedPhotosAlbum([[UIImage alloc] initWithData:self.data], nil, nil, nil);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,8 +24,7 @@
|
||||
|
||||
enum CDVDestinationType {
|
||||
DestinationTypeDataUrl = 0,
|
||||
DestinationTypeFileUri,
|
||||
DestinationTypeNativeUri
|
||||
DestinationTypeFileUri
|
||||
};
|
||||
typedef NSUInteger CDVDestinationType;
|
||||
|
||||
|
||||
@@ -161,7 +161,7 @@ static NSMutableArray *cleanUpFiles;
|
||||
|
||||
/*!
|
||||
Returns to JavaScript a URI.
|
||||
Called when Camera.DestinationType.FILE_URI or Camera.DestinationType.NATIVE_URI.
|
||||
Called when Camera.DestinationType.FILE_URI.
|
||||
*/
|
||||
- (void)returnUri:(NSString *)path command:(CDVInvokedUrlCommand *)command options:(CDVPictureOptions *)pictureOptions {
|
||||
NSString *protocol = (pictureOptions.destinationType == DestinationTypeFileUri) ? @"file://" : @"";
|
||||
|
||||
@@ -190,17 +190,13 @@ function takePictureFromFileWP (successCallback, errorCallback, args) {
|
||||
webUIApp.removeEventListener('activated', filePickerActivationHandler);
|
||||
return;
|
||||
}
|
||||
if (destinationType === Camera.DestinationType.FILE_URI || destinationType === Camera.DestinationType.NATIVE_URI) {
|
||||
if (destinationType === Camera.DestinationType.FILE_URI) {
|
||||
if (targetHeight > 0 && targetWidth > 0) {
|
||||
resizeImage(successCallback, errorCallback, file, targetWidth, targetHeight, encodingType);
|
||||
} else {
|
||||
var storageFolder = getAppData().localFolder;
|
||||
file.copyAsync(storageFolder, file.name, Windows.Storage.NameCollisionOption.replaceExisting).done(function (storageFile) {
|
||||
if (destinationType === Camera.DestinationType.NATIVE_URI) {
|
||||
successCallback('ms-appdata:///local/' + storageFile.name);
|
||||
} else {
|
||||
successCallback(URL.createObjectURL(storageFile));
|
||||
}
|
||||
successCallback(URL.createObjectURL(storageFile));
|
||||
}, function () {
|
||||
errorCallback("Can't access localStorage folder.");
|
||||
});
|
||||
@@ -259,17 +255,13 @@ function takePictureFromFileWindows (successCallback, errorCallback, args) {
|
||||
errorCallback("User didn't choose a file.");
|
||||
return;
|
||||
}
|
||||
if (destinationType === Camera.DestinationType.FILE_URI || destinationType === Camera.DestinationType.NATIVE_URI) {
|
||||
if (destinationType === Camera.DestinationType.FILE_URI) {
|
||||
if (targetHeight > 0 && targetWidth > 0) {
|
||||
resizeImage(successCallback, errorCallback, file, targetWidth, targetHeight, encodingType);
|
||||
} else {
|
||||
var storageFolder = getAppData().localFolder;
|
||||
file.copyAsync(storageFolder, file.name, Windows.Storage.NameCollisionOption.replaceExisting).done(function (storageFile) {
|
||||
if (destinationType === Camera.DestinationType.NATIVE_URI) {
|
||||
successCallback('ms-appdata:///local/' + storageFile.name);
|
||||
} else {
|
||||
successCallback(URL.createObjectURL(storageFile));
|
||||
}
|
||||
successCallback(URL.createObjectURL(storageFile));
|
||||
}, function () {
|
||||
errorCallback("Can't access localStorage folder.");
|
||||
});
|
||||
@@ -374,7 +366,6 @@ function takePictureFromCameraWP (successCallback, errorCallback, args) {
|
||||
|
||||
return capture.initializeAsync(captureSettings);
|
||||
}).then(function () {
|
||||
|
||||
// create focus control if available
|
||||
var VideoDeviceController = capture.videoDeviceController;
|
||||
var FocusControl = VideoDeviceController.focusControl;
|
||||
@@ -477,7 +468,6 @@ function takePictureFromCameraWP (successCallback, errorCallback, args) {
|
||||
}
|
||||
|
||||
function captureAction () {
|
||||
|
||||
var encodingProperties;
|
||||
var fileName;
|
||||
var tempFolder = getAppData().temporaryFolder;
|
||||
@@ -715,7 +705,7 @@ function takePictureFromCameraWindows (successCallback, errorCallback, args) {
|
||||
|
||||
if (targetWidth === -1 && targetHeight === -1) {
|
||||
maxRes = UIMaxRes.highestAvailable;
|
||||
// Temp fix for CB-10539
|
||||
// Temp fix for CB-10539
|
||||
/* else if (totalPixels <= 320 * 240) {
|
||||
maxRes = UIMaxRes.verySmallQvga;
|
||||
} */
|
||||
@@ -781,7 +771,7 @@ function takePictureFromCameraWindows (successCallback, errorCallback, args) {
|
||||
function savePhoto (picture, options, successCallback, errorCallback) {
|
||||
// success callback for capture operation
|
||||
var success = function (picture) {
|
||||
if (options.destinationType === Camera.DestinationType.FILE_URI || options.destinationType === Camera.DestinationType.NATIVE_URI) {
|
||||
if (options.destinationType === Camera.DestinationType.FILE_URI) {
|
||||
if (options.targetHeight > 0 && options.targetWidth > 0) {
|
||||
resizeImage(successCallback, errorCallback, picture, options.targetWidth, options.targetHeight, options.encodingType);
|
||||
} else {
|
||||
@@ -812,7 +802,6 @@ function savePhoto (picture, options, successCallback, errorCallback) {
|
||||
|
||||
if (!options.saveToPhotoAlbum) {
|
||||
success(picture);
|
||||
|
||||
} else {
|
||||
var savePicker = new Windows.Storage.Pickers.FileSavePicker();
|
||||
var saveFile = function (file) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cordova-plugin-camera-tests",
|
||||
"version": "4.1.0",
|
||||
"version": "6.0.0",
|
||||
"description": "",
|
||||
"cordova": {
|
||||
"id": "cordova-plugin-camera-tests",
|
||||
|
||||
@@ -22,12 +22,10 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:rim="http://www.blackberry.com/ns/widgets"
|
||||
id="cordova-plugin-camera-tests"
|
||||
version="4.1.0">
|
||||
version="6.0.0">
|
||||
<name>Cordova Camera Plugin Tests</name>
|
||||
<license>Apache 2.0</license>
|
||||
|
||||
<dependency id="cordova-plugin-file-transfer" />
|
||||
|
||||
<js-module src="tests.js" name="tests">
|
||||
</js-module>
|
||||
</plugin>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/* globals Camera, resolveLocalFileSystemURL, FileEntry, CameraPopoverOptions, FileTransfer, FileUploadOptions, LocalFileSystem, MSApp */
|
||||
/* globals Camera, resolveLocalFileSystemURL, FileEntry, CameraPopoverOptions, LocalFileSystem, MSApp */
|
||||
/* eslint-env jasmine */
|
||||
|
||||
exports.defineAutoTests = function () {
|
||||
@@ -42,10 +42,8 @@ exports.defineAutoTests = function () {
|
||||
it('camera.spec.2 should contain three DestinationType constants', function () {
|
||||
expect(Camera.DestinationType.DATA_URL).toBe(0);
|
||||
expect(Camera.DestinationType.FILE_URI).toBe(1);
|
||||
expect(Camera.DestinationType.NATIVE_URI).toBe(2);
|
||||
expect(navigator.camera.DestinationType.DATA_URL).toBe(0);
|
||||
expect(navigator.camera.DestinationType.FILE_URI).toBe(1);
|
||||
expect(navigator.camera.DestinationType.NATIVE_URI).toBe(2);
|
||||
});
|
||||
|
||||
it('camera.spec.3 should contain two EncodingType constants', function () {
|
||||
@@ -140,7 +138,7 @@ exports.defineManualTests = function (contentEl, createActionButton) {
|
||||
function getPictureWin (data) {
|
||||
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) {
|
||||
if (pictureUrl.indexOf('file:') === 0 || pictureUrl.indexOf('content:') === 0) {
|
||||
resolveLocalFileSystemURL(data, function (e) {
|
||||
fileEntry = e;
|
||||
logCallback('resolveLocalFileSystemURL()', true)(e.toURL());
|
||||
@@ -167,26 +165,6 @@ exports.defineManualTests = function (contentEl, createActionButton) {
|
||||
};
|
||||
}
|
||||
|
||||
function uploadImage () {
|
||||
var ft = new FileTransfer();
|
||||
var options = new FileUploadOptions();
|
||||
options.fileKey = 'photo';
|
||||
options.fileName = 'test.jpg';
|
||||
options.mimeType = 'image/jpeg';
|
||||
ft.onprogress = function (progressEvent) {
|
||||
console.log('progress: ' + progressEvent.loaded + ' of ' + progressEvent.total);
|
||||
};
|
||||
var server = 'http://sheltered-retreat-43956.herokuapp.com';
|
||||
|
||||
ft.upload(pictureUrl, server + '/upload', win, fail, options);
|
||||
function win (information_back) {
|
||||
log('upload complete');
|
||||
}
|
||||
function fail (message) {
|
||||
log('upload failed: ' + JSON.stringify(message));
|
||||
}
|
||||
}
|
||||
|
||||
function logCallback (apiName, success) {
|
||||
return function () {
|
||||
log('Call to ' + apiName + (success ? ' success: ' : ' failed: ') + JSON.stringify([].slice.call(arguments)));
|
||||
@@ -194,7 +172,7 @@ exports.defineManualTests = function (contentEl, createActionButton) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Select image from library using a NATIVE_URI destination type
|
||||
* Select image from library
|
||||
* This calls FileEntry.getMetadata, FileEntry.setMetadata, FileEntry.getParent, FileEntry.file, and FileReader.readAsDataURL.
|
||||
*/
|
||||
function readFile () {
|
||||
@@ -237,7 +215,7 @@ exports.defineManualTests = function (contentEl, createActionButton) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy image from library using a NATIVE_URI destination type
|
||||
* Copy image from library
|
||||
* This calls FileEntry.copyTo and FileEntry.moveTo.
|
||||
*/
|
||||
function copyImage () {
|
||||
@@ -271,7 +249,7 @@ exports.defineManualTests = function (contentEl, createActionButton) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Write image to library using a NATIVE_URI destination type
|
||||
* Write image to library
|
||||
* This calls FileEntry.createWriter, FileWriter.write, and FileWriter.truncate.
|
||||
*/
|
||||
function writeImage () {
|
||||
@@ -305,7 +283,7 @@ exports.defineManualTests = function (contentEl, createActionButton) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove image from library using a NATIVE_URI destination type
|
||||
* Remove image from library
|
||||
* This calls FileEntry.remove.
|
||||
*/
|
||||
function removeImage () {
|
||||
@@ -378,7 +356,7 @@ exports.defineManualTests = function (contentEl, createActionButton) {
|
||||
|
||||
var options = '';
|
||||
if (typeof values === 'boolean') {
|
||||
values = { 'true': 1, 'false': 0 };
|
||||
values = { true: 1, false: 0 };
|
||||
}
|
||||
for (var k in values) {
|
||||
var isSelected = '';
|
||||
@@ -409,9 +387,9 @@ exports.defineManualTests = function (contentEl, createActionButton) {
|
||||
createOptionsEl('destinationType', Camera.DestinationType, camDestinationTypeDefault) +
|
||||
createOptionsEl('encodingType', Camera.EncodingType, camEncodingTypeDefault) +
|
||||
createOptionsEl('mediaType', Camera.MediaType, camMediaTypeDefault) +
|
||||
createOptionsEl('quality', { '0': 0, '50': 50, '80': 80, '100': 100 }, camQualityDefault) +
|
||||
createOptionsEl('targetWidth', { '50': 50, '200': 200, '800': 800, '2048': 2048 }) +
|
||||
createOptionsEl('targetHeight', { '50': 50, '200': 200, '800': 800, '2048': 2048 }) +
|
||||
createOptionsEl('quality', { 0: 0, 50: 50, 80: 80, 100: 100 }, camQualityDefault) +
|
||||
createOptionsEl('targetWidth', { 50: 50, 200: 200, 800: 800, 2048: 2048 }) +
|
||||
createOptionsEl('targetHeight', { 50: 50, 200: 200, 800: 800, 2048: 2048 }) +
|
||||
createOptionsEl('allowEdit', true, camAllowEditDefault) +
|
||||
createOptionsEl('correctOrientation', true, camCorrectOrientationDefault) +
|
||||
createOptionsEl('saveToPhotoAlbum', true, camSaveToPhotoAlbumDefault) +
|
||||
@@ -498,10 +476,6 @@ exports.defineManualTests = function (contentEl, createActionButton) {
|
||||
writeImage();
|
||||
}, 'write');
|
||||
|
||||
createActionButton('Upload Image', function () {
|
||||
uploadImage();
|
||||
}, 'upload');
|
||||
|
||||
createActionButton('Draw Using Canvas', function () {
|
||||
displayImageUsingCanvas();
|
||||
}, 'draw_canvas');
|
||||
|
||||
3
types/index.d.ts
vendored
3
types/index.d.ts
vendored
@@ -51,8 +51,6 @@ interface CameraOptions {
|
||||
* Defined in navigator.camera.DestinationType. Default is FILE_URI.
|
||||
* DATA_URL : 0, Return image as base64-encoded string
|
||||
* FILE_URI : 1, Return image file URI
|
||||
* NATIVE_URI : 2 Return image native URI
|
||||
* (e.g., assets-library:// on iOS or content:// on Android)
|
||||
*/
|
||||
destinationType?: number;
|
||||
/**
|
||||
@@ -149,7 +147,6 @@ declare var Camera: {
|
||||
DestinationType: {
|
||||
DATA_URL: number;
|
||||
FILE_URI: number;
|
||||
NATIVE_URI: number
|
||||
}
|
||||
Direction: {
|
||||
BACK: number;
|
||||
|
||||
@@ -26,20 +26,14 @@ 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: {
|
||||
/** Return base64 encoded string. DATA_URL can be very memory intensive and cause app crashes or out of memory errors. Use FILE_URI or NATIVE_URI if possible */
|
||||
/** Return base64 encoded string. DATA_URL can be very memory intensive and cause app crashes or out of memory errors. Use FILE_URI if possible */
|
||||
DATA_URL: 0,
|
||||
/** Return file uri (content://media/external/images/media/2 for Android) */
|
||||
FILE_URI: 1,
|
||||
/** Return native uri (eg. asset-library://... for iOS) */
|
||||
NATIVE_URI: 2
|
||||
FILE_URI: 1
|
||||
},
|
||||
/**
|
||||
* @enum {number}
|
||||
@@ -64,9 +58,6 @@ module.exports = {
|
||||
/**
|
||||
* @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}
|
||||
*/
|
||||
|
||||
@@ -58,7 +58,7 @@ var CameraPopoverHandle = function () {
|
||||
* @param {module:CameraPopoverOptions} popoverOptions
|
||||
*/
|
||||
this.setPosition = function (popoverOptions) {
|
||||
var args = [ popoverOptions ];
|
||||
var args = [popoverOptions];
|
||||
exec(null, null, 'Camera', 'repositionPopover', args);
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user