如何从 Api 级别 30 中的 imageUri 获取位图?

gul*_*tel 2 android bitmap

我在旧版本中使用 getBitmap 方法,但我无法从 Uri 中找到 getBitmap 的任何替代方法。

        try {
            bitmap = MediaStore.Images.Media.getBitmap(contentResolver, imageUri);
        } catch (IOException e) {
            e.printStackTrace();
        }
Run Code Online (Sandbox Code Playgroud)

现在我从 android 指南中找到了另一种方法,但这仍然不起作用。我不知道如何在工作线程中执行此方法。Guide 说这个方法应该在工作线程中运行。任何人都可以帮助我如何做到这一点?

        try {
            bitmap = ImageDecoder.decodeBitmap(ImageDecoder.createSource(contentResolver, imageUri));
        } catch (IOException e) {
            e.printStackTrace();
        }
Run Code Online (Sandbox Code Playgroud)

我创建了一个简单的类来从 imageUri 获取位图。这里是。

public class 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){
            return null;
        }

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

Run Code Online (Sandbox Code Playgroud)

HB.*_*HB. 6

看看文档

此方法在 API 级别 29 中已弃用。图像的加载应通过 ImageDecoder#createSource(ContentResolver, Uri) 执行,它提供后处理器等现代功能。

所以你必须使用ImageDecoder.createSource,像这样:

Bitmap bitmap = null;
ContentResolver contentResolver = getContentResolver(); 
try {
    if(Build.VERSION.SDK_INT < 28) {
        bitmap = MediaStore.Images.Media.getBitmap(contentResolver, imageUri);
    } else {
        ImageDecoder.Source source = ImageDecoder.createSource(contentResolver, imageUri);
        bitmap = ImageDecoder.decodeBitmap(source);
    }
} catch (Exception e) {
    e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)

以上应该是线程安全的。