以编程方式从Android内置Gallery应用中获取/select图片

我试图从我的应用程序内部的图库内置应用程序中打开图像/图片。

我有一个图片的URI(图片位于SD卡上)。

你有什么build议吗?

这是一个完整的解决scheme。 我刚刚更新了此示例代码,其中包含@mad下面的答案中提供的信息。 同时从@Khobaib检查下面的解决scheme,解释如何处理Picasa图像。

更新

我刚刚回顾了我的原始答案,并创build了一个简单的Android Studio项目,您可以从github检出并直接导入到您的系统。

https://github.com/hanscappelle/SO-2169649

(注意,多个文件select仍然需要工作)

单张图片select

支持来自文件探索者的图像感谢用户疯狂。

public class BrowsePictureActivity extends Activity { // this is the action code we use in our intent, // this way we know we're looking at the response from our own action private static final int SELECT_PICTURE = 1; private String selectedImagePath; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); findViewById(R.id.Button01) .setOnClickListener(new OnClickListener() { public void onClick(View arg0) { // in onCreate or any event where your want the user to // select a file Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(Intent.createChooser(intent, "Select Picture"), SELECT_PICTURE); } }); } public void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == RESULT_OK) { if (requestCode == SELECT_PICTURE) { Uri selectedImageUri = data.getData(); selectedImagePath = getPath(selectedImageUri); } } } /** * helper to retrieve the path of an image URI */ public String getPath(Uri uri) { // just some safety built in if( uri == null ) { // TODO perform some logging or show user feedback return null; } // try to retrieve the image from the media store first // this will only work for images selected from gallery String[] projection = { MediaStore.Images.Media.DATA }; Cursor cursor = managedQuery(uri, projection, null, null, null); if( cursor != null ){ int column_index = cursor .getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); String path = cursor.getString(column_index); cursor.close(); return path; } // this is our fallback here return uri.getPath(); } } 

select多张照片

由于有人要求评论中的信息,最好收集信息。

在意图上设置一个额外的参数EXTRA_ALLOW_MULTIPLE

 intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true); 

并在结果处理检查该参数:

 if (Intent.ACTION_SEND_MULTIPLE.equals(data.getAction())) && Intent.hasExtra(Intent.EXTRA_STREAM)) { // retrieve a collection of selected images ArrayList<Parcelable> list = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); // iterate over these images if( list != null ) { for (Parcelable parcel : list) { Uri uri = (Uri) parcel; // TODO handle the images one by one here } } } 

请注意,这仅受API级别18+的支持。

这是对hcpl发布的罚款代码的更新。 但这与OI文件pipe理器,天文文件pipe理器和媒体库(testing)一起工作。 所以我想它会和每个文件pipe理器一起工作(除了那些提到的还有很多其他的吗?)。 对他写的代码做了一些修改。

 public class BrowsePicture extends Activity { //YOU CAN EDIT THIS TO WHATEVER YOU WANT private static final int SELECT_PICTURE = 1; private String selectedImagePath; //ADDED private String filemanagerstring; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ((Button) findViewById(R.id.Button01)) .setOnClickListener(new OnClickListener() { public void onClick(View arg0) { // in onCreate or any event where your want the user to // select a file Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(Intent.createChooser(intent, "Select Picture"), SELECT_PICTURE); } }); } //UPDATED public void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == RESULT_OK) { if (requestCode == SELECT_PICTURE) { Uri selectedImageUri = data.getData(); //OI FILE Manager filemanagerstring = selectedImageUri.getPath(); //MEDIA GALLERY selectedImagePath = getPath(selectedImageUri); //DEBUG PURPOSE - you can delete this if you want if(selectedImagePath!=null) System.out.println(selectedImagePath); else System.out.println("selectedImagePath is null"); if(filemanagerstring!=null) System.out.println(filemanagerstring); else System.out.println("filemanagerstring is null"); //NOW WE HAVE OUR WANTED STRING if(selectedImagePath!=null) System.out.println("selectedImagePath is the right one for you!"); else System.out.println("filemanagerstring is the right one for you!"); } } } //UPDATED! public String getPath(Uri uri) { String[] projection = { MediaStore.Images.Media.DATA }; Cursor cursor = managedQuery(uri, projection, null, null, null); if(cursor!=null) { //HERE YOU WILL GET A NULLPOINTER IF CURSOR IS NULL //THIS CAN BE, IF YOU USED OI FILE MANAGER FOR PICKING THE MEDIA int column_index = cursor .getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); return cursor.getString(column_index); } else return null; } 

hcpl的方法完美地工作在KitKat之前,但不能与DocumentsProvider API一起工作。 为此,只需按照正式的Android教程提供文档提供程序: https : //developer.android.com/guide/topics/providers/document-provider.html – >打开文档,位图部分。

简单地说,我使用hcpl的代码并对其进行了扩展:如果带有检索到的图像path的文件抛出exception,我将调用这个函数:

 private Bitmap getBitmapFromUri(Uri uri) throws IOException { ParcelFileDescriptor parcelFileDescriptor = getContentResolver().openFileDescriptor(uri, "r"); FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor(); Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor); parcelFileDescriptor.close(); return image; } 

testingNexus 5。

根据上面的代码,我反映了下面的代码,可能更适合:

 public String getPath(Uri uri) { String selectedImagePath; //1:MEDIA GALLERY --- query from MediaStore.Images.Media.DATA String[] projection = { MediaStore.Images.Media.DATA }; Cursor cursor = managedQuery(uri, projection, null, null, null); if(cursor != null){ int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); selectedImagePath = cursor.getString(column_index); }else{ selectedImagePath = null; } if(selectedImagePath == null){ //2:OI FILE Manager --- call method: uri.getPath() selectedImagePath = uri.getPath(); } return selectedImagePath; } 

假设您的SD卡目录中只有图像文件夹。

 Intent intent = new Intent(Intent.ACTION_GET_CONTENT); // tells your intent to get the contents // opens the URI for your image directory on your sdcard intent.setType("file:///sdcard/image/*"); startActivityForResult(intent, 1); 

然后,您可以决定您想要如何处理活动中的内容。

这是一个检索图像path名的例子,用你的代码testing一下,以确保你可以处理返回的结果。 您可以根据需要更改代码,以更好地满足您的需求。

 protected final void onActivityResult(final int requestCode, final int resultCode, final Intent i) { super.onActivityResult(requestCode, resultCode, i); // this matches the request code in the above call if (requestCode == 1) { Uri _uri = i.getData(); // this will be null if no image was selected... if (_uri != null) { // now we get the path to the image file cursor = getContentResolver().query(_uri, null, null, null, null); cursor.moveToFirst(); String imageFilePath = cursor.getString(0); cursor.close(); } } 

我的build议是尝试检索图像正常工作,我认为问题是访问SD卡上的图像的内容。 看看在SD卡显示图像

如果你可以开始运行,可能通过提供一个正确的提供者的例子,你应该能够找出你的代码的解决方法。

通过更新这个问题的进展让我更新。 祝你好运

我通过@hcpl&@mad解决了这个问题。 hcpl的解决scheme很好地支持图库中的本地图像,mad提供了更好的解决scheme – 它有助于加载OI / Astro / Dropbox图像。 但在我的应用程序中,现在已经集成在Android Gallery中的Picasa库中,两个解决scheme都失败了。

我search了一下,分析了一下,最终find了一个更好的优雅的解决scheme来克服这个限制。 感谢Dimitar Darazhanski为他的博客,在这种情况下帮助了我,我修改了一下,使其更容易理解。 这是我的解决scheme –

 public class BrowsePicture extends Activity { //YOU CAN EDIT THIS TO WHATEVER YOU WANT private static final int SELECT_PICTURE = 1; private String selectedImagePath; //ADDED private String filemanagerstring; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ((Button) findViewById(R.id.Button01)) .setOnClickListener(new OnClickListener() { public void onClick(View arg0) { // in onCreate or any event where your want the user to // select a file Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(Intent.createChooser(intent, "Select Picture"), SELECT_PICTURE); } }); } public void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == RESULT_OK) { if (requestCode == SELECT_PICTURE) { Uri selectedImageUri = data.getData(); Log.d("URI VAL", "selectedImageUri = " + selectedImageUri.toString()); selectedImagePath = getPath(selectedImageUri); if(selectedImagePath!=null){ // IF LOCAL IMAGE, NO MATTER IF ITS DIRECTLY FROM GALLERY (EXCEPT PICASSA ALBUM), // OR OI/ASTRO FILE MANAGER. EVEN DROPBOX IS SUPPORTED BY THIS BECAUSE DROPBOX DOWNLOAD THE IMAGE // IN THIS FORM - file:///storage/emulated/0/Android/data/com.dropbox.android/... System.out.println("local image"); } else{ System.out.println("picasa image!"); loadPicasaImageFromGallery(selectedImageUri); } } } } // NEW METHOD FOR PICASA IMAGE LOAD private void loadPicasaImageFromGallery(final Uri uri) { String[] projection = { MediaColumns.DATA, MediaColumns.DISPLAY_NAME }; Cursor cursor = getContentResolver().query(uri, projection, null, null, null); if(cursor != null) { cursor.moveToFirst(); int columnIndex = cursor.getColumnIndex(MediaColumns.DISPLAY_NAME); if (columnIndex != -1) { new Thread(new Runnable() { // NEW THREAD BECAUSE NETWORK REQUEST WILL BE MADE THAT WILL BE A LONG PROCESS & BLOCK UI // IF CALLED IN UI THREAD public void run() { try { Bitmap bitmap = android.provider.MediaStore.Images.Media.getBitmap(getContentResolver(), uri); // THIS IS THE BITMAP IMAGE WE ARE LOOKING FOR. } catch (Exception ex) { ex.printStackTrace(); } } }).start(); } } cursor.close(); } public String getPath(Uri uri) { String[] projection = { MediaColumns.DATA}; Cursor cursor = getContentResolver().query(uri, projection, null, null, null); if(cursor != null) { //HERE YOU WILL GET A NULLPOINTER IF CURSOR IS NULL //THIS CAN BE, IF YOU USED OI FILE MANAGER FOR PICKING THE MEDIA cursor.moveToFirst(); int columnIndex = cursor.getColumnIndexOrThrow(MediaColumns.DATA); String filePath = cursor.getString(columnIndex); cursor.close(); return filePath; } else return uri.getPath(); // FOR OI/ASTRO/Dropbox etc } 

检查它,让我知道如果有一些问题。 我已经testing过,并且在任何情况下都能正常工作。

希望这会帮助大家。

这里有两个关于图像select器的有用的教程,可下载的源代码:

如何创buildAndroid图像select器

如何在Android上select和裁剪图像

然而,应用程序将被迫closures,你可以通过在Manifest文件的主要活动中添加android:configChanges属性来修复它:

 <activity android:name=".MainActivity" android:label="@string/app_name" android:configChanges="keyboardHidden|orientation" > 

相机API似乎失去了方向的控制,所以这将有助于它。 🙂

这是我重新回到这个话题,收集所有的信息,再加上其他相关的堆栈溢出问题。 它在处理内存不足情况和图像旋转的同时返回某些提供程序的图像。 它支持图库,Picasa和文件pipe理器,如下拉框。 用法很简单:作为input,构造函数接收内容parsing器和uri。 输出是最终的位图。

 /** * Creates resized images without exploding memory. Uses the method described in android * documentation concerning bitmap allocation, which is to subsample the image to a smaller size, * close to some expected size. This is required because the android standard library is unable to * create a reduced size image from an image file using memory comparable to the final size (and * loading a full sized multi-megapixel picture for processing may exceed application memory budget). */ public class UserPicture { static int MAX_WIDTH = 600; static int MAX_HEIGHT = 800; Uri uri; ContentResolver resolver; String path; Matrix orientation; int storedHeight; int storedWidth; public UserPicture(Uri uri, ContentResolver resolver) { this.uri = uri; this.resolver = resolver; } private boolean getInformation() throws IOException { if (getInformationFromMediaDatabase()) return true; if (getInformationFromFileSystem()) return true; return false; } /* Support for gallery apps and remote ("picasa") images */ private boolean getInformationFromMediaDatabase() { String[] fields = { Media.DATA, ImageColumns.ORIENTATION }; Cursor cursor = resolver.query(uri, fields, null, null, null); if (cursor == null) return false; cursor.moveToFirst(); path = cursor.getString(cursor.getColumnIndex(Media.DATA)); int orientation = cursor.getInt(cursor.getColumnIndex(ImageColumns.ORIENTATION)); this.orientation = new Matrix(); this.orientation.setRotate(orientation); cursor.close(); return true; } /* Support for file managers and dropbox */ private boolean getInformationFromFileSystem() throws IOException { path = uri.getPath(); if (path == null) return false; ExifInterface exif = new ExifInterface(path); int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); this.orientation = new Matrix(); switch(orientation) { case ExifInterface.ORIENTATION_NORMAL: /* Identity matrix */ break; case ExifInterface.ORIENTATION_FLIP_HORIZONTAL: this.orientation.setScale(-1, 1); break; case ExifInterface.ORIENTATION_ROTATE_180: this.orientation.setRotate(180); break; case ExifInterface.ORIENTATION_FLIP_VERTICAL: this.orientation.setScale(1, -1); break; case ExifInterface.ORIENTATION_TRANSPOSE: this.orientation.setRotate(90); this.orientation.postScale(-1, 1); break; case ExifInterface.ORIENTATION_ROTATE_90: this.orientation.setRotate(90); break; case ExifInterface.ORIENTATION_TRANSVERSE: this.orientation.setRotate(-90); this.orientation.postScale(-1, 1); break; case ExifInterface.ORIENTATION_ROTATE_270: this.orientation.setRotate(-90); break; } return true; } private boolean getStoredDimensions() throws IOException { InputStream input = resolver.openInputStream(uri); Options options = new Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeStream(resolver.openInputStream(uri), null, options); /* The input stream could be reset instead of closed and reopened if it were possible to reliably wrap the input stream on a buffered stream, but it's not possible because decodeStream() places an upper read limit of 1024 bytes for a reset to be made (it calls mark(1024) on the stream). */ input.close(); if (options.outHeight <= 0 || options.outWidth <= 0) return false; storedHeight = options.outHeight; storedWidth = options.outWidth; return true; } public Bitmap getBitmap() throws IOException { if (!getInformation()) throw new FileNotFoundException(); if (!getStoredDimensions()) throw new InvalidObjectException(null); RectF rect = new RectF(0, 0, storedWidth, storedHeight); orientation.mapRect(rect); int width = (int)rect.width(); int height = (int)rect.height(); int subSample = 1; while (width > MAX_WIDTH || height > MAX_HEIGHT) { width /= 2; height /= 2; subSample *= 2; } if (width == 0 || height == 0) throw new InvalidObjectException(null); Options options = new Options(); options.inSampleSize = subSample; Bitmap subSampled = BitmapFactory.decodeStream(resolver.openInputStream(uri), null, options); Bitmap picture; if (!orientation.isIdentity()) { picture = Bitmap.createBitmap(subSampled, 0, 0, options.outWidth, options.outHeight, orientation, false); subSampled.recycle(); } else picture = subSampled; return picture; } } 

参考文献:

2.3(姜饼)-4.4(Kitkat),5.0(棒棒糖)和6.0(棉花糖)的解决scheme下面也是: –

步骤1打开图库select图片的代码:

 public static final int PICK_IMAGE = 1; private void takePictureFromGalleryOrAnyOtherFolder() { Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE); } 

第2步获取onActivityResult数据的代码:

  @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == Activity.RESULT_OK) { if (requestCode == PICK_IMAGE) { Uri selectedImageUri = data.getData(); String imagePath = getRealPathFromURI(selectedImageUri); //Now you have imagePath do whatever you want to do now }//end of inner if }//end of outer if } public String getRealPathFromURI(Uri contentUri) { //Uri contentUri = Uri.parse(contentURI); String[] projection = { MediaStore.Images.Media.DATA }; Cursor cursor = null; try { if (Build.VERSION.SDK_INT > 19) { // Will return "image:x*" String wholeID = DocumentsContract.getDocumentId(contentUri); // Split at colon, use second item in the array String id = wholeID.split(":")[1]; // where id is equal to String sel = MediaStore.Images.Media._ID + "=?"; cursor = context.getContentResolver().query( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, sel, new String[] { id }, null); } else { cursor = context.getContentResolver().query(contentUri, projection, null, null, null); } } catch (Exception e) { e.printStackTrace(); } String path = null; try { int column_index = cursor .getColumnIndex(MediaStore.Images.Media.DATA); cursor.moveToFirst(); path = cursor.getString(column_index).toString(); cursor.close(); } catch (NullPointerException e) { e.printStackTrace(); } return path; } 

要显示图片和video,请试试这个:

  Intent intent = new Intent(); intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(intent, 1); startActivityForResult(Intent.createChooser(intent,"Wybierz plik"), SELECT_FILE); 

以防万一它有帮助 我这样做来获取位图:

 InputStream is = context.getContentResolver().openInputStream(imageUri); Bitmap bitmap = BitmapFactory.decodeStream(is); 

以上答案是正确的。 我遇到了一个不同的问题,在HTC M8的应用程序崩溃时,从图库中select一个图像。 我得到的图像path为空值。 我使用以下解决scheme进行了修复和优化。 在onActivityResult方法中

 protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if ((requestCode == RESULT_LOAD_IMAGE) && (resultCode == RESULT_OK)) { if (data != null) { Uri selectedImageUri = null; selectedImageUri = data.getData(); String[] filePathColumn = { MediaStore.Images.Media.DATA }; Cursor imageCursor = mainActivity.getContentResolver().query( selectedImageUri, filePathColumn, null, null, null); if (imageCursor == null) { return; } imageCursor.moveToFirst(); int columnIndex = imageCursor.getColumnIndex(filePathColumn[0]); picturePath = imageCursor.getString(columnIndex); if (picturePath == null) { picturePath = selectedImageUri.getPath(); String wholeID = DocumentsContract .getDocumentId(selectedImage); // 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 = mainActivity.getContentResolver().query( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, column, sel, new String[] { id }, null); columnIndex = cursor.getColumnIndex(column[0]); if (cursor.moveToFirst()) { picturePath = cursor.getString(columnIndex); } cursor.close(); } picturePathAbs = new File(picturePath).getAbsolutePath(); imageCursor.close(); } 

}

 package com.ImageConvertingDemo; import java.io.BufferedInputStream; import java.io.FileInputStream; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.util.Log; import android.widget.EditText; import android.widget.ImageView; public class MyActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); EditText tv = (EditText)findViewById(R.id.EditText01); ImageView iv = (ImageView)findViewById(R.id.ImageView01); FileInputStream in; BufferedInputStream buf; try { in = new FileInputStream("/sdcard/smooth.png"); buf = new BufferedInputStream(in,1070); System.out.println("1.................."+buf); byte[] bMapArray= new byte[buf.available()]; tv.setText(bMapArray.toString()); buf.read(bMapArray); Bitmap bMap = BitmapFactory.decodeByteArray(bMapArray, 0, bMapArray.length); /*for (int i = 0; i < bMapArray.length; i++) { System.out.print("bytearray"+bMapArray[i]); }*/ iv.setImageBitmap(bMap); //tv.setText(bMapArray.toString()); //tv.setText(buf.toString()); if (in != null) { in.close(); } if (buf != null) { buf.close(); } } catch (Exception e) { Log.e("Error reading file", e.toString()); } } } 
 public class BrowsePictureActivity extends Activity { // this is the action code we use in our intent, // this way we know we're looking at the response from our own action private static final int SELECT_PICTURE = 1; private String selectedImagePath; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ((Button) findViewById(R.id.Button01)) .setOnClickListener(new OnClickListener() { public void onClick(View arg0) { // in onCreate or any event where your want the user to // select a file Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(Intent.createChooser(intent, "Select Picture"), SELECT_PICTURE); } }); } public void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == RESULT_OK) { if (requestCode == SELECT_PICTURE) { Uri selectedImageUri = data.getData(); selectedImagePath = getPath(selectedImageUri); } } } /** * helper to retrieve the path of an image URI */ public String getPath(Uri uri) { // just some safety built in if( uri == null ) { // TODO perform some logging or show user feedback return null; } // try to retrieve the image from the media store first // this will only work for images selected from gallery String[] projection = { MediaStore.Images.Media.DATA }; Cursor cursor = managedQuery(uri, projection, null, null, null); if( cursor != null ){ int column_index = cursor .getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); return cursor.getString(column_index); } // this is our fallback here return uri.getPath(); } } 

检索特定types的文件

这个例子将得到一个图像的副本。

 static final int REQUEST_IMAGE_GET = 1; public void selectImage() { Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("image/*"); if (intent.resolveActivity(getPackageManager()) != null) { startActivityForResult(intent, REQUEST_IMAGE_GET); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_IMAGE_GET && resultCode == RESULT_OK) { Bitmap thumbnail = data.getParcelable("data"); Uri fullPhotoUri = data.getData(); // Do work with photo saved at fullPhotoUri ... } } 

打开特定types的文件

在4.4或更高版本上运行时,请求打开由另一个应用程序pipe理的文件

 static final int REQUEST_IMAGE_OPEN = 1; public void selectImage() { Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); intent.setType("image/*"); intent.addCategory(Intent.CATEGORY_OPENABLE); // Only the system receives the ACTION_OPEN_DOCUMENT, so no need to test. startActivityForResult(intent, REQUEST_IMAGE_OPEN); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_IMAGE_OPEN && resultCode == RESULT_OK) { Uri fullPhotoUri = data.getData(); // Do work with full size photo saved at fullPhotoUri ... } } 

原始来源

除了以前的答案,如果你有问题得到正确的道路(如AndroZip),你可以使用这个:

  public String getPath(Uri uri ,ContentResolver contentResolver) { String[] projection = { MediaStore.MediaColumns.DATA}; Cursor cursor; try{ cursor = contentResolver.query(uri, projection, null, null, null); } catch (SecurityException e){ String path = uri.getPath(); String result = tryToGetStoragePath(path); return result; } if(cursor != null) { //HERE YOU WILL GET A NULLPOINTER IF CURSOR IS NULL //THIS CAN BE, IF YOU USED OI FILE MANAGER FOR PICKING THE MEDIA cursor.moveToFirst(); int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA); String filePath = cursor.getString(columnIndex); cursor.close(); return filePath; } else return uri.getPath(); // FOR OI/ASTRO/Dropbox etc } private String tryToGetStoragePath(String path) { int actualPathStart = path.indexOf("//storage"); String result = path; if(actualPathStart!= -1 && actualPathStart< path.length()) result = path.substring(actualPathStart+1 , path.length()); return result; } 

请从图库中findselect单张图片的答案

 import android.app.Activity; import android.net.Uri; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; import java.io.ByteArrayOutputStream; import java.io.FileNotFoundException; import java.io.InputStream; public class PickImage extends Activity { Button btnOpen, btnGet, btnPick; TextView textInfo1, textInfo2; ImageView imageView; private static final int RQS_OPEN_IMAGE = 1; private static final int RQS_GET_IMAGE = 2; private static final int RQS_PICK_IMAGE = 3; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.image_pick); btnOpen = (Button)findViewById(R.id.open); btnGet = (Button)findViewById(R.id.get); btnPick = (Button)findViewById(R.id.pick); textInfo1 = (TextView)findViewById(R.id.info1); textInfo2 = (TextView)findViewById(R.id.info2); imageView = (ImageView) findViewById(R.id.image); btnOpen.setOnClickListener(btnOpenOnClickListener); btnGet.setOnClickListener(btnGetOnClickListener); btnPick.setOnClickListener(btnPickOnClickListener); } View.OnClickListener btnOpenOnClickListener = new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(); intent.setAction(Intent.ACTION_OPEN_DOCUMENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType("image/*"); startActivityForResult(intent, RQS_OPEN_IMAGE); } }; View.OnClickListener btnGetOnClickListener = new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(); intent.setAction(Intent.ACTION_GET_CONTENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType("image/*"); startActivityForResult(intent, RQS_OPEN_IMAGE); } }; View.OnClickListener btnPickOnClickListener = new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(intent, RQS_PICK_IMAGE); } }; @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK) { if (requestCode == RQS_OPEN_IMAGE || requestCode == RQS_GET_IMAGE || requestCode == RQS_PICK_IMAGE) { imageView.setImageBitmap(null); textInfo1.setText(""); textInfo2.setText(""); Uri mediaUri = data.getData(); textInfo1.setText(mediaUri.toString()); String mediaPath = mediaUri.getPath(); textInfo2.setText(mediaPath); //display the image try { InputStream inputStream = getBaseContext().getContentResolver().openInputStream(mediaUri); Bitmap bm = BitmapFactory.decodeStream(inputStream); ByteArrayOutputStream stream = new ByteArrayOutputStream(); byte[] byteArray = stream.toByteArray(); imageView.setImageBitmap(bm); } catch (FileNotFoundException e) { e.printStackTrace(); } } } } }