需求
获取手机上已安装的所有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图标的实际类型,也要加以判断。
网友评论