android 通过 Uri.getPath() 获取真实路径
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2789276/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
android get real path by Uri.getPath()
提问by davs
I'm trying to get image from gallery.
我正在尝试从图库中获取图像。
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select picture"), resultCode );
After I returned from this activity I have a data, which contains Uri. It looks like:
从这个活动返回后,我有一个包含 Uri 的数据。看起来像:
content://media/external/images/1
How can I convert this path to real one (just like '/sdcard/image.png
') ?
如何将此路径转换为真实路径(就像' /sdcard/image.png
')?
Thanks
谢谢
采纳答案by molnarm
Is it really necessary for you to get a physical path?
For example, ImageView.setImageURI()
and ContentResolver.openInputStream()
allow you to access the contents of a file without knowing its real path.
你真的有必要获得物理路径吗?
例如,ImageView.setImageURI()
并且ContentResolver.openInputStream()
允许你访问一个文件的内容,不知道它的真实路径。
回答by cesards
This is what I do:
这就是我所做的:
Uri selectedImageURI = data.getData();
imageFile = new File(getRealPathFromURI(selectedImageURI));
and:
和:
private String getRealPathFromURI(Uri contentURI) {
String result;
Cursor cursor = getContentResolver().query(contentURI, null, null, null, null);
if (cursor == null) { // Source is Dropbox or other similar local file path
result = contentURI.getPath();
} else {
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
result = cursor.getString(idx);
cursor.close();
}
return result;
}
NOTE: managedQuery()
method is deprecated, so I am not using it.
注意:managedQuery()
方法已被弃用,所以我没有使用它。
Last edit: Improvement. We should close cursor!!
最后编辑:改进。我们应该关闭光标!!
回答by luizfelipetx
@Rene Juuse - above in comments... Thanks for this link !
@Rene Juuse - 以上评论...感谢此链接!
. the code to get the real path is a bit different from one SDK to another so below we have three methods that deals with different SDKs.
. 获取真实路径的代码从一个 SDK 到另一个有点不同,所以下面我们有三种方法来处理不同的 SDK。
getRealPathFromURI_API19(): returns real path for API 19 (or above but not tested) getRealPathFromURI_API11to18(): returns real path for API 11 to API 18 getRealPathFromURI_below11(): returns real path for API below 11
getRealPathFromURI_API19():返回 API 19(或以上但未测试)的真实路径 getRealPathFromURI_API11to18():返回 API 11 到 API 18 的真实路径 getRealPathFromURI_below11():返回 API 低于 11 的真实路径
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);
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){
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);
}
font: http://hmkcode.com/android-display-selected-image-and-its-real-path/
字体:http: //hmkcode.com/android-display-selected-image-and-its-real-path/
UPDATE 2016 March
2016 年 3 月更新
To fix all problems with path of images i try create a custom gallery as facebook and other apps. This is because you can use just local files ( real files, not virtual or temporary) , i solve all problems with this library.
为了解决图像路径的所有问题,我尝试创建一个自定义图库作为 facebook 和其他应用程序。这是因为您只能使用本地文件(真实文件,而不是虚拟文件或临时文件),我用这个库解决了所有问题。
https://github.com/nohana/Laevatein(this library is to take photo from camera or choose from galery , if you choose from gallery he have a drawer with albums and just show local files)
https://github.com/nohana/Laevatein(这个库是从相机拍照或从galery中选择,如果你从galery中选择,他有一个带相册的抽屉,只显示本地文件)
回答by Jaiprakash Soni
NoteThis is an improvement in @user3516549 answerand I have check it on Moto G3 with Android 6.0.1
I have this issue so I have tried answer of @user3516549 but in some cases it was not working properly.
I have found that in Android 6.0(or above) when we start gallery image pick intent then a screen will open that shows recent images when user select image from this list we will get uri as
注意这是@user3516549 答案的改进,我已经在使用 Android 6.0.1 的 Moto G3 上检查过
我有这个问题,所以我尝试了 @user3516549 的答案,但在某些情况下它无法正常工作。我发现在 Android 6.0(或更高版本)中,当我们启动图库图像选择意图时,当用户从此列表中选择图像时,将打开一个显示最近图像的屏幕,我们将获得 uri
content://com.android.providers.media.documents/document/image%3A52530
while if user select gallery from sliding drawer instead of recent then we will get uri as
而如果用户从滑动抽屉而不是最近选择画廊,那么我们将获得 uri
content://media/external/images/media/52530
So I have handle it in getRealPathFromURI_API19()
所以我已经处理了 getRealPathFromURI_API19()
public static String getRealPathFromURI_API19(Context context, Uri uri) {
String filePath = "";
if (uri.getHost().contains("com.android.providers.media")) {
// Image pick from recent
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);
int columnIndex = cursor.getColumnIndex(column[0]);
if (cursor.moveToFirst()) {
filePath = cursor.getString(columnIndex);
}
cursor.close();
return filePath;
} else {
// image pick from gallery
return getRealPathFromURI_BelowAPI11(context,uri)
}
}
EDIT :if you are trying to get image path of file in external sdcard in higher version then check my question
编辑:如果您尝试在更高版本的外部 sdcard 中获取文件的图像路径,请检查我的问题
回答by Javatar
EDIT:Use this Solution here: https://stackoverflow.com/a/20559175/2033223Works perfect!
编辑:在此处使用此解决方案:https: //stackoverflow.com/a/20559175/2033223完美运行!
First of, thank for your solution @luizfelipetx
首先,感谢您的解决方案@luizfelipetx
I changed your solution a little bit. This works for me:
我稍微改变了你的解决方案。这对我有用:
public static String getRealPathFromDocumentUri(Context context, Uri uri){
String filePath = "";
Pattern p = Pattern.compile("(\d+)$");
Matcher m = p.matcher(uri.toString());
if (!m.find()) {
Log.e(ImageConverter.class.getSimpleName(), "ID for requested image not found: " + uri.toString());
return filePath;
}
String imgId = m.group();
String[] column = { MediaStore.Images.Media.DATA };
String sel = MediaStore.Images.Media._ID + "=?";
Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
column, sel, new String[]{ imgId }, null);
int columnIndex = cursor.getColumnIndex(column[0]);
if (cursor.moveToFirst()) {
filePath = cursor.getString(columnIndex);
}
cursor.close();
return filePath;
}
Note: So we got documents and image, depending, if the image comes from 'recents', 'gallery' or what ever. So I extract the image ID first before looking it up.
注意:所以我们得到了文档和图像,这取决于图像是否来自“最近”、“画廊”或其他任何内容。所以我在查找之前先提取图像ID。
回答by Tanmay Sahoo
Hii here is my complete code for taking image from camera or galeery
嗨,这是我从相机或galeery拍摄图像的完整代码
//My variable declaration
//我的变量声明
protected static final int CAMERA_REQUEST = 0;
protected static final int GALLERY_REQUEST = 1;
Bitmap bitmap;
Uri uri;
Intent picIntent = null;
//Onclick
//点击
if (v.getId()==R.id.image_id){
startDilog();
}
//method body
//方法体
private void startDilog() {
AlertDialog.Builder myAlertDilog = new AlertDialog.Builder(yourActivity.this);
myAlertDilog.setTitle("Upload picture option..");
myAlertDilog.setMessage("Where to upload picture????");
myAlertDilog.setPositiveButton("Gallery", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
picIntent = new Intent(Intent.ACTION_GET_CONTENT,null);
picIntent.setType("image/*");
picIntent.putExtra("return_data",true);
startActivityForResult(picIntent,GALLERY_REQUEST);
}
});
myAlertDilog.setNegativeButton("Camera", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
picIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(picIntent,CAMERA_REQUEST);
}
});
myAlertDilog.show();
}
//And rest of things
//还有其他的
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode==GALLERY_REQUEST){
if (resultCode==RESULT_OK){
if (data!=null) {
uri = data.getData();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
try {
BitmapFactory.decodeStream(getContentResolver().openInputStream(uri), null, options);
options.inSampleSize = calculateInSampleSize(options, 100, 100);
options.inJustDecodeBounds = false;
Bitmap image = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri), null, options);
imageofpic.setImageBitmap(image);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}else {
Toast.makeText(getApplicationContext(), "Cancelled",
Toast.LENGTH_SHORT).show();
}
}else if (resultCode == RESULT_CANCELED) {
Toast.makeText(getApplicationContext(), "Cancelled",
Toast.LENGTH_SHORT).show();
}
}else if (requestCode == CAMERA_REQUEST) {
if (resultCode == RESULT_OK) {
if (data.hasExtra("data")) {
bitmap = (Bitmap) data.getExtras().get("data");
uri = getImageUri(YourActivity.this,bitmap);
File finalFile = new File(getRealPathFromUri(uri));
imageofpic.setImageBitmap(bitmap);
} else if (data.getExtras() == null) {
Toast.makeText(getApplicationContext(),
"No extras to retrieve!", Toast.LENGTH_SHORT)
.show();
BitmapDrawable thumbnail = new BitmapDrawable(
getResources(), data.getData().getPath());
pet_pic.setImageDrawable(thumbnail);
}
} else if (resultCode == RESULT_CANCELED) {
Toast.makeText(getApplicationContext(), "Cancelled",
Toast.LENGTH_SHORT).show();
}
}
}
private String getRealPathFromUri(Uri tempUri) {
Cursor cursor = null;
try {
String[] proj = { MediaStore.Images.Media.DATA };
cursor = this.getContentResolver().query(tempUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
private Uri getImageUri(YourActivity youractivity, Bitmap bitmap) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
String path = MediaStore.Images.Media.insertImage(youractivity.getContentResolver(), bitmap, "Title", null);
return Uri.parse(path);
}
回答by Veeresh Charantimath
This helped me to get uri from Gallery and convert to a file for Multipart upload
这帮助我从图库中获取 uri 并转换为用于分段上传的文件
File file = FileUtils.getFile(this, fileUri);