我想为Android Lollipop创建一个图片选择器。我使用Intent.ACTION_GET_CONTENT
来选择我的图片但是我无法从URI中获取所选图像的路径,对话框选择器返回了该路径。
我尝试了这些主题的代码:
retrieve absolute path when select image from gallery kitkat android
https://chintankhetiya.wordpress.com/2013/12/14/picture-selection-from-camera-gallery/
但是所有这些都返回null。任何人都可以帮助我吗?
答案 0 :(得分:13)
尝试
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.CursorLoader;
import android.database.Cursor;
import android.net.Uri;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
public class RealPathUtil {
@SuppressLint("NewApi")
public static String getRealPathFromURI_API19(Context context, Uri uri) {
Log.variable("uri", uri.getPath());
String filePath = "";
if (DocumentsContract.isDocumentUri(context, uri)) {
String wholeID = DocumentsContract.getDocumentId(uri);
Log.variable("wholeID", wholeID);
// Split at colon, use second item in the array
String[] splits = wholeID.split(":");
if (splits.length == 2) {
String id = splits[1];
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();
}
} else {
filePath = uri.getPath();
}
return filePath;
}
@SuppressLint("NewApi")
public static String getRealPathFromURI_API11to18(Context context, Uri contentUri) {
String[] proj = {MediaStore.Images.Media.DATA};
String result = null;
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);
}
return result;
}
public static String getRealPathFromURI_BelowAPI11(Context context, Uri contentUri) {
String[] proj = {MediaStore.Images.Media.DATA};
Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
int column_index
= cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
并使用:
private String uriToFilename(Uri uri) {
String path = null;
if (Build.VERSION.SDK_INT < 11) {
path = RealPathUtil.getRealPathFromURI_BelowAPI11(mContext, uri);
} else if (Build.VERSION.SDK_INT < 19) {
path = RealPathUtil.getRealPathFromURI_API11to18(mContext, uri);
} else {
path = RealPathUtil.getRealPathFromURI_API19(mContext, uri);
}
return path;
}
适用于必须的情况(not works下载应用
)答案 1 :(得分:2)
尝试这个小功能:
public static String getRealPathFromUri(Uri uri) {
String result = "";
String documentID;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
String[] pathParts = uri.getPath().split("/");
documentID = pathParts[pathParts.length - 1];
} else {
String pathSegments[] = uri.getLastPathSegment().split(":");
documentID = pathSegments[pathSegments.length - 1];
}
String mediaPath = MediaStore.Images.Media.DATA;
Cursor imageCursor = getContentResolver().query(uri, new String[]{mediaPath}, MediaStore.Images.Media._ID + "=" + documentID, null, null);
if (imageCursor.moveToFirst()) {
result = imageCursor.getString(imageCursor.getColumnIndex(mediaPath));
}
return result;
}
答案 2 :(得分:1)
这项工作对我而言。
我创建了一个Util类RealPathUtil
(与@Artem答案中的类有一点差别):
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.CursorLoader;
import android.database.Cursor;
import android.net.Uri;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
public class RealPathUtil {
@SuppressLint("NewApi")
public static String getRealPathFromURI_API19(Context context, Uri uri) {
String filePath = "";
String wholeID = DocumentsContract.getDocumentId(uri);
// Split at colon, use second item in the array
String id = wholeID.split(":")[1];
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);
assert cursor != null;
int columnIndex = cursor.getColumnIndex(column[0]);
if (cursor.moveToFirst()) {
filePath = cursor.getString(columnIndex);
}
cursor.close();
return filePath;
}
@SuppressLint("NewApi")
public static String getRealPathFromURI_API11to18(Context context, Uri contentUri) {
String[] proj = { MediaStore.Images.Media.DATA };
String result = null;
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);
}
return result;
}
public static String getRealPathFromURI_BelowAPI11(Context context, Uri contentUri){
Cursor cursor = null;
try {
String[] proj = { MediaStore.Images.Media.DATA };
cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
assert cursor != null;
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
}
然后,在我的应用代码中,我使用了:
private String getPathFromUri(Uri uri) {
if (Build.VERSION.SDK_INT < 11)
return RealPathUtil.getRealPathFromURI_BelowAPI11(getContext(), uri);
else if (Build.VERSION.SDK_INT < 19)
return RealPathUtil.getRealPathFromURI_API11to18(getContext(), uri);
else
return RealPathUtil.getRealPathFromURI_API19(getContext(), uri);
}
答案 3 :(得分:0)
确保您在Android Manifest中获得许可!
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />