Android开发Android开发经验谈Android技术知识

Android上获取已安装app图标的Bitmap对象

2019-11-14  本文已影响0人  磐龍

需求

获取手机上已安装的所有app,列表展示。任意选择其中一个app,导出apk以及应用图标,其中图标保存到sd卡上。

遇到问题

一般的,获取到的应用图标是Drawable类型,保存到sd上,即要把drawable对象保存为一个图像文件。这里的Drawable图标其实是BitmapDrawable实例,所以我们可以得到图标的bitmap,

Bitmap iconBitmap = ((BitmapDrawable) drawable).getBitmap();

但是在android O(8.0)或更高android版本,运行会崩溃,提示Drawable图标是AdaptiveIconDrawable实例,所以代码中直接BitmapDrawable强转,就导致崩溃了。

解决

既然我们发现了这个问题,那我们就尝试去解决它。分两种情况:1、8.0及以上版本;2、8.0以下版本。
直接看代码,比较直观:

/**
     * drawable保存为图像文件
     *
     * @param drawable drawable资源
     * @param filePath 图像绝对路径
     * @param format   图像格式
     * @return true成功,false失败
     */
public static boolean drawableToFile(Drawable drawable, String filePath, Bitmap.CompressFormat format) {
        if (drawable == null) {
            return false;
        }
        try {
            File file = new File(filePath);
            if (file.exists()) {
                file.delete();
            }
            if (!file.exists()) {
                file.createNewFile();
            }
            FileOutputStream out = null;
            out = new FileOutputStream(file);
            Bitmap destBitmap = null;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {/8.0及以上版本
                if (drawable instanceof BitmapDrawable) {
                    destBitmap = ((BitmapDrawable) drawable).getBitmap();
                } else if (drawable instanceof AdaptiveIconDrawable) {
                    Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
                    Canvas canvas = new Canvas(bitmap);
                    drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
                    drawable.draw(canvas);
                    destBitmap = bitmap;
                }
            } else {//8.0以下版本
                destBitmap = ((BitmapDrawable) drawable).getBitmap();
            }
            if (destBitmap == null) {
                out.close();
                return false;
            }
            destBitmap.compress(format, 100, out);
            out.close();
            return true;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

总结

开发阶段的时候使用的调试手机版本是4.4的,华为P10 android9.0测试竟然也没有这个问题。所以除了版本校验外,还有drawable图标的实际类型,也要加以判断。

上一篇下一篇

猜你喜欢

热点阅读