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" />
Solution 1:
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
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.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.
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 oficon-57-2x.png
.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).
Solution 2:
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:
- AndroidAssetStudio
- https://gist.github.com/LinusU/7515016
- cordova-icon
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
Solution 3:
As of Cordova 3.5.0-0.2.6 the <icon />
element in config.xml works with the following caveats:
The
src
attribute is a path relative to your project root folder. The issue tracker about this issue reason why the change.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 inconfig.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.
Solution 4:
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