Should a phonegap plugin be declared in the config.xml file?

I’m pretty sure the reason that you can still use the plugin is because you either edited the wrong config.xml or did not run the cordova command line tools to propagate your changes to the correct config.xml file that is actually used by the app.

There are multiple config.xml files in different spots in a Cordova 3.x project. I’ll try to give you an overview of the different locations of the files and how you should interact with them. Keep in mind that this is what happens when you use the CLI (Command Line-interface) – I generated this directory structure by typing:

cordova create {MyApp}
cordova platform add android ios
cordova plugin add org.apache.cordova.network-information

Or prior to Cordova 3.1, replace the last line with:

cordova plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-network-information.git

If you use just the platform level shell scripts to build the app (the “old” way that we did in Cordova 2.X), you can generally use the same workflow, but will need to Use Plugman to Manage Plugins. (We are in the process of documenting these two different “workflows”.)

First, when you create an app with cordova create MyApp, it will create an empty project structure like this:

/myApp/
        /www/           # This is where your "cross-platform' files go.
                        # The build tools copy these files over to the correct
                        # asset folder for each platform, like /assets/www/ for
                        # android or just /www/ for iOs. This is where you should
                        # be doing most/all of your work and is what should
                        # probably be version controlled.
        /platforms/
            /android/   # These will only appear after `cordova platform add`
            /ios/       # You should generally not touch these file as they are
                        # recreated quite often, although changes will persist.
        /plugins/
            /android/   # These will only appear after `cordova plugin add`. They
                        # pretty much just contain the native and web plugin code
                        # for all platforms that a plugin supports.
            /ios/
        /merges/        # This is where you can place platform-specific code that
                        # you write that will get merged in with your cross
                        # platform source, see the "customize each platform"
                        # section of: http://cordova.apache.org/docs/en/3.0.0/guide_cli_index.md.html

You should make all of your changes to files in /www/, which is the “cross platform” source code. Whatever is in this folder will generally get copied and propagated to the platform level www folder when you use the command line tools (whether its /assets/www for Android or just /www/ for iOS). This way, you only need a single source folder for your app – this is the folder that you should have under version control. Any app-wide configuration changes that you want should be made to the config.xml file placed at this location; later when you use the tools, this config.xml file will be copied (and sometimes modified with platform-specific configuration information) to the appropriate place for each app, like /platforms/android/res/xml/config.xml (for android) or /platforms/ios/AppName/config.xml (for iOS).

Say you want to add the acceleration plugin by typing cordova plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-network-information.git.
If you were to run a diff after this command, you will see the following files have been changed or added:

plugins/org.apache.cordova.network-information/
– This new folder contains all of the plugin meta information and code, including web and native code, for each supported platform

plugins/android.json and plugins/ios.json
– Both of these files have been edited now to contain a reference to the network-information plugin. This is where you will see the config-munge bit of JSON. As you add more plugins, this file will continuously grow to reference all of them. This file tells the command line tools what code it needs to replace and in which files. For example, after adding the cordova-plugin-network-information plugin, you will see this in /plugins/android.json:

{
        "prepare_queue": {
            "installed": [],
            "uninstalled": []
        },
        "config_munge": {
            "res/xml/config.xml": {
                "/*": {
                    "<feature name=\"NetworkStatus\"><param name=\"android-package\" value=\"org.apache.cordova.networkinformation.NetworkManager\" /></feature>": 1
                }
            },
            "AndroidManifest.xml": {
                "/*": {
                    "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\" />": 1
                }
            }
        },
        "installed_plugins": {
            "org.apache.cordova.network-information": {
                "PACKAGE_NAME": "io.cordova.hellocordova"
            }
        },
        "dependent_plugins": {}
    }

This tells the scripts to write the feature name into res/xml/config.xml (again, for iOS, this will be different, since the app level config file is in a different location on iOS!), and also tells it to write android.permission.ACCESS_NETWORK_STATE permission into AndroidManifest.xml (you won’t find anything like this on iOS since no permissions are necessary.) (By the way, what gets written to each of these json files is defined in the plugin’s plugin.xml file.)

platforms/android/AndroidManifest.xml
– The CLI tools took care of adding whichever permission were defined in the plugin’s xml file to AndoridManifest. Yes, this happens when you do cordova plugin add. These permissions are directly copied from whatever is in the plugins/android.json file. These permissions are also deleted when you ‘rm’ a plugin. However, editing these files is done intelligenty, in that you can add custom things to AndroidManifest.xml and they will persist.

platforms/android/assets/www/cordova_plugins.js
– This file is buried inside the html resources that will make up your final app – these resources (pretty much anything in /platforms/) should not be edited by you because they will be replaced by the CLI tools quite frequently. This file is used by Cordova at runtime to load the plugin code that you added; it also takes care of mapping the JavaScript namespaces to the actual files (this is the “clobbers” declaration.) For example, I see:

{
    "file": "plugins/org.apache.cordova.network-information/www/network.js",
    "id": "org.apache.cordova.network-information.network",
    "clobbers": [
        "navigator.connection",
        "navigator.network.connection"
    ]
}

this means that in your app code, navigator.connection and navigator.network.connection will both map to the code contained in plugins/org.apache.cordova.network-information/www/network.js.

platforms/android/res/xml/config.xml
– This is the platform-level config.xml file for Android. This file gets created by the CLI tools. A lot of the information that you write in your top level config.xml (/MyApp/www/config.xml) will get copied here, but not all of it (and there is some additional stuff, I’m not exactly sure where the additional stuff comes from.) This is the file that gets read by Android when it is running your app and it needs to check your config data. For example, Cordova Android code will use this to see which plugins are installed and which native classes map to which namespaces. I think the only way you could edit this is by using the /merges/ folder that I mentioned above.

platforms/ios/{AppName}.xcodeprojcj/project.pbxproj
– The iOS equivalent of AndroidManifest.xml

platforms/ios/{AppName}/config.xml
– This is the platform-level config.xml file for iOS. See how it is in a different spot than on Android? (eg, not in /res/xml/config.xml?) This file automatically gets updated by the CLI and you should not touch it.

platforms/ios/www/cordova_plugins.js
– The same file exists on Android (but in a different location) and has the same purpose: to help Cordova load your plugins at run time when somebody is using the app

I think that pretty much describes all of the files and folders that are used in a cordova project.

Hopefully now you can see that you should in fact only be editing the /www/config.xml file. This file will be used to construct the /platforms/android/res/xml/config.xml and /platforms/ios/{AppName}/config.xml, which are used by Cordova when the packaged app is running. Parts of this file will be used to edit the AndroidManifest.xml and project.pbxprojc files (for Android and iOS, respectively.)

This explains why you were still able to use the accelerometer in your app even after deleting the <feature name="Accelerometer"> lines – they were just being recopied into the platform level config.xml from the main app wide config.xml

I guess the only thing left to figure out is how you can edit platform specific configuration files; for example, how can you edit the AndroidManifest.xml file? Well, it turns out that you can just edit the /platforms/android/AndroidManifest.xml file directly – the CLI is smart enough to not erase your customizations when it automatically adds or removes plugin permissions. So say for some reason you needed to support a lower version of Android than what Cordova supports, you can just change the object and it will persist though your cordova plugin add|rm {id} calls.

I hope that clarifies things, feel free to ask any more questions!

Leave a Comment