Android adaptive icons and Cordova

Adaptive icons were introduced in Android 8 (API level 26). They allow you to define an icon as two parts - a background and foreground. This separation allows for more flexible resizing, as well as animation of app icons in certain launchers.

Icon sizes

Adaptive icons are 108dp in size. However, for the foreground, the safe area size is only 72dp in size. This is because many launchers will do some sort of animation when the icon is moved, which is achieved by moving the foreground of the icon around. I recommend still making the foreground image 108dp in size and just ensuring that its main content is contained within a 72dp square in its centre.

Screen Density Scaling Ratio Icon size Safe area
xxxhdpi 4 432x432 288x288
xxhdpi 3 324x324 216x216
xhdpi 2 216x216 144x144
hdpi 1.5 162x162 108x108
mdpi 1 108x108 72x54
ldpi 0.75 81x81 54x54

Generating adaptive icons with Photoshop

If you have your icon in a PSD file, you can use the Generate Image Assets feature to automatically generate the two layers for you.

The way this works is that every layer or group which has a name which is a file name will be automatically exported in the folder in which the PSD folder is located. For example, if you have a group called background.png, then this group will be exported as a separate PNG file every time you save the PSD. You can also comma-separate these values to export multiple files in different sizes, which is how we will do it for the adaptive icons.

Create two groups in your PSD, one with the icon background, and the other with the foreground. Then name the groups as below:

Background:

432x432 mipmap-xxxhdpi/bg.png, 324x324 mipmap-xxhdpi/bg.png, 216x216 mipmap-xhdpi/bg.png, 162x162 mipmap-hdpi/bg.png, 108x108 mipmap-mdpi/bg.png

Foreground:

432x432 mipmap-xxxhdpi/fg.png, 324x324 mipmap-xxhdpi/fg.png, 216x216 mipmap-xhdpi/fg.png, 162x162 mipmap-hdpi/fg.png, 108x108 mipmap-mdpi/fg.png

Now, enable asset generation by checking File > Generate > Image Assets. Photoshop will now generate the background and foreground PNGs every time your save the PSD.

Using with Cordova

The upcoming release of Cordova 9, which includes cordova-android@8, will include support for adaptive icons out of the box. But, until then, there is a quick way to use adaptive icons now without needing to upgrade.

As well as the background and foreground PNGs, we need to be able to tell Android how these fit together to make the adaptive icon. This is done using an XML file, which we’ll call icon.xml. The name is important, as by default Cordova names icons icon.png, so we can drop in this adaptive icon smoothly if we name it the same way.

Assuming your icons are in a folder called res, this should be saved to res/mipmap-anydpi-v26/icon.xml. The folder name is important. The anydpi part means that this XML file defines the icon for all screen densities. The v26 means that this should only be used for Android 8 (API level 26) and above, which is the version that added adaptive icons.

<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
	<background android:drawable="@mipmap/bg" />
	<foreground android:drawable="@mipmap/fg" />
</adaptive-icon>

This is the most basic form of the file. You can also set padding for the foreground if you want, but it should not be necessary for most cases.

Now that the icons are ready, we just need to get Cordova to copy them into our Android project. In your config.xml file, add these lines inside <platform name="android">. You should not remove your existing icons, as they will still be required for earlier versions of Android.

<resource-file src="res/mipmap-anydpi-v26/icon.xml" target="app/src/main/res/mipmap-anydpi-v26/icon.xml" />
<resource-file src="res/mipmap-ldpi/bg.png" target="app/src/main/res/mipmap-mdpi/bg.png" />
<resource-file src="res/mipmap-ldpi/fg.png" target="app/src/main/res/mipmap-mdpi/fg.png" />
<resource-file src="res/mipmap-mdpi/bg.png" target="app/src/main/res/mipmap-mdpi/bg.png" />
<resource-file src="res/mipmap-mdpi/fg.png" target="app/src/main/res/mipmap-mdpi/fg.png" />
<resource-file src="res/mipmap-hdpi/bg.png" target="app/src/main/res/mipmap-hdpi/bg.png" />
<resource-file src="res/mipmap-hdpi/fg.png" target="app/src/main/res/mipmap-hdpi/fg.png" />
<resource-file src="res/mipmap-xhdpi/bg.png" target="app/src/main/res/mipmap-xhdpi/bg.png" />
<resource-file src="res/mipmap-xhdpi/fg.png" target="app/src/main/res/mipmap-xhdpi/fg.png" />
<resource-file src="res/mipmap-xxhdpi/bg.png" target="app/src/main/res/mipmap-xxhdpi/bg.png" />
<resource-file src="res/mipmap-xxhdpi/fg.png" target="app/src/main/res/mipmap-xxhdpi/fg.png" />
<resource-file src="res/mipmap-xxxhdpi/bg.png" target="app/src/main/res/mipmap-xxxhdpi/bg.png" />
<resource-file src="res/mipmap-xxxhdpi/fg.png" target="app/src/main/res/mipmap-xxxhdpi/fg.png" />

Build your project using cordova build android, and that’s it!