如何从图库(SD卡)为我的应用程序select一个图像?
这个问题最初是要求为Android 1.6。
我正在处理我的应用程序中的照片选项。
我在我的活动中有一个button和一个ImageView。 当我点击button时,它会redirect到画廊,我将能够select一个图像。 所选图像将出现在我的ImageView中。
近5年后更新了答案:
原始答案中的代码不再可靠地工作,因为来自各种来源的图像有时会返回不同的内容URI,即content://
而不是file://
。 一个更好的解决scheme是简单地使用context.getContentResolver().openInputStream(intent.getData())
,因为这将返回一个InputStream,你可以在你select的时候处理。
例如, BitmapFactory.decodeStream()
在这种情况下可以很好地工作,因为您也可以使用Options和inSampleSize字段来下采样大图像并避免内存问题。
但是,Google云端硬盘会将URI返回给尚未实际下载的图片。 因此,您需要在后台线程上执行getContentResolver()代码。
原始答案:
其他答案解释了如何发送意图,但他们没有解释如何处理这个答复。 以下是关于如何做到的一些示例代码:
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) { super.onActivityResult(requestCode, resultCode, imageReturnedIntent); switch(requestCode) { case REQ_CODE_PICK_IMAGE: if(resultCode == RESULT_OK){ Uri selectedImage = imageReturnedIntent.getData(); String[] filePathColumn = {MediaStore.Images.Media.DATA}; Cursor cursor = getContentResolver().query( selectedImage, filePathColumn, null, null, null); cursor.moveToFirst(); int columnIndex = cursor.getColumnIndex(filePathColumn[0]); String filePath = cursor.getString(columnIndex); cursor.close(); Bitmap yourSelectedImage = BitmapFactory.decodeFile(filePath); } } }
在这之后,您已经将所选的图像存储在“yourSelectedImage”中,以执行任何您想要的操作。 这段代码通过获取ContentResolver数据库中图像的位置来工作,但是它本身是不够的。 每个图像都有大约18列的信息,从文件path到'最后修改date'到拍摄照片的GPS坐标,尽pipe很多字段没有被实际使用。
为了节省时间,因为您实际上不需要其他字段,光标search使用filter完成。 该filter通过指定所需列的名称MediaStore.Images.Media.DATA(这是path),然后将该string[]指定给游标查询来工作。 游标查询返回的path,但你不知道它是哪个列,直到你使用columnIndex
代码。 这只是根据名称获取列的编号,在过滤过程中使用了相同的名称。 一旦你得到了,你终于能够解码图像成最后一行我给的代码位图。
private static final int SELECT_PHOTO = 100;
开始意图
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK); photoPickerIntent.setType("image/*"); startActivityForResult(photoPickerIntent, SELECT_PHOTO);
处理结果
@Override protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) { super.onActivityResult(requestCode, resultCode, imageReturnedIntent); switch(requestCode) { case SELECT_PHOTO: if(resultCode == RESULT_OK){ Uri selectedImage = imageReturnedIntent.getData(); InputStream imageStream = getContentResolver().openInputStream(selectedImage); Bitmap yourSelectedImage = BitmapFactory.decodeStream(imageStream); } } }
或者,您也可以对图像进行缩减采样以避免OutOfMemory错误。
private Bitmap decodeUri(Uri selectedImage) throws FileNotFoundException { // Decode image size BitmapFactory.Options o = new BitmapFactory.Options(); o.inJustDecodeBounds = true; BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage), null, o); // The new size we want to scale to final int REQUIRED_SIZE = 140; // Find the correct scale value. It should be the power of 2. int width_tmp = o.outWidth, height_tmp = o.outHeight; int scale = 1; while (true) { if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE) { break; } width_tmp /= 2; height_tmp /= 2; scale *= 2; } // Decode with inSampleSize BitmapFactory.Options o2 = new BitmapFactory.Options(); o2.inSampleSize = scale; return BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage), null, o2); }
你必须开始画廊意图的结果。
Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(i, ACTIVITY_SELECT_IMAGE);
然后在onActivityForResult
,调用intent.getData()
来获取图像的Uri。 然后,您需要从ContentProvider获取图像。
这是一个经过testing的图像和video代码。它将适用于所有19以下和19以上的API。
图片:
if (Build.VERSION.SDK_INT <= 19) { Intent i = new Intent(); i.setType("image/*"); i.setAction(Intent.ACTION_GET_CONTENT); i.addCategory(Intent.CATEGORY_OPENABLE); startActivityForResult(i, 10); } else if (Build.VERSION.SDK_INT > 19) { Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(intent, 10); }
video:
if (Build.VERSION.SDK_INT <= 19) { Intent i = new Intent(); i.setType("video/*"); i.setAction(Intent.ACTION_GET_CONTENT); i.addCategory(Intent.CATEGORY_OPENABLE); startActivityForResult(i, 20); } else if (Build.VERSION.SDK_INT > 19) { Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI); startActivityForResult(intent, 20); }
。
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == Activity.RESULT_OK) { if (requestCode == 10) { Uri selectedImageUri = data.getData(); String selectedImagePath = getRealPathFromURI(selectedImageUri); } else if (requestCode == 20) { Uri selectedVideoUri = data.getData(); String selectedVideoPath = getRealPathFromURI(selectedVideoUri); } } } public String getRealPathFromURI(Uri uri) { if (uri == null) { return null; } String[] projection = {MediaStore.Images.Media.DATA}; Cursor cursor = getActivity().getContentResolver().query(uri, projection, null, null, null); if (cursor != null) { int column_index = cursor .getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); return cursor.getString(column_index); } return uri.getPath(); }
这样做启animation廊,并允许用户select一个图像:
Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("image/*"); startActivityForResult(intent, IMAGE_PICK);
然后在你的onActivityResult()
使用返回的图像的URI来设置ImageView上的图像。
public class EMView extends Activity { ImageView img,img1; int column_index; Intent intent=null; // Declare our Views, so we can access them later String logo,imagePath,Logo; Cursor cursor; //YOU CAN EDIT THIS TO WHATEVER YOU WANT private static final int SELECT_PICTURE = 1; String selectedImagePath; //ADDED String filemanagerstring; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); img= (ImageView)findViewById(R.id.gimg1); ((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 @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK) { if (requestCode == SELECT_PICTURE) { Uri selectedImageUri = data.getData(); //OI FILE Manager filemanagerstring = selectedImageUri.getPath(); //MEDIA GALLERY selectedImagePath = getPath(selectedImageUri); img.setImageURI(selectedImageUri); imagePath.getBytes(); TextView txt = (TextView)findViewById(R.id.title); txt.setText(imagePath.toString()); Bitmap bm = BitmapFactory.decodeFile(imagePath); // img1.setImageBitmap(bm); } } } //UPDATED! public String getPath(Uri uri) { String[] projection = { MediaColumns.DATA }; Cursor cursor = managedQuery(uri, projection, null, null, null); column_index = cursor .getColumnIndexOrThrow(MediaColumns.DATA); cursor.moveToFirst(); imagePath = cursor.getString(column_index); return cursor.getString(column_index); } }
public class BrowsePictureActivity extends Activity { 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) { 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); } } } public String getPath(Uri uri) { if( uri == null ) { return null; } // 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); } return uri.getPath(); } }
由于某些原因, onActivityResult()
所有答案都会尝试对接收到的Uri
进行后期处理,例如获取图像的实际path,然后使用BitmapFactory.decodeFile(path)
获取Bitmap
。
这一步是不必要的。 ImageView
类有一个名为setImageURI(uri)
。 把你的尿通过它,你应该完成。
Uri imageUri = data.getData(); imageView.setImageURI(imageUri);
对于一个完整的工作例子,你可以看看这里: http : //androidbitmaps.blogspot.com/2015/04/loading-images-in-android-part-iii-pick.html
PS:
在一个单独的variables中获取Bitmap
是有意义的,因为要加载的图像太大而不能放入内存,并且缩小操作对于防止OurOfMemoryError
是必要的,就像@siamii答案中所示。
调用chooseImage方法like-
public void chooseImage(ImageView v) { Intent intent = new Intent(Intent.ACTION_PICK); intent.setType("image/*"); startActivityForResult(intent, SELECT_PHOTO); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) { // TODO Auto-generated method stub super.onActivityResult(requestCode, resultCode, imageReturnedIntent); if(imageReturnedIntent != null) { Uri selectedImage = imageReturnedIntent.getData(); switch(requestCode) { case SELECT_PHOTO: if(resultCode == RESULT_OK) { Bitmap datifoto = null; temp.setImageBitmap(null); Uri picUri = null; picUri = imageReturnedIntent.getData();//<- get Uri here from data intent if(picUri !=null){ try { datifoto = android.provider.MediaStore.Images.Media.getBitmap(this.getContentResolver(), picUri); temp.setImageBitmap(datifoto); } catch (FileNotFoundException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } catch (OutOfMemoryError e) { Toast.makeText(getBaseContext(), "Image is too large. choose other", Toast.LENGTH_LONG).show(); } } } break; } } else { //Toast.makeText(getBaseContext(), "data null", Toast.LENGTH_SHORT).show(); } }
#initialize in main activity path = Environment.getExternalStorageDirectory() + "http://img.dovov.commake_machine_example.jpg"; # ImageView image=(ImageView)findViewById(R.id.image); //--------------------------------------------------|| public void FromCamera(View) { Log.i("camera", "startCameraActivity()"); File file = new File(path); Uri outputFileUri = Uri.fromFile(file); Intent intent = new Intent( android.provider.MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri); startActivityForResult(intent, 1); } public void FromCard() { Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(i, 2); } protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 2 && resultCode == RESULT_OK && null != data) { Uri selectedImage = data.getData(); String[] filePathColumn = { MediaStore.Images.Media.DATA }; Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null); cursor.moveToFirst(); int columnIndex = cursor.getColumnIndex(filePathColumn[0]); String picturePath = cursor.getString(columnIndex); cursor.close(); bitmap = BitmapFactory.decodeFile(picturePath); image.setImageBitmap(bitmap); if (bitmap != null) { ImageView rotate = (ImageView) findViewById(R.id.rotate); } } else { Log.i("SonaSys", "resultCode: " + resultCode); switch (resultCode) { case 0: Log.i("SonaSys", "User cancelled"); break; case -1: onPhotoTaken(); break; } } } protected void onPhotoTaken() { // Log message Log.i("SonaSys", "onPhotoTaken"); taken = true; imgCapFlag = true; BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 4; bitmap = BitmapFactory.decodeFile(path, options); image.setImageBitmap(bitmap); }
- 在注销时,清除活动历史堆栈,防止“后退”button打开已login的活动
- 帮助传递ArrayList和Parcelable Activity
- 在CoordinatorLayout的工具栏下方添加视图
- 我应该怎样给图像在Android的圆angular?
- Android VideoView方向随着缓冲video而改变
- Android – 从HashMap获取价值
- content_main.xml和activity_main.xml之间的区别?
- 获取存储在android的res / raw文件夹中的.mp3文件的URI
- 如何在没有checkbox的情况下在listview中显示已安装的应用程序列表在列表视图滚动时未被选中?