Uygulamam için galeriden (SD Kart) bir resim nasıl seçilir?


343

Bu soru ilk olarak Android 1.6 için sorulmuştur.

Uygulamamdaki fotoğraf seçenekleri üzerinde çalışıyorum.

Etkinliğimde bir düğme ve bir ImageView var. Düğmeye tıkladığımda galeriye yönlendiriyor ve bir resim seçebiliyorum. Seçilen görüntü ImageView'imde görünecektir.


1
Bu cevaba bak, ben de dosya yöneticilerinden seçtikleri ele almak için geliştirilmiş bir kod yayınladı ayrıca stackoverflow.com/questions/2169649/…
mad

Yanıtlar:


418

Güncel cevap, yaklaşık 5 yıl sonra:

Çeşitli kaynaklardan görüntüleri bazen yani farklı bir içerikle URI ile dönmek gibi orijinal yanıtında kod artık, güvenilir bir şekilde çalışır content://ziyade file://. Daha iyi bir çözüm basitçe kullanmaktır context.getContentResolver().openInputStream(intent.getData()), çünkü seçtiğiniz gibi işleyebileceğiniz bir InputStream döndürür.

Örneğin, BitmapFactory.decodeStream()bu durumda mükemmel çalışır, çünkü büyük resimleri küçültmek ve bellek sorunlarından kaçınmak için Seçenekler ve inSampleSize alanını da kullanabilirsiniz.

Ancak, Google Drive gibi şeyler URI'leri henüz indirilmemiş görüntülere döndürür. Bu nedenle, arka plan iş parçacığında getContentResolver () kodunu gerçekleştirmeniz gerekir.


Orijinal cevap:

Diğer cevaplar, niyetin nasıl gönderileceğini açıkladı, ancak yanıtı nasıl ele alacağını iyi açıklamadılar. Bunu nasıl yapacağınıza dair bazı örnek kodlar:

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);
        }
    }
}

Bundan sonra, seçilen görüntüyü istediğiniz gibi yapmak için "yourSelectedImage" da depolanır. Bu kod, görüntünün ContentResolver veritabanındaki konumunu alarak çalışır, ancak bu tek başına yeterli değildir. Her görüntünün dosya yolundan 'son değiştirilme tarihi'ne, fotoğrafın çekildiği yerdeki GPS koordinatlarına kadar 18 sütunluk bilgi vardır, ancak alanların çoğu gerçekte kullanılmaz.

Diğer alanlara gerçekten ihtiyacınız olmadığından zaman kazanmak için imleç araması bir filtreyle yapılır. Filtre, istediğiniz sütunun adını (yol olan MediaStore.Images.Media.DATA) belirterek ve ardından o dizeyi [] imleç sorgusuna vererek çalışır. İmleç sorgusu yolla döner, ancak columnIndexkodu kullanana kadar hangi sütunda olduğunu bilmezsiniz . Bu, filtreleme işleminde kullanılanın adıyla sütun sayısını alır. Bunu elde ettikten sonra, görüntüyü son verdiğim kod satırı ile bir bitmap'e deşifre edebilirsiniz.


4
cursor.moveToFirst () varlığının kontrol edilmesi gerekir: if (cursor.moveToFirst ()) {imleç verileriyle bir şeyler yapın}
mishkin

14
İmleç yerine görüntüyü şu şekilde almalısınız: Bitmap b = MediaStore.Images.Media.getBitmap (this.getContentResolver (), selectedImage);
Luigi Agosti

4
Luigi, Bitmap büyükse MediaStore.Images.Media.getBitmap (), OutOfMemory istisnalarına neden olabilir. Steve'in yöntemi, görüntüyü belleğe yüklemeden önce ölçeklendirmeyi sağlar.
Frank Harper

9
Bu benim için çalışmıyor, cursor.getString (columnIndex) bir null olsun;
Alexis Pautrot

9
Bu yönteme dikkat edin: kullanıcı bir picasa albümünden veya Google+ Fotoğraflar uygulamasından bir fotoğraf seçtiğinde dosya adı 'boş' olur.
Ciske Boekelo

315
private static final int SELECT_PHOTO = 100;

Niyeti başlat

Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, SELECT_PHOTO);    

İşlem sonucu

@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);
        }
    }
}

Alternatif olarak, OutOfMemory hatalarını önlemek için resminizi altörnekleyebilirsiniz.

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);

    }

8
100 piksele 100 piksellik küçük görüntülemeye 1,5 MB'lik bir jpeg yerleştirmek VM'nin bellek yetersizliğine neden oldu. Altörnekleme bu sorunu düzeltti :-)
Birisi

1
Selam. Her iki akış da kapatılmamalı mı?
Denis Kniazhev

Merhaba @ siamii..Kodunu takip ettim ... ama kısmen benim için çalışıyor .. :( Resim yakalanan resimler bölümünde galeriden seçildiğinde, json hatası veriyor, ancak görüntü bluetooth bölümü altında galeriden seçildiğinde görüntü erişilir ve sunucuya gönderilir .. lütfen bu bağlantıyı kontrol edip bana herhangi bir çözüm önerebilir misiniz? stackoverflow.com/questions/29234409/image-is-not-uploaded
Prabs

Ölçeği bulma ile ilgili bölüm şu şekilde yazılabilir:int scale = 1; for ( ; bfOptions.outWidth / scale > TARGET_SIZE && bfOptions.outWidth > TARGET_SIZE; scale*=2);
The_Rafi

@siamii Bu yöntemi nereden ve nasıl çağırırsınız -------- decodeUri
Akshay Kumar

87

Sonuç için galeri amacını başlatmalısınız.

Intent i = new Intent(Intent.ACTION_PICK,
               android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, ACTIVITY_SELECT_IMAGE); 

Ardından , Görüntünün Uri'sini almak için onActivityForResultarayın intent.getData(). Ardından, Görüntüyü ContentProvider'dan almanız gerekir.


ACTION_PICK'in diğer iki cevapta kullanılan ACTION_GET_CONTENT'ten farkı nedir?
penguin359

4
ACTION_PICK ile belirli bir URI belirtirsiniz ve ACTION_GET_CONTENT ile bir mime_type belirtirsiniz. ACTION_PICK'i kullandım çünkü soru özellikle SDCARD'dan görüntüler değil, tüm resimlerdi.
Robby Pond

2
Güzel. Bu tam olarak ihtiyaç duyduğum ve bir cazibe gibi çalıştı :) Bu şeyleri nereden bulduğunuzu merak ediyorum :)
Jayshil Dave

@WilliamKinaan ACTIVITY_SELECT_IMAGE, almayı beklediğiniz sonucu belirlemek için belirttiğiniz herhangi bir int değeridir. Daha sonra onActivityResult'a (int requestCode, int sonuçKodu, Niyet verileri) 'requestCode' olarak geri gönderilir.
Fydo

@Fydo Daha sonra fark ettim, Teşekkürler
William Kinaan 28:13

22

İşte görüntü ve video için test edilmiş bir kod. 19'dan küçük ve 19'dan büyük tüm API'ler için de çalışır.

Resim:

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();
        }

14

Galeriyi başlatmak ve kullanıcının bir görüntü seçmesine izin vermek için bunu yapın:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, IMAGE_PICK);

Ardından onActivityResult(), ImageView'inizde görüntüyü ayarlamak için döndürülen görüntünün URI'sini kullanın.


3
Bu Android 4.4 cihazlar için çalışmaz. Son kullanılan belgeler ekranını başlatacak.
Noundla Sandeep

2
KitKat için bir düzeltme: stackoverflow.com/a/26690628/860488
Morten Holmgaard

11
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);
}

}

8
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();
}

}

KitKat için bir düzeltme: stackoverflow.com/a/26690628/860488
Morten Holmgaard

4

Bazı nedenlerden dolayı, bu konudaki tüm cevaplar onActivityResult(), alınan Urigörüntünün gerçek yolunu almak ve daha sonra kullanmak gibi,BitmapFactory.decodeFile(path) almak almak içinBitmap .

Bu adım gerekli değildir. ImageViewSınıf olarak adlandırılan bir yöntemi vardır setImageURI(uri). Uri'nizi ona iletin ve işiniz bitti.

Uri imageUri = data.getData();
imageView.setImageURI(imageUri);

Tam bir çalışma örneği için buraya göz atabilirsiniz: http://androidbitmaps.blogspot.com/2015/04/loading-images-in-android-part-iii-pick.html

Not:
Alma Bitmapgörüntü yüklenecek durumlarda mantıklıdır ayrı değişkene bellekte sığmayacak kadar büyük ve operasyon aşağı bir ölçek önlemek için gerekli OurOfMemoryError@siamii cevap gösterildiği gibi,.


3

selectImage yöntemini çağırın-

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();
    }
}

1
#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);


}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.