2

I'm attempting to save all of the icons of the packages on a device as a BMP or PNG file by iterating through each package and doing the following.

Drawable icon = getPackageManager().getApplicationIcon(packageInfo);
Bitmap bitmap = Bitmap.createBitmap(icon.getIntrinsicWidth(), icon.getIntrinsicHeight(), Config.ARGB_8888);

try {
     out = new FileOutputStream("/storage/sdcard0/images/" + packageInfo.packageName +".png");
     bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
} catch (Exception e) {
     e.printStackTrace();
} finally {
    try{
     out.close();
    } catch(Throwable ignore) {}
}

This is creating blank images though, how would I change my code to create the actual icon in an image format?

enter image description here

parameter
  • 894
  • 2
  • 18
  • 35
  • "But I just want the icon as an image the way it appears on the screen of a device" -- what does this mean? – CommonsWare Jul 18 '14 at 16:14
  • maybe I'm confused on what an 'icon' in Android terminology means, but I am hoping and assuming it is the image that represents an application, the image that is clicked on to launch an application. – parameter Jul 18 '14 at 16:16
  • 1
    And what for? To reuse them in some app of yours? Apart that `out = new FileOutputStream("/storage/sdcard0/images/" + packageInfo.packageName +".bmp");` contains an absolute path which isn't said to be found on every device. Then the extension is **bmp** (ridiculous on Android). Then you do `bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);`, so saving to the PNG format with the BMP extension and trying to compress in an uncompressed format (PNG and BMP are uncompressed)... I think it's a mess. – Phantômaxx Jul 18 '14 at 16:17
  • There are no icons in Android to launch an application, simply because you do not launch an application in Android. You launch an *activity* inside an application. An application may have zero, one, or several activities designed to be launched this way. – CommonsWare Jul 18 '14 at 16:18
  • @FrankN.Stein I'm just doing it this way for testing purposes currently, this is not how it will actually be implemented. I just want to see if I can get an image file of the Drawable icon for each android package. – parameter Jul 18 '14 at 16:29
  • Whatever files you found there, they don't have the .png extension. Add it. – 323go Jul 18 '14 at 16:47
  • Mind that there could be **different icons for different resolutions**. I think you'll get only the currently displayed resolution app icon. – Phantômaxx Jul 18 '14 at 16:48
  • @323go I tried and they're just black squares, will update image – parameter Jul 18 '14 at 16:48

2 Answers2

2

My issue was this if anyone has the same problem, I referenced this answer.

I forgot to check to see if the icon was already an instance of BitmapDrawable. Because it was I could just cast it to a bitmapdrawable and use .getBitmap

if (icon instanceof BitmapDrawable) {
    bitmap = ((BitmapDrawable)icon).getBitmap();
}else{
    bitmap = Bitmap.createBitmap(icon.getIntrinsicWidth(), icon.getIntrinsicHeight(), Config.ARGB_8888);
}
Community
  • 1
  • 1
user3509128
  • 142
  • 1
  • 10
  • Not a helpful answer with the question as it is. Nobody will find this, and it's technically a duplicate. – 323go Jul 20 '14 at 06:04
  • 1
    @323go how so? this portion of the code replaces the part where the bitmap is created. It solves the issue. – user3509128 Jul 21 '14 at 15:47
2

Below is the code that could cover all the cases.

public static Bitmap drawableToBitmap (Drawable drawable) {


    if (drawable instanceof BitmapDrawable) {
        BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
        if (bitmapDrawable.getBitmap() != null) {
            return bitmapDrawable.getBitmap();
        }
    }

    if (drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
        return Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); // Single color bitmap will be created of 1x1 pixel
    } else {
        return Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
    }

}
Adinia
  • 3,722
  • 5
  • 40
  • 58