[cordova] How to add app icon within phonegap projects?

I created a new phonegap (v 3.0.0-0.14.0) project with default config.xml and then added iOS and Android platforms.

The config contains all the paths to all platform icons.

I have overwritten the default icons for iOS and Android so that path and name still matches those pngs.

When running in simulator the icons don't show up. I have looked it up in xCode where it tells me that the "Resources" folder for the icons still contains the phonegap default icons. Same with Android.

What am I doing wrong?

How can I add custom app icons for iOS and Android with phonegap?

thanks

my config.xml

<icon src="icon.png" />

<icon gap:density="ldpi" gap:platform="android" src="res/icon/android/icon-36-ldpi.png" />
<icon gap:density="mdpi" gap:platform="android" src="res/icon/android/icon-48-mdpi.png" />
<icon gap:density="hdpi" gap:platform="android" src="res/icon/android/icon-72-hdpi.png" />
<icon gap:density="xhdpi" gap:platform="android" src="res/icon/android/icon-96-xhdpi.png" />

<icon gap:platform="ios" height="57" src="res/icon/ios/icon-57.png" width="57" />
<icon gap:platform="ios" height="72" src="res/icon/ios/icon-72.png" width="72" />
<icon gap:platform="ios" height="114" src="res/icon/ios/icon-57-2x.png" width="114" />
<icon gap:platform="ios" height="144" src="res/icon/ios/icon-72-2x.png" width="144" />

<icon gap:platform="blackberry" src="res/icon/blackberry/icon-80.png" />
<icon gap:platform="blackberry" gap:state="hover" src="res/icon/blackberry/icon-80.png" />

<icon gap:platform="webos" src="res/icon/webos/icon-64.png" />
<icon gap:platform="winphone" src="res/icon/windows-phone/icon-48.png" />
<icon gap:platform="winphone" gap:role="background" src="res/icon/windows-phone/icon-173.png" />

This question is related to cordova

The answer is


I'm running phonegap 3.1.0-0.15.0, since iOS7 changed the resolution to 120x120px I just added a file with those dimensions to the project then changed the info.plist file.

  1. Add a 120x120 file to the project, by right clicking the project file in Xcode and selecting, "Add files to "[Your Project Name]"...
  2. Go to the info.plist file in Xcode "Resources/[Your Project Name]-info.plist"
  3. Under "Icon files (iOS 5)/Primary Icon/Icon files" change "Item 2" to whatever the filename your file had (I called mine "icon-120.png which I placed in the Project folder along side all the other icons, though this shouldn't matter)

More info can be found here: http://www.digifloor.com/missing-recommended-icon-file-error-ios-app-13

To fix the splash screen in iOS i just pasted in new files with the same dimensions and same filenames, overwriting the old ones. Just remember to go to Product>Clean in the menu bar in Xcode (shortcut Shift+Command+K) and it should work fine! :)


I'm also in the middle of trying to understand how this all connects.

Here's what I've found so far in XCode, but I hope to be corrected or affirmed if my assumptions are correct. I haven't found an out of the box build to xcode from cordova that correctly applies the icons. Like you I've updated all the icons listed in the config.xml but no dice.

So...

First, I usually update the config.xml in the root of the project with the one in my "www" folder (this I do out of uncertainty that the www/config.xml has any precedence or if it's even applied)

Second, I update the "Build Phases" of the project. Expand "Copy Bundle Resources", you've already noticed all of the images in "Resources/icons", "Resources/splash". You can either:

  • remove all of these to avoid overwriting your images OR
  • update all of these images with your own (renaming to the image name listed)

As I was working this out, you might be able to minimally just update images from the "Summary" tab.

Drag-and-drop your images from your res folders to the appropriate image in the "Summary" tab. (res/icon/ios -> App icons and res/screen/ios -> Launch Images). I do it only for iPhone since my app is iPhone only. Check "prerendered" if you don't want gloss to appear.

Then update the "icon.png" referenced in the project's plist file: PROJECT_NAME-Info.plist or in the "Info" tab when looking at the project target. Rename it to "icon-57.png" (that now lives in your project root, this was automatically added to the root when you did the drag-and-drop.

Build and you should an updated app icon.


For me the custom icon was not working I then updated the icon on the following location and it worked.

{projectlocation}\platforms\android\app\src\main\res


Just noting that I've just changed my config.xml to look like Sebastian's example.

Something that's also helpful in debugging all this especially if you don't do local builds... is to download the XAP/IPA/APK files as built from PhoneGap cloud and create folders for each. Rename each file with a .ZIP extension and extract the contents of each to their respective folders. So basically, you can now see what's in the package that will be shipped to the phone.

Doing this, I can see that for the Microsoft Phone platform it's largely ignoring all my attempts at replacing the icon or splash screen. If you then replace the ApplicationIcon.png and SplashScreenImage.jpg, then re-zip the folderset and rename it again as a .XAP file you can then deploy it to your phone and it will work perfectly. Somehow, there's a way of just getting the PhoneGap build to turn your icon.png and icon.jpg into those two files. Perhaps Masood's suggestion is a possibility here and utilize a hook script.

Doing the same for the .IPA file (iOS) results in several files like icon-something.png at the parent level above www. They all appear to be blank.

Doing the same for the .APK file (Android) results in a res/drawable-something set of folders and it appears to have my icon.png in each one. It's the closest to a success I can claim at the moment.


in some cases the internal skripts of cordova don´t put the icons in the right folder, therfore you can see the f*** cordova robot instead of your own icon.

Make use of hook script.;)

three-hooks-your-cordovaphonegap-project-needs

Create a folder "after_platform_add" in the hook folder and put/change the last skript from devgirl.

Don´t forget to set executive rights for the script, in linux "chmod 777 <script>"

good luck!


Since most of the answers here are targeted towards iOS here's a solution for changing icon in Android.

For android:

Make changes in <project location>\platforms\android\ant-build\res and not <project location>\platforms\android\res

For some people making changes in the latter location may have worked, but having noticed Phonegap copying from \android\res into \android\ant-build\res, I decided to check in there and found a separate set of drawable folders containing the default phonegap icon.

Changing those finally worked.

Since I'm building and running locally and not using Adobe PhoneGap Build, changing icons in <project location>\www\res\icon\android didn't work either.


Just add this code into your config.xml file

<icon src="path to your icon image">

eg:

<icon src="icon.png">

Al ways remember you need to use .png extension


If you want an easy-to-use way to add icons automatically when building locally (cordova emulate ios, cordova run android, etc) have a look at this gist:

https://gist.github.com/LinusU/7515016

Hopefully this will start to work out of the box sometime in the future, here is the relevant bug report on the Cordova project:

https://issues.apache.org/jira/browse/CB-2606


Fortunately there is a little bit in the docs about the splash images, which put me on the road to getting the right location for the icon images as well. So here it goes.

Where the files are placed Once you have built your project using command-line interface "cordova build ios" you should have a complete file structure for your iOS app in the platforms/ios/ folder.

Inside that folder is a folder with the name of your app. Which in turn contains a resources/ directory where you will find the icons/ and splashscreen/ folders.

In the icons folder you will find four icon files (for 57px and 72 px, each in regular and @2x version). These are the Phonegap placeholder icons you've been seeing so far.

What to do

All you have to do is save the icon files in this folder. So that's:

YourPhonegapProject/Platforms/ios/YourAppName/Resources/icons

Same for splashscreen files.

Notes

  1. After placing the files there, rebuild the project using cordova build ios AND use xCode's 'Clean product' menu command. Without this, you'll still be seeing the Phonegap placeholders.

  2. It's wisest to rename your files the iOS/Apple way (i.e. [email protected] etc) instead of editing the names in the info.plist or config.xml. At least that worked for me.

  3. And by the way, ignore the weird path and the weird filename given for the icons in config.xml (i.e. <icon gap:platform="ios" height="114" src="res/icon/ios/icon-57-2x.png" width="114" />). I just left those definitions there, and the icons showed up just fine even though my 114px icon was named [email protected] instead of icon-57-2x.png.

  4. Don't use config.xml to prevent Apple's gloss effect on the icon. Instead, tick the box in xCode (click the project title in the left navigation column, select your app under the Target header, and scroll down to the icons section).


FAQ: ICON / SPLASH SCREEN (Cordova 5.x / 2015)

I present my answer as a general FAQ that may help you to solve many problems I've encountered while dealing with icons/splash screens. You may find out like me that the documentation is not always very clear nor up to date. This will probably go to StackOverflow documentation when available.

First: answering the question

How can I add custom app icons for iOS and Android with phonegap?

In your version of Cordova the icon tag is useless. It is not even documented in Cordova 3.0.0. You should use the documentation version that fits the cli you are using and not the latest one!

The icon tag does not work for Android at all before the version 3.5.0 according to what I can see in the different versions of the documentation. In 3.4.0 they still advice to manually copy the files

In newer versions: your config.xml looks better for newer Cordova versions. However there are still many things you may want to know. If you decide to upgrade here are some useful things to modify:

  • You don't need the gap: namespace
  • You need <preference name="SplashScreen" value="screen" /> for Android

Here are more details of the questions you might ask yourself when trying to deal with icons and splash screen:

Can I use an old version of Cordova / Phonegap

No, the icon/splashscreen feature was not in former versions of Cordova so you must use a recent version. In former versions, only Phonegap Build did handle the icons/splash screen so building locally and handling icons was only possible with a hook. I don't know the minimum version to use this feature but with 5.1.1 it works fine in both Cordova/Phonegap cli. With Cordova 3.5 it didn't work for me.

Edit: for Android you must use at least 3.5.0

How can I debug the build process about icons?

The cli use a CP command. If you provide an invalid icon path, it will show a cp error:

sebastien@sebastien-xps:cordova (dev *+$%)$ cordova run android --device
cp: no such file or directory: /home/sebastien/Desktop/Stample-react/cordova/res/www/stample_splash.png

Edit: you have use cordova build <platform> --verbose to get logs of cp command usage to see where your icons gets copied

The icons should go in a folder according to the config. For me it goes in many subfolders in : platforms/android/build/intermediates/res/armv7/debug/drawable-hdpi-v4/icon.png

Then you can find the APK, and open it as a zip archive to check the icons are present. They must be in a res/drawable* folder because it's a special folder for Android.

Where should I put the icons/splash screens in my project?

In many examples you will find the icons/splash screens are declared inside a res folder. This res is a special Android folder in the output APK, but it does not mean you have to use a res folder in your project.

You can put your icon anywhere, but the path you use must be relative to the root of the project, and not www so take care! This is documented, but not clearly because all the examples are using res and you don't know where this folder is :(

I mean if you put the icon in www/icon.png you absolutly must include www in your path.

Edit Mars 2016: after upgrading my versions, now it seems that icons are relative to www folder but documentation has not been changed (issue)

Does <icon src="icon.png"/> work?

No it does not!.

On Android, it seems it used to work before (when the density attribute was not supported yet?) but not anymore. See this Cordova issue

On iOS, it seems using this global declaration may override more specific declarations so take care and build with --verbose to ensure everything works as expected.

Can I use the same icon/splash screen file for all the densities.

Yes you can. You can even use the same file for both the icon, and splash screen (just to test!). I have used a "big" icon file of 65kb without any problem.

What's the difference when using the platform tag vs the platform attribute

<icon src="icon.png" platform="android" density="ldpi" />

is the same as

<platform name="android">
    <icon src="www/stample_icon.png" density="ldpi" />
</platform>

Should I use the gap: namespace if using Phonegap?

In my experience new versions of Phonegap or Cordova are both able to understand icon declarations without using any gap: xml namespace.

However I'm still waiting for a valid answer here: cordova/phonegap plugin add VS config.xml

As far as I understand, some features with the gap: namespace may be available earlier in PhonegapBuild, then in Phonegap and then being ported to Cordova (?)

Is <preference name="SplashScreen" value="screen" /> required?

At least for Android yes it is. I opened an issue with additional explainations.

Does icon declaration order matters?

Yes it does! It may not have any impact on Android but it has on iOS according to my tests. This is unexpected and undocumented behavior so I opened another issue.

Do I need cordova-plugin-splashscreen?

Yes this is absolutly required if you want the splash screen to work. The documentation is not clear (issue) and let us think that the plugin is required only to offer a splash screen javascript API.

How can I resize the images for all width/height/densities fastly

There are tools to help you do that. The best one for me is http://makeappicon.com/ but it requires to provide an email address.

Other possible solutions are:

Can you give me an example config?

Yes. Here's my real config.xml

<?xml version='1.0' encoding='utf-8'?>
<widget id="co.x" version="0.2.6" xmlns="http://www.w3.org/ns/widgets" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:cdv="http://cordova.apache.org/ns/1.0" xmlns:gap="http://phonegap.com/ns/1.0">
    <name>x</name>
    <description>
        x
    </description>
    <author email="[email protected]" href="https://x.co">
        x
    </author>
    <content src="index.html" />
    <preference name="permissions"                  value="none" />
    <preference name="webviewbounce"                value="false" />
    <preference name="StatusBarOverlaysWebView"     value="false" />
    <preference name="StatusBarBackgroundColor"     value="#0177C6" />
    <preference name="detect-data-types"            value="true" />
    <preference name="stay-in-webview"              value="false" />
    <preference name="android-minSdkVersion"        value="14" />
    <preference name="android-targetSdkVersion"     value="22" />
    <preference name="phonegap-version"             value="cli-5.1.1" />

    <preference name="SplashScreenDelay"            value="10000" />
    <preference name="SplashScreen"                 value="screen" />


    <plugin name="cordova-plugin-device"                spec="1.0.1" />
    <plugin name="cordova-plugin-console"               spec="1.0.1" />
    <plugin name="cordova-plugin-whitelist"             spec="1.1.0" />
    <plugin name="cordova-plugin-crosswalk-webview"     spec="1.2.0" />
    <plugin name="cordova-plugin-statusbar"             spec="1.0.1" />
    <plugin name="cordova-plugin-screen-orientation"    spec="1.3.6" />
    <plugin name="cordova-plugin-splashscreen"          spec="2.1.0" />

    <access origin="http://*" />
    <access origin="https://*" />

    <access launch-external="yes" origin="tel:*" />
    <access launch-external="yes" origin="geo:*" />
    <access launch-external="yes" origin="mailto:*" />
    <access launch-external="yes" origin="sms:*" />
    <access launch-external="yes" origin="market:*" />

    <platform name="android">
        <icon src="www/stample_icon.png" density="ldpi" />
        <icon src="www/stample_icon.png" density="mdpi" />
        <icon src="www/stample_icon.png" density="hdpi" />
        <icon src="www/stample_icon.png" density="xhdpi" />
        <icon src="www/stample_icon.png" density="xxhdpi" />
        <icon src="www/stample_icon.png" density="xxxhdpi" />
        <splash src="www/stample_splash.png" density="land-hdpi"/>
        <splash src="www/stample_splash.png" density="land-ldpi"/>
        <splash src="www/stample_splash.png" density="land-mdpi"/>
        <splash src="www/stample_splash.png" density="land-xhdpi"/>
        <splash src="www/stample_splash.png" density="land-xhdpi"/>
        <splash src="www/stample_splash.png" density="land-xhdpi"/>
        <splash src="www/stample_splash.png" density="port-hdpi"/>
        <splash src="www/stample_splash.png" density="port-ldpi"/>
        <splash src="www/stample_splash.png" density="port-mdpi"/>
        <splash src="www/stample_splash.png" density="port-xhdpi"/>
        <splash src="www/stample_splash.png" density="port-xxhdpi"/>
        <splash src="www/stample_splash.png" density="port-xxxhdpi"/>
    </platform>

    <platform name="ios">
        <icon src="www/stample_icon.png" width="180" height="180" />
        <icon src="www/stample_icon.png" width="60" height="60" />
        <icon src="www/stample_icon.png" width="120" height="120" />
        <icon src="www/stample_icon.png" width="76" height="76" />
        <icon src="www/stample_icon.png" width="152" height="152" />
        <icon src="www/stample_icon.png" width="40" height="40" />
        <icon src="www/stample_icon.png" width="80" height="80" />
        <icon src="www/stample_icon.png" width="57" height="57" />
        <icon src="www/stample_icon.png" width="114" height="114" />
        <icon src="www/stample_icon.png" width="72" height="72" />
        <icon src="www/stample_icon.png" width="144" height="144" />
        <icon src="www/stample_icon.png" width="29" height="29" />
        <icon src="www/stample_icon.png" width="58" height="58" />
        <icon src="www/stample_icon.png" width="50" height="50" />
        <icon src="www/stample_icon.png" width="100" height="100" />
        <splash src="www/stample_splash.png" width="320" height="480"/>
        <splash src="www/stample_splash.png" width="640" height="960"/>
        <splash src="www/stample_splash.png" width="768" height="1024"/>
        <splash src="www/stample_splash.png" width="1536" height="2048"/>
        <splash src="www/stample_splash.png" width="1024" height="768"/>
        <splash src="www/stample_splash.png" width="2048" height="1536"/>
        <splash src="www/stample_splash.png" width="640" height="1136"/>
        <splash src="www/stample_splash.png" width="750" height="1334"/>
        <splash src="www/stample_splash.png" width="1242" height="2208"/>
        <splash src="www/stample_splash.png" width="2208" height="1242"/>
    </platform>

    <allow-intent href="*" />
    <engine name="browser" spec="^3.6.0" />
    <engine name="android" spec="^4.0.2" />
</widget>

A good source of examples are starter kits. Like phonegap-start or Ionic starter


As of Cordova 3.5.0-0.2.6 the <icon /> element in config.xml works with the following caveats:

  1. The src attribute is a path relative to your project root folder. The issue tracker about this issue reason why the change.

  2. The <icon src="..." /> element without resolution/dpi is documented as the icon used by all platforms as the default icon. However, on android builds, the default icon is only copied to the android drawable folder, without specific resolutions set. This makes you custom icon appear in the /res/drawable folder, and the cordova default icon with specific resolutions exists in the other folders inside the final apk (i.e. /res/drawable-ldpi). You must add one icon element in config.xml for each resolution on the android platform.

For instance, if your icon image is in the path www/res/img/icon.png relative to your root project, this lines in config.xml makes your app icon in android works:

<!-- Default application icon -->
<icon src="www/res/img/icon.png" />
<!--
    Default icon should work, but cordova don't overwrite
    the default on all densities
-->
<icon src="www/res/img/icon.png" platform="android" density="ldpi" />
<icon src="www/res/img/icon.png" platform="android" density="mdpi" />
<icon src="www/res/img/icon.png" platform="android" density="hdpi" />
<icon src="www/res/img/icon.png" platform="android" density="xhdpi" />

With that configuration in place, you can have a single image icon for all resolutions overwriting the default cordova icon, and without custom hoooks. Simply building with cordova build android should do the trick.


You have to create a config.xml file in which you shall put the icon file

<?xml version="1.0" encoding="ISO-8859-1" ?>
<widget xmlns = "http://www.w3.org/ns/widgets"
   xmlns:gap = "http://phonegap.com/ns/1.0"
   id        = "example"
   version    = "1.0.0">

   <icon src="icon.png" />
</widget>

Check this: https://build.phonegap.com/docs/config-xml

there is iOS specific icons


In cordova 3.3.1-0.1.2 the expected behavior is not working right.

in

http://cordova.apache.org/docs/en/3.3.0/config_ref_images.md.html#Icons%20and%20Splash%20Screens

it clearly states you're suppose to put them into your main www folder in a folder called res and icons that follow a particular naming convention instead of the original customizable config.xml specified way (in which you point to a file of your choosing, which was/is much better). it should take then from there for each platform and put them into the platforms/?android?/res/drawable-?dpi/icon.png but it does no such correct behavior at this time... bug.

so I guess we have to manually put them there for each platform. it would of course need to remove that from duplicating it into the www folder again. for me I had to totally replace the contents in the main www folder anyway because it simply didn't work with even hello world without hacking a redirect index.html to find some weird random folder there. Putting the res folder beside www makes the most sense but what ever it seems to be for me caused by this series of cascading and confusing design choices/flaws.


All I did was added the below lines in config.xml <icon src="www/img/appIcon.png" />

And it worked totally fine