mirror of
https://github.com/apache/cordova-plugin-camera.git
synced 2026-02-03 00:06:46 +08:00
Compare commits
25 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 |
@@ -15,6 +15,7 @@ environment:
|
||||
matrix:
|
||||
- nodejs_version: "10"
|
||||
- nodejs_version: "12"
|
||||
- nodejs_version: "14"
|
||||
|
||||
platform:
|
||||
- x86
|
||||
|
||||
24
.asf.yaml
24
.asf.yaml
@@ -15,6 +15,30 @@
|
||||
# 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
|
||||
|
||||
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 }}
|
||||
@@ -17,7 +17,7 @@ env:
|
||||
- ANDROID_BUILD_TOOLS_VERSION=29.0.2
|
||||
|
||||
language: node_js
|
||||
node_js: 12
|
||||
node_js: 14
|
||||
|
||||
# yaml anchor/alias: https://medium.com/@tommyvn/travis-yml-dry-with-anchors-8b6a3ac1b027
|
||||
|
||||
|
||||
@@ -20,6 +20,38 @@
|
||||
-->
|
||||
# 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
|
||||
|
||||
661
package-lock.json
generated
661
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
12
package.json
12
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cordova-plugin-camera",
|
||||
"version": "5.0.1",
|
||||
"version": "6.0.0",
|
||||
"description": "Cordova Camera Plugin",
|
||||
"types": "./types/index.d.ts",
|
||||
"cordova": {
|
||||
@@ -45,7 +45,17 @@
|
||||
"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"
|
||||
}
|
||||
}
|
||||
|
||||
29
plugin.xml
29
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="5.0.1">
|
||||
version="6.0.0">
|
||||
<name>Camera</name>
|
||||
<description>Cordova Camera Plugin</description>
|
||||
<license>Apache 2.0</license>
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
<engines>
|
||||
<engine name="cordova" version=">=9.0.0"/>
|
||||
<engine name="cordova-android" version=">=9.0.0" />
|
||||
<engine name="cordova-android" version=">=10.0.0" />
|
||||
<engine name="cordova-ios" version=">=5.1.0" />
|
||||
</engines>
|
||||
|
||||
@@ -69,6 +69,24 @@
|
||||
</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/FileHelper.java" target-dir="src/org/apache/cordova/camera" />
|
||||
<source-file src="src/android/ExifHelper.java" target-dir="src/org/apache/cordova/camera" />
|
||||
@@ -76,13 +94,12 @@
|
||||
<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 -->
|
||||
|
||||
@@ -39,7 +39,7 @@ 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;
|
||||
@@ -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";
|
||||
|
||||
@@ -196,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -272,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 {
|
||||
@@ -355,11 +357,10 @@ 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;
|
||||
@@ -419,7 +420,6 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
// set crop properties
|
||||
cropIntent.putExtra("crop", "true");
|
||||
|
||||
|
||||
// indicate output X and Y
|
||||
if (targetWidth > 0) {
|
||||
cropIntent.putExtra("outputX", targetWidth);
|
||||
@@ -438,7 +438,6 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
cropIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
|
||||
cropIntent.putExtra("output", croppedUri);
|
||||
|
||||
|
||||
// start the activity - we handle returning in onActivityResult
|
||||
|
||||
if (this.cordova != null) {
|
||||
@@ -449,9 +448,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
LOG.e(LOG_TAG, "Crop operation not supported on this device");
|
||||
try {
|
||||
processResultFromCamera(destType, cameraIntent);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
LOG.e(LOG_TAG, "Unable to write to file");
|
||||
}
|
||||
@@ -474,7 +471,6 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
this.croppedFilePath :
|
||||
this.imageFilePath;
|
||||
|
||||
|
||||
if (this.encodingType == JPEG) {
|
||||
try {
|
||||
//We don't support PNG, so let's not pretend we do
|
||||
@@ -609,7 +605,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
ContentResolver resolver = this.cordova.getActivity().getContentResolver();
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, galleryPathVO.getGalleryFileName());
|
||||
contentValues.put(MediaStore.MediaColumns.MIME_TYPE, getMimetypeForFormat(encodingType));
|
||||
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);
|
||||
@@ -622,7 +618,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
|
||||
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();
|
||||
@@ -638,28 +634,20 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
|
||||
/**
|
||||
* 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);
|
||||
@@ -683,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.
|
||||
@@ -706,24 +711,22 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
|
||||
String uriString = uri.toString();
|
||||
String finalLocation = fileLocation != null ? fileLocation : uriString;
|
||||
String mimeType = FileHelper.getMimeType(uriString, this.cordova);
|
||||
String mimeTypeOfGalleryFile = FileHelper.getMimeType(uriString, this.cordova);
|
||||
|
||||
if (finalLocation == null) {
|
||||
this.failPicture("Error retrieving result.");
|
||||
} else {
|
||||
|
||||
// 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))) {
|
||||
// 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 {
|
||||
} 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 && !this.correctOrientation &&
|
||||
mimeType != null && mimeType.equalsIgnoreCase(getMimetypeForFormat(encodingType)))
|
||||
getMimetypeForEncodingType().equalsIgnoreCase(mimeTypeOfGalleryFile))
|
||||
{
|
||||
this.callbackContext.success(finalLocation);
|
||||
} else {
|
||||
@@ -749,17 +752,17 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
// Did we modify the image?
|
||||
if ( (this.targetHeight > 0 && this.targetWidth > 0) ||
|
||||
(this.correctOrientation && this.orientationCorrected) ||
|
||||
!mimeType.equalsIgnoreCase(getMimetypeForFormat(encodingType)))
|
||||
!mimeTypeOfGalleryFile.equalsIgnoreCase(getMimetypeForEncodingType()))
|
||||
{
|
||||
try {
|
||||
String modifiedPath = this.outputModifiedBitmap(bitmap, uri);
|
||||
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.");
|
||||
this.failPicture("Error retrieving image: "+e.getLocalizedMessage());
|
||||
}
|
||||
} else {
|
||||
this.callbackContext.success(finalLocation);
|
||||
@@ -776,6 +779,18 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the camera view exits.
|
||||
*
|
||||
@@ -829,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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -973,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);
|
||||
@@ -997,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();
|
||||
@@ -1051,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]);
|
||||
@@ -1091,8 +1101,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
}
|
||||
}
|
||||
return scaledBitmap;
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
// delete the temporary copy
|
||||
if (localFile != null) {
|
||||
localFile.delete();
|
||||
@@ -1268,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;
|
||||
}
|
||||
@@ -1304,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));
|
||||
@@ -1318,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;
|
||||
}
|
||||
}
|
||||
@@ -1350,6 +1358,10 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
state.putString(IMAGE_URI_KEY, this.imageFilePath);
|
||||
}
|
||||
|
||||
if (this.imageFilePath != null) {
|
||||
state.putString(IMAGE_FILE_PATH_KEY, this.imageFilePath);
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -1375,6 +1387,10 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,7 +43,7 @@ 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
|
||||
*/
|
||||
@@ -57,7 +56,7 @@ public class FileHelper {
|
||||
* 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
|
||||
*/
|
||||
@@ -132,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
|
||||
@@ -142,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.
|
||||
*
|
||||
@@ -177,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);
|
||||
@@ -206,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);
|
||||
}
|
||||
@@ -225,7 +213,7 @@ public class FileHelper {
|
||||
}
|
||||
return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the mime type of the data specified by the given URI string.
|
||||
*
|
||||
@@ -233,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://")) {
|
||||
@@ -316,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 {}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cordova-plugin-camera-tests",
|
||||
"version": "5.0.1",
|
||||
"version": "6.0.0",
|
||||
"description": "",
|
||||
"cordova": {
|
||||
"id": "cordova-plugin-camera-tests",
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:rim="http://www.blackberry.com/ns/widgets"
|
||||
id="cordova-plugin-camera-tests"
|
||||
version="5.0.1">
|
||||
version="6.0.0">
|
||||
<name>Cordova Camera Plugin Tests</name>
|
||||
<license>Apache 2.0</license>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user