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 to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@ -18,8 +16,14 @@
*/ */
package org.apache.cordova.camera; package org.apache.cordova.camera;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.CursorLoader;
import android.database.Cursor; import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
import android.os.Build;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.webkit.MimeTypeMap; import android.webkit.MimeTypeMap;
import org.apache.cordova.CordovaInterface; import org.apache.cordova.CordovaInterface;
@ -43,27 +47,19 @@ public class FileHelper {
* @return the full path to the file * @return the full path to the file
*/ */
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public static String getRealPath(String uriString, CordovaInterface cordova) { public static String getRealPath(Uri uri, CordovaInterface cordova) {
String realPath = null; String realPath = null;
if (uriString.startsWith("content://")) { if (Build.VERSION.SDK_INT < 11)
String[] proj = { _DATA }; realPath = FileHelper.getRealPathFromURI_BelowAPI11(cordova.getActivity(), uri);
Cursor cursor = cordova.getActivity().managedQuery(Uri.parse(uriString), proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(_DATA); // SDK >= 11 && SDK < 19
cursor.moveToFirst(); else if (Build.VERSION.SDK_INT < 19)
realPath = cursor.getString(column_index); realPath = FileHelper.getRealPathFromURI_API11to18(cordova.getActivity(), uri);
if (realPath == null) {
LOG.e(LOG_TAG, "Could get real path for URI string %s", uriString); // SDK > 19 (Android 4.4)
} else
} else if (uriString.startsWith("file://")) { realPath = FileHelper.getRealPathFromURI_API19(cordova.getActivity(), uri);
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;
}
return realPath; return realPath;
} }
@ -76,8 +72,74 @@ public class FileHelper {
* @param cordova the current application context * @param cordova the current application context
* @return the full path to the file * @return the full path to the file
*/ */
public static String getRealPath(Uri uri, CordovaInterface cordova) { public static String getRealPath(String uriString, CordovaInterface cordova) {
return FileHelper.getRealPath(uri.toString(), 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,10 +150,12 @@ public class FileHelper {
* @return an input stream into the data at the given URI or null if given an invalid URI string * @return an input stream into the data at the given URI or null if given an invalid URI string
* @throws IOException * @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")) { if (uriString.startsWith("content")) {
Uri uri = Uri.parse(uriString); Uri uri = Uri.parse(uriString);
return cordova.getActivity().getContentResolver().openInputStream(uri); returnValue = cordova.getActivity().getContentResolver().openInputStream(uri);
} else if (uriString.startsWith("file://")) { } else if (uriString.startsWith("file://")) {
int question = uriString.indexOf("?"); int question = uriString.indexOf("?");
if (question > -1) { if (question > -1) {
@ -100,13 +164,22 @@ public class FileHelper {
if (uriString.startsWith("file:///android_asset/")) { if (uriString.startsWith("file:///android_asset/")) {
Uri uri = Uri.parse(uriString); Uri uri = Uri.parse(uriString);
String relativePath = uri.getPath().substring(15); String relativePath = uri.getPath().substring(15);
return cordova.getActivity().getAssets().open(relativePath); returnValue = cordova.getActivity().getAssets().open(relativePath);
} else { } 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 { } else {
return new FileInputStream(getRealPath(uriString, cordova)); returnValue = new FileInputStream(uriString);
} }
return returnValue;
} }
/** /**