48

My onActivityResult is not working because getBitmap is deprecated. Is there any alternative code to achieve this?

Here is the code that needs to be changed (any suggestions?):

val bitmap = MediaStore.Images.Media.getBitmap(contentResolver, selectedPhotoUri)

The getBitmap is crossed out in my tooling with a message that says it's deprecated.

starball
  • 20,030
  • 7
  • 43
  • 238
jaedster medina
  • 589
  • 1
  • 4
  • 7
  • 4
    Being deprecated doesn't mean "doesn't work", it means that the function will be removed in a later release but it is still usable. – htafoya Sep 28 '20 at 20:04

14 Answers14

45

This worked for me,

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        if(requestCode == 1 && resultCode == Activity.RESULT_OK && data != null) {

            val selectedPhotoUri = data.data
            try {
                selectedPhotoUri?.let {
                    if(Build.VERSION.SDK_INT < 28) {
                        val bitmap = MediaStore.Images.Media.getBitmap(
                            this.contentResolver,
                            selectedPhotoUri
                        )
                        imageView.setImageBitmap(bitmap)
                    } else {
                        val source = ImageDecoder.createSource(this.contentResolver, selectedPhotoUri)
                        val bitmap = ImageDecoder.decodeBitmap(source) { decoder, _, _ ->
                            decoder.setTargetSampleSize(1) // shrinking by
                            decoder.isMutableRequired = true // this resolve the hardware type of bitmap problem
                        }
                        imageView.setImageBitmap(bitmap)
                    }
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }
sarkiroka
  • 1,485
  • 20
  • 28
Ally
  • 783
  • 6
  • 14
  • 5
    it gives me result as unexpected error unsupported bitmap configuration : "Hardware" – Rishav Singla Mar 13 '20 at 12:10
  • 2
    MediaStore.Images.Media.getBitmap( contentResolver,uri) is also depricated. :( – Rohit Singh Aug 15 '20 at 03:05
  • 2
    Rishav Singla, use this line of code. imageBitmap = imageBitmap.copy(Bitmap.Config.ARGB_8888, true); – Deepak Gautam Nov 11 '20 at 04:01
  • 1
    This method was deprecated in API level 29, [official doc](https://developer.android.com/reference/android/provider/MediaStore.Images.Media.html#getBitmap(android.content.ContentResolver,%2520android.net.Uri)). Why You use `if(Build.VERSION.SDK_INT < 28)`? – Bokili Production Apr 08 '21 at 13:57
  • It requires API level 28, for lower API use the old way – d-feverx Apr 12 '21 at 15:40
  • It seems to me that using older `Media.getBitmap` requires you to rotate the image based on EXIF data whereas using `ImageDecoder.decodeBitmap` does not! I can't find anything in docs to reflect this but have tried on a couple of devices. Anyone finding the same? – mrrrk Jun 11 '21 at 07:28
22

This worked well for me in java

ImageDecoder.Source source = ImageDecoder.createSource(this.getContentResolver(), pictureUri);
Bitmap bitmap = ImageDecoder.decodeBitmap(source);
davincia
  • 229
  • 2
  • 2
  • 8
    It requires API level 28, what about older API levels? – Ahmed Maad Apr 08 '20 at 22:46
  • you can do it like this if (Build.VERSION.SDK_INT >= 29) { val source = ImageDecoder.createSource(it.contentResolver, documentUri) ImageDecoder.decodeBitmap(source) } else { MediaStore.Images.Media.getBitmap(it.contentResolver, documentUri) } – Sikander Bakht Jan 26 '21 at 17:57
20

You can use:

private fun getCapturedImage(selectedPhotoUri: Uri): Bitmap {
    val bitmap = when {
    Build.VERSION.SDK_INT < 28 -> MediaStore.Images.Media.getBitmap(
        this.contentResolver,
        selectedPhotoUri
    )
    else -> {
        val source = ImageDecoder.createSource(this.contentResolver, selectedPhotoUri)
        ImageDecoder.decodeBitmap(source)
    }
}
Willi Mentzel
  • 27,862
  • 20
  • 113
  • 121
Hasan A Yousef
  • 22,789
  • 24
  • 132
  • 203
10

Check the official doc:

This method was deprecated in API level 29. loading of images should be performed through ImageDecoder#createSource(ContentResolver, Uri), which offers modern features like PostProcessor.

Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
  • thanks! any suggestions on how i can use that to my existing code? – jaedster medina Jun 18 '19 at 14:43
  • 1
    @jaedstermedina the method is deprecated not removed. The alternative is the method reported in the answer. It is not related to the version of gradle or the plugin for android, it is related to adoption of api 29. – Gabriele Mariotti Jun 18 '19 at 14:45
6

It was evident that the getBitmap API doesn't work with the latest Android SDK - 29. So, this worked for me

Uri contentURI = data.getData();
try {
    imageView.setImageURI(contentURI);
} catch (Exception e) {
    e.printStackTrace();
}

Please let me know if this doesn't work for any of you, shall other options!

Aashish Chaubey
  • 589
  • 1
  • 8
  • 22
6

You can use this code for creating bitmap

Bitmap bitmap;
if (Build.VERSION.SDK_INT >= 29) {
     ImageDecoder.Source source = ImageDecoder.createSource(getApplicationContext().getContentResolver(), imageUri);
     try {
         bitmap = ImageDecoder.decodeBitmap(source);
     } catch (IOException e) {
         e.printStackTrace();
     }
} else {
     try {
     bitmap = MediaStore.Images.Media.getBitmap(getApplicationContext().getContentResolver(), imageUri);
     } catch (IOException e) {
          e.printStackTrace();
     }
}
Kasım Özdemir
  • 5,414
  • 3
  • 18
  • 35
Asad Mehmood
  • 341
  • 2
  • 12
3

I have created a class for loading a Bitmap from uri:

public class BitmapResolver {
    private final static String TAG = "BitmapResolver";

    @SuppressWarnings("deprecation")
    private static Bitmap getBitmapLegacy(@NonNull ContentResolver contentResolver, @NonNull Uri fileUri){
        Bitmap bitmap = null;

        try {
            bitmap = MediaStore.Images.Media.getBitmap(contentResolver, fileUri);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return bitmap;
    }

    @TargetApi(Build.VERSION_CODES.P)
    private static Bitmap getBitmapImageDecoder(@NonNull ContentResolver contentResolver, @NonNull Uri fileUri){
        Bitmap bitmap = null;

        try {
            bitmap = ImageDecoder.decodeBitmap(ImageDecoder.createSource(contentResolver, fileUri));
        } catch (IOException e) {
            e.printStackTrace();
        }

        return bitmap;
    }

    public static Bitmap getBitmap(@NonNull ContentResolver contentResolver, Uri fileUri){
        if (fileUri == null){
            Log.i(TAG, "returning null because URI was null");
            return null;
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P){
            return getBitmapImageDecoder(contentResolver, fileUri);
        } else{
            return getBitmapLegacy(contentResolver, fileUri);
        }
    }
   }

Just to save you some time ...

t7bdh3hdhb
  • 438
  • 3
  • 15
1

For anyone getting unsupported bitmap configuration : "Hardware" error or you need mutable bitmap for Canvas or reading pixels use this

ImageDecoder.decodeBitmap(
    ImageDecoder.createSource(context.contentResolver, uri)
) { decoder, info, source ->
    decoder.allocator = ImageDecoder.ALLOCATOR_SOFTWARE
    decoder.isMutableRequired = true
}
Thracian
  • 43,021
  • 16
  • 133
  • 222
0

ImageDecoder.createSource(this.getContentResolver(), pictureUri)

works fine, but to be able to use this code, mindSdkVersion should be at least 28.

-1

Have you tried this?

val bitmap = ImageDecoder.createSource(contentResolver, uri)

-1

hi freind you check api device

var Image_select: String? = null
var bitmap:Bitmap?=null

you show image set

binding?.ImAvator?.setImageURI(data!!.data)


 try {
                    val uri: Uri? = data!!.data
                    bitmap = if(Build.VERSION.SDK_INT>=29){
                        val source: ImageDecoder.Source = ImageDecoder.createSource(requireActivity()
                            .contentResolver, uri!!)
                        ImageDecoder.decodeBitmap(source)
                    } else{
                        MediaStore.Images.Media.getBitmap(requireActivity().contentResolver, uri!!)
                    }
               

                } catch (e: IOException) {
                    e.printStackTrace()
                }

when upload image

compress bitmap send server

 fun Camparse() {
        val size = (bitmap!!.height * (812.0 / bitmap!!.width)).toInt()
        val b = Bitmap.createScaledBitmap(bitmap!!, 812, size, true)
        val by = ByteArrayOutputStream()
        b.compress(Bitmap.CompressFormat.JPEG, 100, by)
        val bytes = by.toByteArray()
        Image_select = Base64.encodeToString(bytes, 0)
    }
developerjavad
  • 315
  • 1
  • 2
  • 10
-1

For deprecated MediaStore.Images.Media.getBitmap() in API level 29, You can use this code:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(resultCode == Activity.RESULT_OK) {
        if (requestCode == GALLERY_REQUEST) {
            Uri selectedImage = data.getData();
            try {
                if (Build.VERSION.SDK_INT < 29) {
                    Bitmap bitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), selectedImage);
                    imageView2.setImageBitmap(bitmap);
                } else {
                    ImageDecoder.Source source = ImageDecoder.createSource(getActivity().getContentResolver(), selectedImage);
                    Bitmap bitmap = ImageDecoder.decodeBitmap(source);
                    imageView2.setImageBitmap(bitmap);
                }
            } catch (IOException e) {
                Toast.makeText(getContext(), R.string.error_read_image, Toast.LENGTH_LONG).show();
            }
        }
    }
}

Regards.

-1
if(result.resultCode == Activity.RESULT_OK && result.data != null {
binding?.ivImage?.setImageURI(result.data?.data)}
juan
  • 49
  • 2
-2

This code works for my case:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    try {
            when (requestCode) {

                //get the image with camera
                SECTIONCAMERA -> {
                    val imageBitmap = data?.extras?.get("data") as Bitmap
                  ImageView_imagePerfil.setImageBitmap(imageBitmap)

                }
                //get the image in gallery
                SECTIONGALLERY -> {
                    val imageUri = data?.data
                    ImageView_imagePerfil.setImageURI(imageUri) }
            }

    } catch (e: Exception){
             e.printStackTrace()
    }
}
Fabio Mendes Soares
  • 1,357
  • 5
  • 20
  • 30