android seleziona le immagini dalla galleria


197

Voglio creare un selettore immagini dalla galleria. Io uso il codice

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

Il mio problema è che in questa attività vengono visualizzati i file video. Esiste un modo per filtrare i file visualizzati in modo che nessun file video venga visualizzato in questa attività?


3
Questo articolo descrive bene come scegliere le immagini dalla galleria: androidbitmaps.blogspot.com/2015/04/…
Andy Res

C'è una domanda simile come te. stackoverflow.com/a/31382240/1835650
TeeTracker

Risposte:


346

Assolutamente. Prova questo:

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

Non dimenticare inoltre di creare la costante PICK_IMAGE , in modo da poter riconoscere quando l'utente torna dalla galleria di immagini Attività:

public static final int PICK_IMAGE = 1;

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

È così che chiamo la galleria di immagini. Inseriscilo e vedi se funziona per te.

MODIFICARE:

Questo fa apparire l'app Documenti. Per consentire all'utente di utilizzare anche qualsiasi app della galleria che potrebbe aver installato:

    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
Ottengo 2 opzioni su questo "Sistema Android", "Documenti". Se seleziono Sistema Android, allora mi presenta Galleria e Foto. Come posso eliminare questo elenco di opzioni intermedie?
Uday

4
@Uday è semplicemente perché non hai impostato il valore predefinito. Lascialo :)
Tristan Wiley,

13
A cosa deve essere impostata la costante PICK_IMAGE? Dice "Impossibile risolvere il simbolo" PICK_IMAGE "
Michael

3
@ Michael il PICK_IMAGE costante detiene alcun static int valore determinato da voi su questo molto di classe, questo è ulteriormente utilizzato sulla @Overridefunzione onActivityResult(int requestCode, resultCode, Intent data), dove è consigliabile utilizzare questa costante per controllare il requestCodeparametro prima di fare qualsiasi azione :)
Gabriel Checchia Vitali

È possibile recuperare Bitmap dal metodo onActivityResult (...) con il seguente codice (presupponendo RESULT_OK): Bitmap bitmap = data.getExtras (). GetParcelable ("data");
Shn_Android_Dev

197

A volte, non è possibile ottenere un file dall'immagine che si sceglie. È perché quello scelto proviene da Google+, Drive, Dropbox o qualsiasi altro fornitore.

La soluzione migliore è chiedere al sistema di scegliere un contenuto tramite Intent.ACTION_GET_CONTENT e ottenere il risultato con un fornitore di contenuti.

Puoi seguire il codice qui sotto o guardare il mio riassunto aggiornato .

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) {...}può essere utilizzato per rilevare successo / annullamento
Thamme Gowda

Come puoi ottenere il percorso?
consegna il

@delive, penso che potresti provare new File(data.getData()).getAbsolutePath()Solo una supposizione, non l'ho provato
Someone Somewhere

1
Avviso di eccezione FileNotFound da Android Studio in frammento in getActivity().getContentResolver().openInputStream(data.getData());.
Iqbal,

1
Funziona su alcuni dispositivi in ​​cui non viene restituito il percorso del file. Tuttavia, non vedo alcun modo per determinare - una volta che ho InputStream - come capire l'orientamento dell'immagine.
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);


}

Grazie mille. Questa risposta mi ha aiutato a caricare l'immagine in seguito
Rosário Pereira Fernandes,

Immagino tu intenda il caso 1: invece del caso -1: nello switch in OnActivityResult.
Mathias,

so che è una domanda newibe ma, perché abbiamo fatto tutto questo per ottenere il percorso dell'immagine, cosa restituisce data.getData?
MoumenShobakey,

qual è il valore di path? inFile file = new File(path);
Ravi Vaniya

23

Puoi usare questo metodo per selezionare l'immagine dalla galleria. Verranno visualizzate solo le immagini.

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

e sovrascrivi 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 ... dove hai trovato l'elenco degli extra consentiti per l'intenzione di ACTION_PICK? Grazie!
Johnny Wu,

1
Non dimenticare di aggiungere autorizzazioni di runtime per READ_EXTERNAL_STORAGE e WRITE_EXTERNAL_STORAGE per il livello API 23 e versioni successive. Altrimenti potresti non ottenere bitmap dalla galleria come non null. Vedere stackoverflow.com/a/35285667/3341089
oguzhan

1
La chiamata a setType dopo aver impostato l'URI cancellerà i dati.
Taslim Oseni,

11

Ecco un esempio completo per l'autorizzazione richiesta (se necessario), seleziona l'immagine dalla galleria, quindi converti l'immagine in bitmapofile

AndroidManifesh.xml

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

Attività

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


Questo non è altro che una libreria, in particolare con quella funzione di ritaglio e proporzioni. Non ho mai saputo che esistesse una cosa del genere. Grazie mille signore.
Lalit Fauzdar,

1
Di nuovo qui, non è così bello come speravo di vedere le prime impressioni. Non seleziona l'immagine quando viene modificata con snapseed, nessun arresto anomalo ma nessuna immagine, l'app predefinita della galleria di huawei non fa nulla quando clicco dopo dopo la modifica, non modifica l'immagine quando viene scelta da google foto, riportala indietro senza di essa direttamente. Funziona bene solo se scelgo la galleria predefinita di huawei e google foto per modificarlo.
Lalit Fauzdar,


2

Solo per offrire un aggiornamento alla risposta per le persone con API min 19, secondo i documenti:

Su Android 4.4 (livello API 19) e versioni successive, hai l'opzione aggiuntiva di utilizzare l'intento ACTION_OPEN_DOCUMENT, che visualizza un'interfaccia utente di selezione controllata dal sistema controllata che consente all'utente di sfogliare tutti i file resi disponibili da altre app. Da questa singola interfaccia utente, l'utente può scegliere un file da qualsiasi app supportata.

Su Android 5.0 (livello API 21) e versioni successive, puoi anche utilizzare l'intento ACTION_OPEN_DOCUMENT_TREE, che consente all'utente di scegliere una directory a cui accedere un'app client.

Apri i file utilizzando il framework di accesso all'archiviazione - Documenti Android

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

0

Per scegliere solo da locale aggiungi questo:

        i.putExtra(Intent.EXTRA_LOCAL_ONLY,true)

E questo funziona bene:

    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

Puoi farlo più facilmente di questa risposta:

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

lo faccio e ha funzionato. se hai bisogno di usare file per esempio per l'invio al server devi usare altri modi ma solo per caricare un'immagine in imageview puoi fare questa semplice soluzione.
Alireza Taghizadeh,

5
Benvenuti in SO! Invece di commentare il tuo post, puoi anche modificare il tuo post. Se il tuo commento dovrebbe spiegare la risposta, allora perché non inserirlo nella risposta stessa? Personalmente, non vedo come la tua risposta (tardiva) a questa vecchia domanda sia collegata alla domanda. Posso suggerire di concentrarsi prima sul rispondere alle domande, che non hanno ancora una risposta accettata?
cfi,

1
non riesco a trovare le domande Android. come posso vedere solo le domande Android?
Alireza Taghizadeh,

3
Si prega di leggere le pagine di aiuto. Inoltre, i commenti non sono per discussioni su come funziona il sito, puoi usare le chat room per discussioni dal vivo con altri utenti e puoi fare domande specifiche su Meta (aiuto-> Meta)
cfi
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.