I create a plugin for Cordova and I want to edit the AndroidManifest to add an attribute in the "application" tag. I know config-file to add a new tag but I don't find if I can update an existing tag.
For example, I have this AndroidManifest:
<?xml version='1.0' encoding='utf-8'?>
<manifest android:hardwareAccelerated="true" android:versionCode="1" android:versionName="0.0.1" package="com.test.testCordova" xmlns:android="http://schemas.android.com/apk/res/android">
<supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" android:xlargeScreens="true" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application android:hardwareAccelerated="true" android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" android:label="@string/activity_name" android:launchMode="singleTop" android:name="CordovaApp" android:theme="@android:style/Theme.Black.NoTitleBar" android:windowSoftInputMode="adjustResize">
<intent-filter android:label="@string/launcher_name">
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="10" android:targetSdkVersion="19" />
</manifest>
and I want add android:isGame=true
in the <application>
tag.
If i can't do this from the plugin.xml
, I will create a hook to edit the AndroidManifest
by myself but I hope it will not be necessary.
The general meaning of the problem is that the label of application needs to be manually set and overwritten in the androidmanifest.xml file Locate the Android/APP/SRC/main/androidmanifest.xml file in the project folder Find the application tag. If not, create a new one under the manifest tag, as follows
See that attribute for more information. By default, all activities within an application share the same affinity. The name of that affinity is the same as the package name set by the <manifest> element. Indicates whether this application is only for testing purposes.
This attribute was added in API level 17. An affinity name that applies to all activities within the application, except for those that set a different affinity with their own taskAffinity attributes. See that attribute for more information. By default, all activities within an application share the same affinity.
There is no default value. Whether or not the Android system can instantiate components of the application — "true" if it can, and "false" if not. If the value is "true", each component's enabled attribute determines whether that component is enabled or not.
I ended doing a plugin hook which I didn't know existed. Plugin hooks are hooks that are defined in the plugin and that can be called before or after the plugin is added or removed (either when you run the cordova plugin cli commands or when cordova adds the plugin to the platform with cordova platform add command).
I didn't want to use hooks because I thought hooks had to be placed in config.xml and could not be linked with a plugin.
Here I added this line in the platform android section of the plugin.xml file (my requirement was a little different than the OP's but the sample may help anyway) :
<platform name="android">
<hook type="before_plugin_install" src="scripts/androidBeforeInstall.js" />
...
</platform>
And then I wrote the androidBeforeInstall.js hook script :
module.exports = function(ctx) {
var fs = ctx.requireCordovaModule('fs'),
path = ctx.requireCordovaModule('path'),
xml = ctx.requireCordovaModule('cordova-common').xmlHelpers;
var manifestPath = path.join(ctx.opts.projectRoot, 'platforms/android/AndroidManifest.xml');
var doc = xml.parseElementtreeSync(manifestPath);
if (doc.getroot().tag !== 'manifest') {
throw new Error(manifestPath + ' has incorrect root node name (expected "manifest")');
}
//adds the tools namespace to the root node
doc.getroot().attrib['xmlns:tools'] = 'http://schemas.android.com/tools';
//add tools:replace in the application node
doc.getroot().find('./application').attrib['tools:replace'] = 'android:label';
//write the manifest file
fs.writeFileSync(manifestPath, doc.write({indent: 4}), 'utf-8');
};
It's a little more complex than just adding config-file lines in plugin.xml, but once you have the good syntax it can be very powerfull.
Edit:
For some reason with only the hook in before_plugin_install, the AndroidManifest.xml was correctly updated during the platform add, but was restored at it's default state at the end of the platdorm add.
As I couldn't figure out the reason, I added the following line in the plugin.xml so the script is also launched at the end of the platform add (luckilly hooks defined in plugin.xml can be run not only when adding or removing a plugin).
<hook type="after_platform_add" src="scripts/androidBeforeInstall.js" />
For latest cordova version 8.1.2
path of AndroidManifest.xml
file has been changed.
Below is how I did it and working perfectly fine.
In similar way you can also update any other configuration of AndroidManifest.xml
.
<edit-config file="app/src/main/AndroidManifest.xml" mode="merge" target="/manifest/application">
<application android:isGame="true" />
</edit-config>
Also make sure that you added the android namespace in the root <widget>
tag in config.xml (otherwise you will get unbound prefix error):
<widget ... xmlns:android="http://schemas.android.com/apk/res/android">
You are done!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With