Android wybiera zdjęcia z galerii


196

Chcę utworzyć selektor zdjęć z galerii. Używam kodu

 intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
 startActivityForResult(intent, TFRequestCodes.GALLERY);

Mój problem polega na tym, że w tym działaniu wyświetlane są pliki wideo. Czy istnieje sposób na filtrowanie wyświetlanych plików, aby żadne pliki wideo nie były wyświetlane w tym działaniu?


3
W tym artykule ładnie opisano, jak wybierać zdjęcia z galerii: androidbitmaps.blogspot.com/2015/04/…
Andy Res

Jest jedno podobne pytanie jak ty. stackoverflow.com/a/31382240/1835650
TeeTracker

Odpowiedzi:


344

Absolutnie. Spróbuj tego:

Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE);

Nie zapomnij również o utworzeniu stałej PICK_IMAGE , abyś mógł rozpoznać, kiedy użytkownik wróci z galerii obrazów. Aktywność:

public static final int PICK_IMAGE = 1;

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
    if (requestCode == PICK_IMAGE) {
        //TODO: action
    }
}

Tak nazywam galerię zdjęć. Włóż i sprawdź, czy to działa dla Ciebie.

EDYTOWAĆ:

Spowoduje to wyświetlenie aplikacji Dokumenty. Aby umożliwić użytkownikowi korzystanie z dowolnych zainstalowanych aplikacji galerii:

    Intent getIntent = new Intent(Intent.ACTION_GET_CONTENT);
    getIntent.setType("image/*");

    Intent pickIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    pickIntent.setType("image/*");

    Intent chooserIntent = Intent.createChooser(getIntent, "Select Image");
    chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] {pickIntent});

    startActivityForResult(chooserIntent, PICK_IMAGE);

6
Dostaję 2 opcje w tym „systemie Android”, „Dokumentach”. Jeśli wybiorę system Android, wyświetli mi się Galeria i zdjęcia. Jak pozbyć się tej pośredniej listy opcji?
Uday,

4
@Uday to po prostu dlatego, że nie ustawiłeś domyślnego. Po prostu zostaw to :)
Tristan Wiley

13
Na co należy ustawić stałą PICK_IMAGE? Napis „Nie można rozwiązać symbolu” PICK_IMAGE ”
Michael

3
@Michael, stała PICK_IMAGE przechowuje dowolną ustaloną przez ciebie statyczną wartość int w tej klasie, jest ona dalej używana w @Overridefunkcji onActivityResult(int requestCode, resultCode, Intent data), gdzie zalecane jest użycie tej stałej do sprawdzenia requestCodeparametru przed wykonaniem jakiejkolwiek akcji :)
Gabriel Checchia Vitali

Możesz pobrać mapę bitową z metody onActivityResult (...) za pomocą następującego kodu (przy założeniu RESULT_OK): Bitmap bitmap = data.getExtras (). GetParcelable ("data");
Shn_Android_Dev

196

Czasami nie można pobrać pliku z wybranego obrazu. To dlatego, że wybrany pochodzi z Google+, Dysk, Dropbox lub dowolnego innego dostawcy.

Najlepszym rozwiązaniem jest poproszenie systemu o wybranie treści przez Intent.ACTION_GET_CONTENT i uzyskanie wyniku od dostawcy treści.

Możesz postępować zgodnie z poniższym kodem lub spojrzeć na moją zaktualizowaną treść .

public void pickImage() {
  Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
  intent.setType("image/*");
  startActivityForResult(intent, PICK_PHOTO_FOR_AVATAR);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == PICK_PHOTO_FOR_AVATAR && resultCode == Activity.RESULT_OK) {
        if (data == null) {
            //Display an error
            return;
        }
        InputStream inputStream = context.getContentResolver().openInputStream(data.getData());
        //Now you can do whatever you want with your inpustream, save it as file, upload to a server, decode a bitmap...
    }
}

14
if(resultCode == Activity.RESULT_OK) {...}może być użyty do wykrycia sukcesu / anulowania
Thamme Gowda

Jak zdobyć ścieżkę?
wyślij

@delive, myślę, że możesz spróbować new File(data.getData()).getAbsolutePath()Tylko zgadnij, nie próbowałem
ktoś gdzieś

1
FileNotFound ostrzeżenie o wyjątku od Android Studio we fragmencie w getActivity().getContentResolver().openInputStream(data.getData());.
Iqbal

1
Działa to na niektórych urządzeniach, w których ścieżka pliku nie jest zwracana. Nie widzę jednak sposobu, aby określić - kiedy już mam InputStream - jak ustalić orientację obrazu.
Casey Perkins,

30
public void FromCamera() {

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


}

Dziękuję Ci bardzo. Ta odpowiedź pomogła mi załadować obraz później
Rosário Pereira Fernandes,

Chyba masz na myśli przypadek 1: zamiast przypadku -1: w przełączniku OnActivityResult.
Mathias

wiem, że jest to pytanie newibe, ale dlaczego to wszystko zrobiliśmy, aby uzyskać ścieżkę obrazu, co zwraca data.getData?
moumenShobakey

Jaka jest wartość path? inFile file = new File(path);
Ravi Vaniya

23

Możesz użyć tej metody, aby wybrać obraz z galerii. Wyświetlane będą tylko obrazy.

public void pickImage() {
    Intent intent = new Intent(Intent.ACTION_PICK,
            MediaStore.Images.Media.INTERNAL_CONTENT_URI);
    intent.setType("image/*");
    intent.putExtra("crop", "true");
    intent.putExtra("scale", true);
    intent.putExtra("outputX", 256);
    intent.putExtra("outputY", 256);
    intent.putExtra("aspectX", 1);
    intent.putExtra("aspectY", 1);
    intent.putExtra("return-data", true);
    startActivityForResult(intent, 1);
}

i zastąp parametr onActivityResult as

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode != RESULT_OK) {
            return;
        }
        if (requestCode == 1) {
            final Bundle extras = data.getExtras();
            if (extras != null) {
                //Get image
                Bitmap newProfilePic = extras.getParcelable("data");
            }
        }
    }

2
@Abhishek ... gdzie znalazłeś listę dodatków dozwolonych w celu ACTION_PICK? Dzięki!
Johnny Wu

1
Nie zapomnij dodać uprawnień środowiska wykonawczego dla READ_EXTERNAL_STORAGE i WRITE_EXTERNAL_STORAGE dla interfejsu API na poziomie 23 i wyższym. W przeciwnym razie bitmapa może nie zostać pobrana z galerii, ponieważ nie jest zerowa. Zobacz stackoverflow.com/a/35285667/3341089
oguzhan

1
Wywołanie setType po ustawieniu identyfikatora URI wyczyści dane.
Taslim Oseni

11

Oto pełny przykład pozwolenia na żądanie (w razie potrzeby), wybierz obraz z galerii, a następnie przekonwertuj obraz na bitmaplubfile

AndroidManifesh.xml

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

Czynność

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        button_pick_image.setOnClickListener {
            pickImage()
        }
    }

    private fun pickImage() {
        if (ActivityCompat.checkSelfPermission(this, READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
            val intent = Intent(
                Intent.ACTION_PICK,
                MediaStore.Images.Media.INTERNAL_CONTENT_URI
            )
            intent.type = "image/*"
            intent.putExtra("crop", "true")
            intent.putExtra("scale", true)
            intent.putExtra("aspectX", 16)
            intent.putExtra("aspectY", 9)
            startActivityForResult(intent, PICK_IMAGE_REQUEST_CODE)
        } else {
            ActivityCompat.requestPermissions(
                this,
                arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
                READ_EXTERNAL_STORAGE_REQUEST_CODE
            )
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == PICK_IMAGE_REQUEST_CODE) {
            if (resultCode != Activity.RESULT_OK) {
                return
            }
            val uri = data?.data
            if (uri != null) {
                val imageFile = uriToImageFile(uri)
                // todo do something with file
            }
            if (uri != null) {
                val imageBitmap = uriToBitmap(uri)
                // todo do something with bitmap
            }
        }
    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        when (requestCode) {
            READ_EXTERNAL_STORAGE_REQUEST_CODE -> {
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // pick image after request permission success
                    pickImage()
                }
            }
        }
    }

    private fun uriToImageFile(uri: Uri): File? {
        val filePathColumn = arrayOf(MediaStore.Images.Media.DATA)
        val cursor = contentResolver.query(uri, filePathColumn, null, null, null)
        if (cursor != null) {
            if (cursor.moveToFirst()) {
                val columnIndex = cursor.getColumnIndex(filePathColumn[0])
                val filePath = cursor.getString(columnIndex)
                cursor.close()
                return File(filePath)
            }
            cursor.close()
        }
        return null
    }

    private fun uriToBitmap(uri: Uri): Bitmap {
        return MediaStore.Images.Media.getBitmap(this.contentResolver, uri)
    }

    companion object {
        const val PICK_IMAGE_REQUEST_CODE = 1000
        const val READ_EXTERNAL_STORAGE_REQUEST_CODE = 1001
    }
}

Demo
https://github.com/PhanVanLinh/AndroidPickImage


To nic innego jak biblioteka, szczególnie z tą funkcją przycinania i proporcji. Nigdy nie wiedziałem, że coś takiego istnieje. Dziękuję Panu bardzo.
Lalit Fauzdar

1
Wracając tutaj, nie jest tak dobrze, jak miałem nadzieję zobaczyć pierwsze wrażenia. Nie wybiera obrazu po edycji snapseed, nie ma awarii, ale nie ma obrazu, domyślna aplikacja galerii Huawei nic nie robi, gdy kliknę przycisk Dalej po edycji, nie edytuje obrazu po wybraniu ze zdjęć Google, przywróć go z powrotem bez tego bezpośrednio. Działa dobrze tylko wtedy, gdy wybiorę domyślną galerię Huawei i zdjęcia Google do edycji.
Lalit Fauzdar


1

Aby zaoferować aktualizację odpowiedzi dla osób z API min. 19, zgodnie z dokumentami:

W Androidzie 4.4 (poziom interfejsu API 19) i nowszym masz dodatkową opcję korzystania z zamiaru ACTION_OPEN_DOCUMENT, który wyświetla kontrolowany przez system kontroler interfejsu wyboru, który pozwala użytkownikowi przeglądać wszystkie pliki udostępnione przez inne aplikacje. Z tego pojedynczego interfejsu użytkownika użytkownik może wybrać plik z dowolnej obsługiwanej aplikacji.

W Androidzie 5.0 (interfejs API na poziomie 21) i wyższym możesz również użyć zamiaru ACTION_OPEN_DOCUMENT_TREE, który pozwala użytkownikowi wybrać katalog, do którego ma uzyskać dostęp aplikacja kliencka.

Otwórz pliki za pomocą struktury dostępu do pamięci - Dokumenty Android

     val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
     intent.type = "image/*"
     startActivityForResult(intent, PICK_IMAGE_REQUEST_CODE)

0

Aby wybrać tylko z lokalnego, dodaj to:

        i.putExtra(Intent.EXTRA_LOCAL_ONLY,true)

A to działa dobrze:

    val i = Intent(Intent.ACTION_GET_CONTENT,MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
    i.type = "image/*"
    i.putExtra(Intent.EXTRA_LOCAL_ONLY,true)
    startActivityForResult(Intent.createChooser(i,"Select Photo"),pickImageRequestCode)

-7

U możesz to zrobić łatwiej niż te odpowiedzi:

Uri Selected_Image_Uri = data.getData();
ImageView imageView = (ImageView) findViewById(R.id.loadedimg);
imageView.setImageURI(Selected_Image_Uri);

robię to i zadziałało. jeśli potrzebujesz użyć pliku, na przykład do wysłania na serwer, musisz użyć innych sposobów, ale tylko w celu załadowania obrazu do podglądu obrazu możesz zrobić to proste rozwiązanie.
Alireza Taghizadeh

5
Witamy w SO! Zamiast komentować własny post, możesz również edytować swój post. Jeśli twój komentarz ma wyjaśniać odpowiedź, to dlaczego nie umieścić go w samej odpowiedzi? Osobiście nie rozumiem, jak twoja (spóźniona) odpowiedź na to stare pytanie ma związek z tym pytaniem. Czy mogę zasugerować skoncentrowanie się najpierw na odpowiadaniu na pytania, na które nie ma jeszcze akceptowanej odpowiedzi?
por.

1
Nie mogę znaleźć pytań na Androida. jak mogę zobaczyć tylko pytania na Androida?
Alireza Taghizadeh

3
Proszę przeczytać strony pomocy. Ponadto komentarze nie dotyczą dyskusji na temat działania witryny, możesz używać czatów do dyskusji na żywo z innymi użytkownikami i możesz zadawać szczegółowe pytania na temat Meta (pomoc-> Meta)
cfi
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.