Pojedynczy zamiar, aby pozwolić użytkownikowi zrobić zdjęcie lub wybrać zdjęcie z galerii w Androidzie

Rozwijam aplikację dla Androida 2.1 w górę. Chcę, aby moi użytkownicy mogli wybrać zdjęcie profilowe w mojej aplikacji (nie używam struktury kontaktów).

Idealnym rozwiązaniem byłoby uruchomienie intencji, która umożliwia użytkownikowi wybranie obrazu z galerii, ale jeśli odpowiedni obraz nie jest dostępny, użyj aparatu, aby zrobić zdjęcie (lub odwrotnie, tj. Galeria i wybierz zdjęcie).

Obecnie mogę zrobić jedno lub drugie, ale nie jedno i drugie.

Jeśli wejdę bezpośrednio w tryb kamery używając MediaStore.ACTION_IMAGE_CAPTURE wtedy nie ma opcji, aby wpaść do galerii.

Jeśli wejdę bezpośrednio do galerii używając intencji.ACTION_PICK następnie mogę wybrać obraz, ale jeśli kliknę przycisk aparatu (w prawym górnym rogu galerii) to zostanie wywołana Nowa intencja aparatu. Tak więc każde zdjęcie, które zostało zrobione, nie jest zwracane bezpośrednio do mojej aplikacji. (Oczywiście możesz nacisnąć przycisk Wstecz, aby wrócić do galerii i wybrać stamtąd obraz, ale jest to dodatkowy niepotrzebny krok i wcale nie jest intuicyjny).

Więc jest sposób, aby połączyć oba lub będę musiał zaoferować menu do zrobienia jednego lub drugiego z mojej aplikacji? Wydaje się, że byłby to powszechny przypadek użycia...na pewno coś przeoczyłem?

Author: Damian, 2010-04-25

4 answers

UPDATE : druga odpowiedź, używając EXTRA_INITIAL_INTENTS, jest lepsza w tym momencie. W czasie pisania mojej odpowiedzi, EXTRA_INITIAL_INTENTS jeszcze nie istnieje, ponieważ został dodany w API poziom 5.

Więc jest sposób, aby połączyć oba lub czy będę musiał zaoferować menu do czy jeden lub drugi z wewnątrz mojego podanie?

Napisz własną galerię, która ma funkcje, których pragniesz.

Myślę, że menu byłoby prostsze.

Wydaje się, że byłoby to wspólne użycie case...na pewno coś przeoczyłem?

Deweloper obok ciebie pomyśli, że Galeria powinna pozwolić Ci wybrać z lokalnej galerii lub wyskoczyć do Flickr, aby dokonać wyboru stamtąd. Inny programista pomyśli, że aparat powinien nie tylko pozwalać na" zrobienie zdjęcia "za pomocą aparatu, ale" zrobienie zdjęcia " poprzez wybranie czegoś z galerii, odwrócenie rzeczy od sposobu, w jaki to wyobrażasz. Kolejny deweloper pomyśli, że Galeria powinna umożliwiać wybieranie z lokalnej galerii, Flickr, kamery lub sieciowej kamery internetowej. Jeszcze inny programista pomyśli, że galeria jest głupia, a użytkownicy powinni po prostu wybierać pliki za pomocą eksploratora plików. I tak dalej.

Wszystko to w środowisku (telefony komórkowe), w którym flash dla systemu operacyjnego jest na wagę złota.

Stąd, IMHO, to nie jest całkowicie szokujące, że core Android zespół zdecydował się dostarczyć klocki do montażu, jak uważasz za stosowne, zamiast próbować pomieścić wszystkie możliwy wzór.

 13
Author: CommonsWare,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-25 11:37:12

Możesz spróbować zrobić coś takiego:

// ...
// Within your enclosing Class
// ...
private static final int SELECT_PICTURE = 1;

// ... 

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

Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

String pickTitle = "Select or take a new Picture"; // Or get from strings.xml
Intent chooserIntent = Intent.createChooser(pickIntent, pickTitle);
chooserIntent.putExtra
(
  Intent.EXTRA_INITIAL_INTENTS, 
  new Intent[] { takePhotoIntent }
);

startActivityForResult(chooserIntent, SELECT_PICTURE);

Aby zobaczyć, jak poradzić sobie z wynikiem działania, zapoznaj się z to pytanie


Uwaga: krytycznym punktem jest określenie, czy użyto kamery lub galerii. To jest pokazane w tym przykładzie kodu: https://stackoverflow.com/a/12347567/294884

 116
Author: Macarse,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:23

Możesz postępować w ten sposób w swojej aktywności:

private static final int REQUEST_CODE_PICTURE= 1;

    /**
     * Click on View to change photo. Sets into View of your layout, android:onClick="clickOnPhoto"
     * @param view View
     */
    public void clickOnPhoto(View view) {
        Intent pickIntent = new Intent();
        pickIntent.setType("image/*");
        pickIntent.setAction(Intent.ACTION_GET_CONTENT);
        Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        String pickTitle = "Take or select a photo";
        Intent chooserIntent = Intent.createChooser(pickIntent, pickTitle);
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] { takePhotoIntent });
        startActivityForResult(chooserIntent, REQUEST_CODE_PICTURE);
    }

Następnie dodaj zawsze w swojej aktywności metodę onActivityResult:

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_PICTURE && resultCode == Activity.RESULT_OK) {
            if (data == null) {
                return;
            }
            try {
                InputStream inputStream = getContentResolver().openInputStream(data.getData());
                Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                imgPhoto.setImageBitmap(bitmap);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
    }
 10
Author: Dario Bruzzese,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-11 09:03:24

Moja odpowiedź jest prawie identyczna z rozwiązaniem @Macarse, ale dodaję również dodatkowy zamiar wyświetlania aplikacji galerii (np.: Zdjęcia Google) i jest napisany w Kotlinie:

val REQUEST_CODE_GET_IMAGE = 101

private fun addProfileImage() {
    val pickImageFileIntent = Intent()
    pickImageFileIntent.type = "image/*"
    pickImageFileIntent.action = Intent.ACTION_GET_CONTENT

    val pickGalleryImageIntent = Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI)

    val captureCameraImageIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)

    val pickTitle = "Capture from camera or Select from gallery the Profile photo"
    val chooserIntent = Intent.createChooser(pickImageFileIntent, pickTitle)
    chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, arrayOf(captureCameraImageIntent, pickGalleryImageIntent))
    startActivityForResult(chooserIntent, REQUEST_CODE_GET_IMAGE)
}

Przykład bonusu:

private var imageTempFile: File? = null
private var imageMimeType: String? = null

private fun extractImage(intent: Intent?) {
    val imageUri = intent?.data
    imageUri?.let {
        Glide.with(this)
                .load(imageUri)
                .into(profileImageCiv)
        imageTempFile = MediaUtils.copyContentFromUriToCacheFile(this, imageUri, Settings.DIRECTORY_CACHE_TEMP_PROFILE_IMAGE)
        imageMimeType = MediaUtils.getMimeType(this, imageUri)
    } ?: run {
        intent?.extras?.get("data")?.let { bitmap ->    // Bitmap was returned as raw bitmap
            Glide.with(this)
                    .load(bitmap)
                    .into(profileImageCiv)
            imageTempFile = MediaUtils.writeBitmapToCacheFile(this, bitmap as Bitmap, Settings.DIRECTORY_CACHE_TEMP_PROFILE_IMAGE)
            imageMimeType = "image/jpeg"    // The bitmap was compressed as JPEG format. The bitmap itself doesn't have any format associated to it
        } ?: run {
            imageTempFile = null
            imageMimeType = null
            Log.e("Intent data is null.")
            Log.d("Error during photo selection")
        }
    }
}
 0
Author: vovahost,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-17 12:47:46