android escolher imagens da galeria


197

Quero criar um seletor de imagens da galeria. Eu uso código

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

Meu problema é que nesta atividade e os arquivos de vídeo são exibidos. Existe uma maneira de filtrar os arquivos exibidos para que nenhum arquivo de vídeo seja exibido nesta atividade?


3
Este artigo descreve bem como escolher imagens da galeria: androidbitmaps.blogspot.com/2015/04/…
Andy Res

Há uma pergunta semelhante como você. stackoverflow.com/a/31382240/1835650
TeeTracker

Respostas:


346

Absolutamente. Tente o seguinte:

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

Não esqueça também de criar a constante PICK_IMAGE , para que você possa reconhecer quando o usuário voltar da galeria de imagens Atividade:

public static final int PICK_IMAGE = 1;

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

É assim que eu chamo a galeria de imagens. Coloque-o e veja se funciona para você.

EDITAR:

Isso abre o aplicativo Documentos. Para permitir que o usuário use também qualquer aplicativo de galeria que ele possa ter instalado:

    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
Eu recebo 2 opções neste "Sistema Android", "Documentos". Se eu selecionar o sistema Android, ele apresentará a Galeria e as fotos. Como faço para me livrar dessa lista de opções intermediárias?
Uday

4
@ Dia é simplesmente porque você não definiu o padrão. Apenas deixe :)
Tristan Wiley

13
O que a constante PICK_IMAGE deve ser definida? Ele diz: "Não é possível símbolo resolver 'PICK_IMAGE'
Michael

3
@ Michael o PICK_IMAGE constante detém qualquer static int valor determinado por você nesta mesma classe, este é ainda usado na @Overridefunção onActivityResult(int requestCode, resultCode, Intent data), onde é recomendado que você usar essa constante para verificar o requestCodeparâmetro antes de fazer qualquer ação :)
Gabriel Checchia Vitali

Você pode recuperar o Bitmap do método onActivityResult (...) com o seguinte código (assumindo RESULT_OK): Bitmap de bitmap = data.getExtras (). GetParcelable ("data");
21718 Shn_Android_Dev #

197

Às vezes, você não pode obter um arquivo da imagem que escolher. É porque o escolhido veio do Google+, Drive, Dropbox ou qualquer outro provedor.

A melhor solução é solicitar ao sistema que escolha um conteúdo via Intent.ACTION_GET_CONTENT e obtenha o resultado com um provedor de conteúdo.

Você pode seguir o código abaixo ou olhar para a minha essência atualizada .

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) {...}pode ser usado para detectar o sucesso / cancelar
Thamme Gowda

Como você pode encontrar o caminho?
delive

@delive, acho que você poderia tentar new File(data.getData()).getAbsolutePath()Apenas um palpite, eu ainda não tentei
Someone Somewhere

1
Aviso de exceção FileNotFound do Android Studio no fragmento getActivity().getContentResolver().openInputStream(data.getData());.
Iqbal 27/01

1
Isso funciona em certos dispositivos nos quais o caminho do arquivo não é retornado. No entanto, não vejo como determinar - depois de ter o InputStream - como descobrir a orientação da imagem.
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);


}

Muito obrigado. Esta resposta me ajudou a carregar a imagem mais tarde
Rosário Pereira Fernandes

Acho que você quer dizer o caso 1: em vez do caso -1: no comutador no OnActivityResult.
Mathias

Eu sei que é uma pergunta newibe, mas, por que fizemos tudo isso para obter o caminho da imagem, o que data.getData retorna então?
moumenShobakey

qual é o valor de path? emFile file = new File(path);
Ravi Vaniya 03/03

23

Você pode usar esse método para escolher uma imagem da galeria. Somente imagens serão exibidas.

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 substitua onActivityResult como

    @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 ... onde você encontrou a lista de extras permitidos para a intenção de ACTION_PICK? Obrigado!
Johnny Wu

1
Não se esqueça de adicionar permissões de tempo de execução para READ_EXTERNAL_STORAGE e WRITE_EXTERNAL_STORAGE para API nível 23 e superior. Caso contrário, você não poderá obter o bitmap da galeria como não nulo. Veja stackoverflow.com/a/35285667/3341089
oguzhan

1
Chamar setType após definir o URI limpará os dados.
Taslim Oseni 28/02

11

Aqui está um exemplo completo para solicitar permissão (se necessário), escolher uma imagem da galeria e converter a imagem em bitmapoufile

AndroidManifesh.xml

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

Atividade

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


Isso é nada menos que uma biblioteca, especialmente com esse recurso de corte e proporção. Eu nunca soube que tal coisa existia. Muito obrigado, senhor.
Lalit Fauzdar

1
De volta aqui, não é tão bom quanto eu esperava ver as primeiras impressões. Ele não seleciona a imagem quando editada com snapseed, nenhuma falha, mas nenhuma imagem, o aplicativo de galeria padrão da huawei não faz nada quando eu clico no próximo após a edição, ele não edita a imagem quando escolhido no google photos, traga-o de volta sem ele diretamente. Funciona bem apenas se eu escolher a galeria padrão do huawei e o google fotos para editá-lo.
Lalit Fauzdar


2

Apenas para oferecer uma atualização da resposta para pessoas com API min 19, de acordo com os documentos:

No Android 4.4 (API nível 19) e superior, você tem a opção adicional de usar a intenção ACTION_OPEN_DOCUMENT, que exibe uma interface do usuário do selecionador controlado pelo sistema, que permite ao usuário procurar todos os arquivos que outros aplicativos disponibilizaram. Nessa interface do usuário, o usuário pode escolher um arquivo em qualquer um dos aplicativos suportados.

No Android 5.0 (nível 21 da API) e superior, você também pode usar a intenção ACTION_OPEN_DOCUMENT_TREE, que permite ao usuário escolher um diretório para o acesso a um aplicativo cliente.

Abrir arquivos usando a estrutura de acesso ao armazenamento - Android Docs

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

0

Para escolher apenas local, adicione:

        i.putExtra(Intent.EXTRA_LOCAL_ONLY,true)

E isso está funcionando bem:

    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

Você pode fazer isso mais facilmente do que estas respostas:

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

eu faço e funcionou. se você precisar usar o arquivo, por exemplo, para enviar para o servidor, precisará usar outras maneiras, mas apenas para carregar uma imagem na visualização de imagem, você pode fazer essa solução fácil.
Alireza Taghizadeh

5
Bem-vindo ao SO! Em vez de comentar sua própria postagem, você também pode editá-la. Se o seu comentário deve explicar a resposta, por que não colocá-lo na resposta? Pessoalmente, não vejo como a sua resposta (tardia) a essa pergunta antiga está relacionada à pergunta. Posso sugerir que você se concentre em responder às perguntas primeiro, que ainda não têm uma resposta aceita?
Cfi

1
Não consigo encontrar perguntas sobre o Android. como posso ver apenas as perguntas do android?
Alireza Taghizadeh 31/10/2015

3
Por favor, leia as páginas de ajuda. Além disso, os comentários não são para discussões sobre como funciona o site, você pode usar salas de chat para discussões ao vivo com outros usuários, e você pode fazer perguntas específicas sobre Meta (Ajuda-> Meta)
TPI
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.