Convert AdaptiveIconDrawable to Bitmap in Android O preview

后端 未结 2 1363
慢半拍i
慢半拍i 2020-12-03 11:36

With the new preview release yesterday I started to update my app to this version. Part of my app is to list installed applications with the associated icons.



        
相关标签:
2条回答
  • 2020-12-03 12:00

    We can achieve by following way,

    AppIconHelper.java

    public class AppIconHelper {
    
        public static Bitmap getAppIcon(PackageManager mPackageManager, String packageName) {
    
            if (Build.VERSION.SDK_INT >= 26) {
                return AppIconHelperV26.getAppIcon(mPackageManager, packageName);
            }
    
            try {
                Drawable drawable = mPackageManager.getApplicationIcon(packageName);
    
                return ((BitmapDrawable) drawable).getBitmap();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            return null;
        }
    }
    

    For device supporting Android O( >=26) we can call AppIconHelperV26 class to get the AppIcon, In this, if its drawable is AdaptiveIconDrawable, we are doing the following steps 1. Get the Foreground and Background drawable and create as Layer Drawable 2. Using Canvas we can convert the Layer drawable to Bitmap

    AppIconHelperV26.java

    public class AppIconHelperV26 {
    
        @RequiresApi(api = Build.VERSION_CODES.O)
        public static Bitmap getAppIcon(PackageManager mPackageManager, String packageName) {
    
            try {
                Drawable drawable = mPackageManager.getApplicationIcon(packageName);
    
                if (drawable instanceof BitmapDrawable) {
                    return ((BitmapDrawable) drawable).getBitmap();
                } else if (drawable instanceof AdaptiveIconDrawable) {
                    Drawable backgroundDr = ((AdaptiveIconDrawable) drawable).getBackground();
                    Drawable foregroundDr = ((AdaptiveIconDrawable) drawable).getForeground();
    
                    Drawable[] drr = new Drawable[2];
                    drr[0] = backgroundDr;
                    drr[1] = foregroundDr;
    
                    LayerDrawable layerDrawable = new LayerDrawable(drr);
    
                    int width = layerDrawable.getIntrinsicWidth();
                    int height = layerDrawable.getIntrinsicHeight();
    
                    Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    
                    Canvas canvas = new Canvas(bitmap);
    
                    layerDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
                    layerDrawable.draw(canvas);
    
                    return bitmap;
                }
            } catch (PackageManager.NameNotFoundException e) {
                e.printStackTrace();
            }
    
            return null;
        }
    }
    

    Now you can call AppIconHelper.getAppIcon to get the Bitmap,

    AppListAdapter.java

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        //... your code here
        Bitmap appIcon = AppIconHelper.getAppIcon(packageManager, packageName);
        imageView.setImageBitmap(appIcon);
    
    }
    
    0 讨论(0)
  • 2020-12-03 12:08

    This is much more universal solution:

    @NonNull
    private Bitmap getBitmapFromDrawable(@NonNull Drawable drawable) {
        final Bitmap bmp = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
        final Canvas canvas = new Canvas(bmp);
        drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
        drawable.draw(canvas);
        return bmp;
    }
    

    It will also render background in the system defined shape, if you don't want to use own.

    You can use it on any Drawable, so also for VectorDrawable. It will works also on BitmapDrawable, just getBitmap() will be more memory efficient.

    0 讨论(0)
提交回复
热议问题