[CB-2213] Added NATIVE_URI support.

This is mostly the same as FILE_URI on Android.

Also replaced calls to `stripFileProtocol` with the more general-purpose `getRealPathFromURI`.  This helps support some operations on content URIs.
This commit is contained in:
Max Woghiren 2013-02-06 15:48:23 -05:00 committed by Andrew Grieve
parent 8ab7278db2
commit 1246a81d39
2 changed files with 46 additions and 27 deletions

View File

@ -58,6 +58,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
private static final int DATA_URL = 0; // Return base64 encoded string 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 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 PHOTOLIBRARY = 0; // Choose image from picture library (same as SAVEDPHOTOALBUM for Android)
private static final int CAMERA = 1; // Take picture from camera private static final int CAMERA = 1; // Take picture from camera
@ -310,7 +311,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
} }
// If sending filename back // If sending filename back
else if (destType == FILE_URI) { else if (destType == FILE_URI || destType == NATIVE_URI) {
if (!this.saveToPhotoAlbum) { if (!this.saveToPhotoAlbum) {
uri = Uri.fromFile(new File(DirectoryManager.getTempDirectoryPath(this.cordova.getActivity()), System.currentTimeMillis() + ".jpg")); uri = Uri.fromFile(new File(DirectoryManager.getTempDirectoryPath(this.cordova.getActivity()), System.currentTimeMillis() + ".jpg"));
} else { } else {
@ -434,7 +435,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
} }
// If sending filename back // If sending filename back
else if (destType == FILE_URI) { else if (destType == FILE_URI || destType == NATIVE_URI) {
// Do we need to scale the returned file // Do we need to scale the returned file
if (this.targetHeight > 0 && this.targetWidth > 0) { if (this.targetHeight > 0 && this.targetWidth > 0) {
try { try {

View File

@ -43,7 +43,6 @@ import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
import android.os.Environment; import android.os.Environment;
import android.provider.MediaStore; import android.provider.MediaStore;
import android.util.Log;
import android.webkit.MimeTypeMap; import android.webkit.MimeTypeMap;
//import android.app.Activity; //import android.app.Activity;
@ -89,7 +88,7 @@ public class FileUtils extends CordovaPlugin {
* Executes the request and returns whether the action was valid. * Executes the request and returns whether the action was valid.
* *
* @param action The action to execute. * @param action The action to execute.
* @param args JSONArry of arguments for the plugin. * @param args JSONArray of arguments for the plugin.
* @param callbackContext The callback context used when calling back into JavaScript. * @param callbackContext The callback context used when calling back into JavaScript.
* @return True if the action was valid, false otherwise. * @return True if the action was valid, false otherwise.
*/ */
@ -238,7 +237,7 @@ public class FileUtils extends CordovaPlugin {
* @param filePath the path to check * @param filePath the path to check
*/ */
private void notifyDelete(String filePath) { private void notifyDelete(String filePath) {
String newFilePath = stripFileProtocol(filePath); String newFilePath = getRealPathFromURI(Uri.parse(filePath), cordova);
try { try {
this.cordova.getActivity().getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, this.cordova.getActivity().getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
MediaStore.Images.Media.DATA + " = ?", MediaStore.Images.Media.DATA + " = ?",
@ -342,18 +341,18 @@ public class FileUtils extends CordovaPlugin {
* @throws InvalidModificationException * @throws InvalidModificationException
* @throws EncodingException * @throws EncodingException
* @throws JSONException * @throws JSONException
* @throws FileExistsException * @throws FileExistsException
*/ */
private JSONObject transferTo(String fileName, String newParent, String newName, boolean move) throws JSONException, NoModificationAllowedException, IOException, InvalidModificationException, EncodingException, FileExistsException { private JSONObject transferTo(String fileName, String newParent, String newName, boolean move) throws JSONException, NoModificationAllowedException, IOException, InvalidModificationException, EncodingException, FileExistsException {
fileName = stripFileProtocol(fileName); String newFileName = getRealPathFromURI(Uri.parse(fileName), cordova);
newParent = stripFileProtocol(newParent); newParent = getRealPathFromURI(Uri.parse(newParent), cordova);
// Check for invalid file name // Check for invalid file name
if (newName != null && newName.contains(":")) { if (newName != null && newName.contains(":")) {
throw new EncodingException("Bad file name"); throw new EncodingException("Bad file name");
} }
File source = new File(fileName); File source = new File(newFileName);
if (!source.exists()) { if (!source.exists()) {
// The file/directory we are copying doesn't exist so we should fail. // The file/directory we are copying doesn't exist so we should fail.
@ -385,7 +384,14 @@ public class FileUtils extends CordovaPlugin {
} }
} else { } else {
if (move) { if (move) {
return moveFile(source, destination); JSONObject newFileEntry = moveFile(source, destination);
// If we've moved a file given its content URI, we need to clean up.
if (fileName.startsWith("content://")) {
notifyDelete(fileName);
}
return newFileEntry;
} else { } else {
return copyFile(source, destination); return copyFile(source, destination);
} }
@ -483,7 +489,7 @@ public class FileUtils extends CordovaPlugin {
if (!destinationDir.exists()) { if (!destinationDir.exists()) {
if (!destinationDir.mkdir()) { if (!destinationDir.mkdir()) {
// If we can't create the directory then fail // If we can't create the directory then fail
throw new NoModificationAllowedException("Couldn't create the destination direcotry"); throw new NoModificationAllowedException("Couldn't create the destination directory");
} }
} }
@ -561,8 +567,8 @@ public class FileUtils extends CordovaPlugin {
* @throws JSONException * @throws JSONException
* @throws IOException * @throws IOException
* @throws InvalidModificationException * @throws InvalidModificationException
* @throws NoModificationAllowedException * @throws NoModificationAllowedException
* @throws FileExistsException * @throws FileExistsException
*/ */
private JSONObject moveDirectory(File srcDir, File destinationDir) throws IOException, JSONException, InvalidModificationException, NoModificationAllowedException, FileExistsException { private JSONObject moveDirectory(File srcDir, File destinationDir) throws IOException, JSONException, InvalidModificationException, NoModificationAllowedException, FileExistsException {
// Renaming a file to an existing directory should fail // Renaming a file to an existing directory should fail
@ -742,7 +748,7 @@ public class FileUtils extends CordovaPlugin {
if (fileName.startsWith("/")) { if (fileName.startsWith("/")) {
fp = new File(fileName); fp = new File(fileName);
} else { } else {
dirPath = stripFileProtocol(dirPath); dirPath = getRealPathFromURI(Uri.parse(dirPath), cordova);
fp = new File(dirPath + File.separator + fileName); fp = new File(dirPath + File.separator + fileName);
} }
return fp; return fp;
@ -757,7 +763,7 @@ public class FileUtils extends CordovaPlugin {
* @throws JSONException * @throws JSONException
*/ */
private JSONObject getParent(String filePath) throws JSONException { private JSONObject getParent(String filePath) throws JSONException {
filePath = stripFileProtocol(filePath); filePath = getRealPathFromURI(Uri.parse(filePath), cordova);
if (atRootDirectory(filePath)) { if (atRootDirectory(filePath)) {
return getEntry(filePath); return getEntry(filePath);
@ -773,7 +779,7 @@ public class FileUtils extends CordovaPlugin {
* @return true if we are at the root, false otherwise. * @return true if we are at the root, false otherwise.
*/ */
private boolean atRootDirectory(String filePath) { private boolean atRootDirectory(String filePath) {
filePath = stripFileProtocol(filePath); filePath = getRealPathFromURI(Uri.parse(filePath), cordova);
if (filePath.equals(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/" + cordova.getActivity().getPackageName() + "/cache") || if (filePath.equals(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/" + cordova.getActivity().getPackageName() + "/cache") ||
filePath.equals(Environment.getExternalStorageDirectory().getAbsolutePath()) || filePath.equals(Environment.getExternalStorageDirectory().getAbsolutePath()) ||
@ -803,7 +809,7 @@ public class FileUtils extends CordovaPlugin {
* @return * @return
*/ */
private File createFileObject(String filePath) { private File createFileObject(String filePath) {
filePath = stripFileProtocol(filePath); filePath = getRealPathFromURI(Uri.parse(filePath), cordova);
File file = new File(filePath); File file = new File(filePath);
return file; return file;
@ -845,7 +851,7 @@ public class FileUtils extends CordovaPlugin {
metadata.put("size", file.length()); metadata.put("size", file.length());
metadata.put("type", getMimeType(filePath)); metadata.put("type", getMimeType(filePath));
metadata.put("name", file.getName()); metadata.put("name", file.getName());
metadata.put("fullPath", file.getAbsolutePath()); metadata.put("fullPath", filePath);
metadata.put("lastModifiedDate", file.lastModified()); metadata.put("lastModifiedDate", file.lastModified());
return metadata; return metadata;
@ -1028,7 +1034,7 @@ public class FileUtils extends CordovaPlugin {
if (filename != null) { if (filename != null) {
// Stupid bug in getFileExtensionFromUrl when the file name has a space // Stupid bug in getFileExtensionFromUrl when the file name has a space
// So we need to replace the space with a url encoded %20 // So we need to replace the space with a url encoded %20
// CB-2185: Stupid bug not putting JPG extension in the mime-type map // CB-2185: Stupid bug not putting JPG extension in the mime-type map
String url = filename.replace(" ", "%20").toLowerCase(); String url = filename.replace(" ", "%20").toLowerCase();
MimeTypeMap map = MimeTypeMap.getSingleton(); MimeTypeMap map = MimeTypeMap.getSingleton();
@ -1050,10 +1056,15 @@ public class FileUtils extends CordovaPlugin {
* @param data The contents of the file. * @param data The contents of the file.
* @param offset The position to begin writing the file. * @param offset The position to begin writing the file.
* @throws FileNotFoundException, IOException * @throws FileNotFoundException, IOException
* @throws NoModificationAllowedException
*/ */
/**/ /**/
public long write(String filename, String data, int offset) throws FileNotFoundException, IOException { public long write(String filename, String data, int offset) throws FileNotFoundException, IOException, NoModificationAllowedException {
filename = stripFileProtocol(filename); if (filename.startsWith("content://")) {
throw new NoModificationAllowedException("Couldn't write to file given its content URI");
}
filename = getRealPathFromURI(Uri.parse(filename), cordova);
boolean append = false; boolean append = false;
if (offset > 0) { if (offset > 0) {
@ -1079,9 +1090,14 @@ public class FileUtils extends CordovaPlugin {
* @param filename * @param filename
* @param size * @param size
* @throws FileNotFoundException, IOException * @throws FileNotFoundException, IOException
* @throws NoModificationAllowedException
*/ */
private long truncateFile(String filename, long size) throws FileNotFoundException, IOException { private long truncateFile(String filename, long size) throws FileNotFoundException, IOException, NoModificationAllowedException {
filename = stripFileProtocol(filename); if (filename.startsWith("content://")) {
throw new NoModificationAllowedException("Couldn't truncate file given its content URI");
}
filename = getRealPathFromURI(Uri.parse(filename), cordova);
RandomAccessFile raf = new RandomAccessFile(filename, "rw"); RandomAccessFile raf = new RandomAccessFile(filename, "rw");
try { try {
@ -1090,7 +1106,7 @@ public class FileUtils extends CordovaPlugin {
channel.truncate(size); channel.truncate(size);
return size; return size;
} }
return raf.length(); return raf.length();
} finally { } finally {
raf.close(); raf.close();
@ -1110,7 +1126,7 @@ public class FileUtils extends CordovaPlugin {
return cordova.getActivity().getContentResolver().openInputStream(uri); return cordova.getActivity().getContentResolver().openInputStream(uri);
} }
else { else {
path = stripFileProtocol(path); path = getRealPathFromURI(Uri.parse(path), cordova);
return new FileInputStream(path); return new FileInputStream(path);
} }
} }
@ -1125,8 +1141,10 @@ public class FileUtils extends CordovaPlugin {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
protected static String getRealPathFromURI(Uri contentUri, CordovaInterface cordova) { protected static String getRealPathFromURI(Uri contentUri, CordovaInterface cordova) {
final String scheme = contentUri.getScheme(); final String scheme = contentUri.getScheme();
if (scheme.compareTo("content") == 0) { if (scheme == null) {
return contentUri.toString();
} else if (scheme.compareTo("content") == 0) {
String[] proj = { _DATA }; String[] proj = { _DATA };
Cursor cursor = cordova.getActivity().managedQuery(contentUri, proj, null, null, null); Cursor cursor = cordova.getActivity().managedQuery(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(_DATA); int column_index = cursor.getColumnIndexOrThrow(_DATA);