Как выбрать изображение из галереи (SD-карта) для моего приложения?
этот вопрос был первоначально задан для Android 1.6.
Я работаю над вариантами фотографий в моем приложении.
У меня есть кнопка и ImageView в моей деятельности. Когда я нажимаю кнопку, она перенаправляется в галерею, и я смогу выбрать изображение. Выбранное изображение появится в мои книги.
10 ответов:
обновил ответ, почти 5 лет спустя:
код в исходном ответе больше не работает надежно, так как изображения из разных источников иногда возвращаются с другим содержимым URI, т. е.
content://
, а неfile://
. Лучшее решение-просто использоватьcontext.getContentResolver().openInputStream(intent.getData())
, так как это вернет входной поток, который вы можете обрабатывать по своему выбору.например,
BitmapFactory.decodeStream()
отлично работает в этой ситуации, так как вы также можете использовать параметры и поле inSampleSize, чтобы downsample большие изображения и избежать проблем с памятью.однако такие вещи, как Google Drive, возвращают 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 столбцов информации, начиная от его пути к файлу до "даты последнего изменения" до GPS-координат, где была сделана фотография, хотя многие из полей фактически не используются.
чтобы сэкономить время, поскольку вам на самом деле не нужны другие поля, курсор поиск осуществляется с помощью фильтра. Фильтр работает, указывая имя столбца, который вы хотите, MediaStore.Изображения.Сми.Данные, которые являются путем, а затем дают эту строку[] для запроса курсора. Запрос курсора возвращает путь, но вы не знаете, в каком столбце он находится, пока не используете
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.
вот проверенный код для изображения и video.It будет работать для всех API менее 19 и более 19, а также.
изображение:
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); }
видео:
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(); }
сделать это, чтобы запустить галерею и позволить пользователю выбрать изображение:
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
, Как получать реальный путь изображения, а затем использоватьBitmapFactory.decodeFile(path)
для полученияBitmap
.этот шаг не является необходимым. Элемент
ImageView
класс имеет метод, называемыйsetImageURI(uri)
. Передайте ваш uri к нему, и вы должны быть сделаны.Uri imageUri = data.getData(); imageView.setImageURI(imageUri);
для полного рабочего примера вы можете посмотреть здесь: http://androidbitmaps.blogspot.com/2015/04/loading-images-in-android-part-iii-pick.html
PS:
ПолучениеBitmap
в отдельной переменной будет иметь смысл в тех случаях, когда загружаемое изображение слишком велико, чтобы поместиться в памяти, и операция масштабирования необходима для предотвращенияOurOfMemoryError
, как показано в ответе @siamii.
вызовите метод chooseImage, например-
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() + "/images/make_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); }