mirror of
https://github.com/apache/cordova-plugin-camera.git
synced 2025-01-31 12:42:50 +08:00
CB-11625: Files Provider does not work with Android 4.4.4 or lower, and I have no idea why. Working around with CordovaUri
This commit is contained in:
parent
61064ae3ed
commit
84f96c1067
@ -103,7 +103,7 @@ 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 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 targetWidth; // desired width of the image
|
||||||
private int targetHeight; // desired height of the image
|
private int targetHeight; // desired height of the image
|
||||||
private Uri imageUri; // Uri of captured image
|
private CordovaUri imageUri; // Uri of captured image
|
||||||
private int encodingType; // Type of encoding to use
|
private int encodingType; // Type of encoding to use
|
||||||
private int mediaType; // What type of media to retrieve
|
private int mediaType; // What type of media to retrieve
|
||||||
private int destType; // Source type (needs to be saved for the permission handling)
|
private int destType; // Source type (needs to be saved for the permission handling)
|
||||||
@ -292,10 +292,10 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
|||||||
|
|
||||||
// Specify file so that large image is captured and returned
|
// Specify file so that large image is captured and returned
|
||||||
File photo = createCaptureFile(encodingType);
|
File photo = createCaptureFile(encodingType);
|
||||||
this.imageUri = FileProvider.getUriForFile(cordova.getActivity(),
|
this.imageUri = new CordovaUri(FileProvider.getUriForFile(cordova.getActivity(),
|
||||||
applicationId + ".provider",
|
applicationId + ".provider",
|
||||||
photo);
|
photo));
|
||||||
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, this.imageUri);
|
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, imageUri.getCorrectUri());
|
||||||
//We can write to this URI, this will hopefully allow us to write files to get to the next step
|
//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);
|
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
|
||||||
|
|
||||||
@ -471,7 +471,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
|||||||
|
|
||||||
String sourcePath = (this.allowEdit && this.croppedUri != null) ?
|
String sourcePath = (this.allowEdit && this.croppedUri != null) ?
|
||||||
FileHelper.stripFileProtocol(this.croppedUri.toString()) :
|
FileHelper.stripFileProtocol(this.croppedUri.toString()) :
|
||||||
getFileNameFromUri(this.imageUri);
|
this.imageUri.getFilePath();
|
||||||
|
|
||||||
|
|
||||||
if (this.encodingType == JPEG) {
|
if (this.encodingType == JPEG) {
|
||||||
@ -498,7 +498,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
|||||||
if (this.allowEdit && this.croppedUri != null) {
|
if (this.allowEdit && this.croppedUri != null) {
|
||||||
writeUncompressedImage(croppedUri, galleryUri);
|
writeUncompressedImage(croppedUri, galleryUri);
|
||||||
} else {
|
} else {
|
||||||
Uri imageUri = Uri.fromFile(new File(getFileNameFromUri(this.imageUri)));
|
Uri imageUri = this.imageUri.getFileUri();
|
||||||
writeUncompressedImage(imageUri, galleryUri);
|
writeUncompressedImage(imageUri, galleryUri);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -546,7 +546,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
|||||||
Uri croppedUri = Uri.fromFile(new File(getFileNameFromUri(this.croppedUri)));
|
Uri croppedUri = Uri.fromFile(new File(getFileNameFromUri(this.croppedUri)));
|
||||||
writeUncompressedImage(croppedUri, uri);
|
writeUncompressedImage(croppedUri, uri);
|
||||||
} else {
|
} else {
|
||||||
Uri imageUri = Uri.fromFile(new File(getFileNameFromUri(this.imageUri)));
|
Uri imageUri = this.imageUri.getFileUri();
|
||||||
writeUncompressedImage(imageUri, uri);
|
writeUncompressedImage(imageUri, uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -589,7 +589,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
|||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.cleanup(FILE_URI, this.imageUri, galleryUri, bitmap);
|
this.cleanup(FILE_URI, this.imageUri.getFileUri(), galleryUri, bitmap);
|
||||||
bitmap = null;
|
bitmap = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1340,7 +1340,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.imageUri != null) {
|
if (this.imageUri != null) {
|
||||||
state.putString("imageUri", this.imageUri.toString());
|
state.putString("imageUri", this.imageUri.getFileUri().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
@ -1364,7 +1364,8 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (state.containsKey("imageUri")) {
|
if (state.containsKey("imageUri")) {
|
||||||
this.imageUri = Uri.parse(state.getString("imageUri"));
|
//I have no idea what type of URI is being passed in
|
||||||
|
this.imageUri = new CordovaUri(Uri.parse(state.getString("imageUri")));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.callbackContext = callbackContext;
|
this.callbackContext = callbackContext;
|
||||||
@ -1382,7 +1383,6 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
|||||||
* we own the context in this case.
|
* we own the context in this case.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
private String getFileNameFromUri(Uri uri) {
|
private String getFileNameFromUri(Uri uri) {
|
||||||
String fullUri = uri.toString();
|
String fullUri = uri.toString();
|
||||||
String partial_path = fullUri.split("external_files")[1];
|
String partial_path = fullUri.split("external_files")[1];
|
||||||
@ -1391,4 +1391,6 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
|||||||
return path;
|
return path;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
85
src/android/CordovaUri.java
Normal file
85
src/android/CordovaUri.java
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user