CB-8235 android: Fix crash when selecting images from DropBox with spaces in path (close #65)

This commit is contained in:
Serge Huijben 2015-03-04 20:33:21 -05:00 committed by Andrew Grieve
parent f39a08ba29
commit 929733b891

View File

@ -6,9 +6,7 @@
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
@ -18,8 +16,14 @@
*/
package org.apache.cordova.camera;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.CursorLoader;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.webkit.MimeTypeMap;
import org.apache.cordova.CordovaInterface;
@ -43,27 +47,19 @@ public class FileHelper {
* @return the full path to the file
*/
@SuppressWarnings("deprecation")
public static String getRealPath(String uriString, CordovaInterface cordova) {
public static String getRealPath(Uri uri, CordovaInterface cordova) {
String realPath = null;
if (uriString.startsWith("content://")) {
String[] proj = { _DATA };
Cursor cursor = cordova.getActivity().managedQuery(Uri.parse(uriString), proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(_DATA);
cursor.moveToFirst();
realPath = cursor.getString(column_index);
if (realPath == null) {
LOG.e(LOG_TAG, "Could get real path for URI string %s", uriString);
}
} else if (uriString.startsWith("file://")) {
realPath = uriString.substring(7);
if (realPath.startsWith("/android_asset/")) {
LOG.e(LOG_TAG, "Cannot get real path for URI string %s because it is a file:///android_asset/ URI.", uriString);
realPath = null;
}
} else {
realPath = uriString;
}
if (Build.VERSION.SDK_INT < 11)
realPath = FileHelper.getRealPathFromURI_BelowAPI11(cordova.getActivity(), uri);
// SDK >= 11 && SDK < 19
else if (Build.VERSION.SDK_INT < 19)
realPath = FileHelper.getRealPathFromURI_API11to18(cordova.getActivity(), uri);
// SDK > 19 (Android 4.4)
else
realPath = FileHelper.getRealPathFromURI_API19(cordova.getActivity(), uri);
return realPath;
}
@ -76,8 +72,74 @@ public class FileHelper {
* @param cordova the current application context
* @return the full path to the file
*/
public static String getRealPath(Uri uri, CordovaInterface cordova) {
return FileHelper.getRealPath(uri.toString(), cordova);
public static String getRealPath(String uriString, CordovaInterface cordova) {
return FileHelper.getRealPath(Uri.parse(uriString), cordova);
}
@SuppressLint("NewApi")
public static String getRealPathFromURI_API19(Context context, Uri uri) {
String filePath = "";
try {
String wholeID = DocumentsContract.getDocumentId(uri);
// Split at colon, use second item in the array
String id = wholeID.indexOf(":") > -1 ? wholeID.split(":")[1] : wholeID.indexOf(";") > -1 ? wholeID
.split(";")[1] : wholeID;
String[] column = { MediaStore.Images.Media.DATA };
// where id is equal to
String sel = MediaStore.Images.Media._ID + "=?";
Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, column,
sel, new String[] { id }, null);
int columnIndex = cursor.getColumnIndex(column[0]);
if (cursor.moveToFirst()) {
filePath = cursor.getString(columnIndex);
}
cursor.close();
} catch (Exception e) {
filePath = "";
}
return filePath;
}
@SuppressLint("NewApi")
public static String getRealPathFromURI_API11to18(Context context, Uri contentUri) {
String[] proj = { MediaStore.Images.Media.DATA };
String result = null;
try {
CursorLoader cursorLoader = new CursorLoader(context, contentUri, proj, null, null, null);
Cursor cursor = cursorLoader.loadInBackground();
if (cursor != null) {
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
result = cursor.getString(column_index);
}
} catch (Exception e) {
result = null;
}
return result;
}
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;
}
/**
@ -88,25 +150,36 @@ public class FileHelper {
* @return an input stream into the data at the given URI or null if given an invalid URI string
* @throws IOException
*/
public static InputStream getInputStreamFromUriString(String uriString, CordovaInterface cordova) throws IOException {
public static InputStream getInputStreamFromUriString(String uriString, CordovaInterface cordova)
throws IOException {
InputStream returnValue = null;
if (uriString.startsWith("content")) {
Uri uri = Uri.parse(uriString);
return cordova.getActivity().getContentResolver().openInputStream(uri);
returnValue = cordova.getActivity().getContentResolver().openInputStream(uri);
} else if (uriString.startsWith("file://")) {
int question = uriString.indexOf("?");
if (question > -1) {
uriString = uriString.substring(0,question);
uriString = uriString.substring(0, question);
}
if (uriString.startsWith("file:///android_asset/")) {
Uri uri = Uri.parse(uriString);
String relativePath = uri.getPath().substring(15);
return cordova.getActivity().getAssets().open(relativePath);
returnValue = cordova.getActivity().getAssets().open(relativePath);
} else {
return new FileInputStream(getRealPath(uriString, cordova));
// might still be content so try that first
try {
returnValue = cordova.getActivity().getContentResolver().openInputStream(Uri.parse(uriString));
} catch (Exception e) {
returnValue = null;
}
if (returnValue == null) {
returnValue = new FileInputStream(getRealPath(uriString, cordova));
}
}
} else {
return new FileInputStream(getRealPath(uriString, cordova));
returnValue = new FileInputStream(uriString);
}
return returnValue;
}
/**