Android recoger imágenes de la galería


197

Quiero crear un selector de imágenes desde la galería. Yo uso codigo

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

Mi problema es que en esta actividad se muestran los archivos de video. ¿Hay alguna forma de filtrar los archivos mostrados para que no se muestren archivos de video en esta actividad?


3
Este artículo describe muy bien cómo elegir imágenes de la galería: androidbitmaps.blogspot.com/2015/04/…
Andy Res

Hay una pregunta similar como tú. stackoverflow.com/a/31382240/1835650
TeeTracker

Respuestas:


347

Absolutamente. Prueba esto:

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

No olvide también crear la constante PICK_IMAGE , para que pueda reconocer cuando el usuario regrese de la galería de imágenes Actividad:

public static final int PICK_IMAGE = 1;

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

Así llamo a la galería de imágenes. Póngalo y vea si funciona para usted.

EDITAR:

Esto abre la aplicación Documentos. Para permitir que el usuario también use cualquier aplicación de galería que haya 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);

66
Tengo 2 opciones en este "Sistema Android", "Documentos". Si selecciono Sistema Android, entonces me presenta Galería y Fotos. ¿Cómo me deshago de esta lista de opciones intermedias?
Uday

44
@Uday es simplemente porque no ha establecido el valor predeterminado. Solo déjalo :)
Tristan Wiley

13
¿A qué se debe establecer la constante PICK_IMAGE? Dice "No se puede resolver el símbolo" PICK_IMAGE "
Michael

3
@Michael la constante PICK_IMAGE contiene cualquier valor int estático determinado por usted en esta misma clase, esto se usa más en la @Overridefunción onActivityResult(int requestCode, resultCode, Intent data), donde se recomienda que use esta constante para verificar el requestCodeparámetro antes de realizar cualquier acción :)
Gabriel Checchia Vitali

Puede recuperar el mapa de bits del método onActivityResult (...) con el siguiente código (suponiendo RESULT_OK): mapa de bits mapa de bits = data.getExtras (). GetParcelable ("data");
Shn_Android_Dev

197

A veces, no puede obtener un archivo de la imagen que elija. Es porque el elegido vino de Google+, Drive, Dropbox o cualquier otro proveedor.

La mejor solución es pedirle al sistema que elija un contenido a través de Intent.ACTION_GET_CONTENT y obtenga el resultado con un proveedor de contenido.

Puede seguir el código a continuación o mirar mi esencia actualizada .

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) {...}puede usarse para detectar el éxito / cancelar
Thamme Gowda

¿Cómo puedes conseguir el camino?
entrega

@delive, creo que podrías intentar new File(data.getData()).getAbsolutePath()Solo una suposición, no lo he intentado
Someone Somewhere

1
Advertencia de excepción FileNotFound de Android Studio en fragmento en getActivity().getContentResolver().openInputStream(data.getData());.
Iqbal

1
Esto funciona en ciertos dispositivos en los que no se devuelve la ruta del archivo. Sin embargo, no veo forma de determinar, una vez que tengo el InputStream, cómo averiguar la orientación de la imagen.
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);


}

Muchas gracias. Esta respuesta me ayudó a subir la imagen más tarde
Rosário Pereira Fernandes

Supongo que te refieres al caso 1: en lugar del caso -1: en el interruptor en OnActivityResult.
Mathias

Sé que es una pregunta nueva pero, ¿por qué hicimos todo esto para obtener la ruta de la imagen? ¿Qué devuelve data.getData?
moumenShobakey

¿Cuál es el valor de path? enFile file = new File(path);
Ravi Vaniya

23

Puede usar este método para elegir una imagen de la galería. Solo se mostrarán las imágenes.

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

y anular 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 ... ¿dónde encontraste la lista de extras permitidos para la intención ACTION_PICK? ¡Gracias!
Johnny Wu

1
No olvide agregar permisos de tiempo de ejecución para READ_EXTERNAL_STORAGE y WRITE_EXTERNAL_STORAGE para el nivel de API 23 y superior. De lo contrario, es posible que no obtenga un mapa de bits de la galería porque no es nulo. Ver stackoverflow.com/a/35285667/3341089
oguzhan

1
Llamar a setType después de configurar URI borrará los datos.
Taslim Oseni

11

Aquí está un ejemplo completo para la solicitud de autorización (si es necesario), recoger la imagen de la galería, a continuación, convertir la imagen a bitmapofile

AndroidManifesh.xml

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

Actividad

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


Esto es nada menos que una biblioteca, especialmente con esa característica de recorte y relación de aspecto. Nunca supe que tal cosa existía. Muchas gracias señor.
Lalit Fauzdar

1
De vuelta aquí, no es tan bueno como esperaba ver las primeras impresiones. No selecciona la imagen cuando se edita con snapseed, sin bloqueo pero sin imagen, la aplicación de la galería predeterminada de Huawei no hace nada cuando hago clic en Siguiente después de editar, no edita la imagen cuando se selecciona de Google Photos, tráigala de vuelta sin ella directamente. Funciona bien solo si elijo la galería predeterminada de huawei y las fotos de google para editarla.
Lalit Fauzdar


2

Solo para ofrecer una actualización de la respuesta para personas con API min 19, según los documentos:

En Android 4.4 (API nivel 19) y superior, tiene la opción adicional de usar la intención ACTION_OPEN_DOCUMENT, que muestra una interfaz de usuario de selector controlada por el sistema controlada que permite al usuario explorar todos los archivos que otras aplicaciones han puesto a disposición. Desde esta única interfaz de usuario, el usuario puede elegir un archivo de cualquiera de las aplicaciones compatibles.

En Android 5.0 (API nivel 21) y superior, también puede usar la intención ACTION_OPEN_DOCUMENT_TREE, que permite al usuario elegir un directorio para acceder a una aplicación cliente.

Abrir archivos usando el marco de acceso de almacenamiento - Android Docs

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

0

Para elegir solo de local, agregue esto:

        i.putExtra(Intent.EXTRA_LOCAL_ONLY,true)

Y esto funciona bien:

    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 puede hacerlo más fácil de lo que esto responde:

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

Lo hago y funcionó. si necesita usar para archivar, por ejemplo, para enviar al servidor, debe usar otras formas, pero solo para cargar una imagen en la vista de imagen puede hacer esta solución fácil.
Alireza Taghizadeh

55
Bienvenido a SO! En lugar de comentar tu propia publicación, también puedes editarla. Si se supone que su comentario explica la respuesta, ¿por qué no ponerlo en la respuesta misma? Personalmente, no veo cómo su respuesta (tardía) a esta vieja pregunta está relacionada con la pregunta. ¿Puedo sugerir que primero se concentre en responder preguntas que aún no tienen una respuesta aceptada?
cfi

1
No puedo encontrar preguntas de Android. ¿Cómo puedo ver solo las preguntas de Android?
Alireza Taghizadeh

3
Por favor lea las páginas de ayuda. Además, los comentarios no son para discusiones sobre cómo funciona el sitio, puede usar salas de chat para discusiones en vivo con otros usuarios, y puede hacer preguntas específicas sobre Meta (ayuda-> Meta)
cfi
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.