Change AndroidManifest.xml on Ionic v3.7.0 - android

I'm using v3.7.0 and I want to change the AndroidManifest.xml when I build my app. Currently I have tried changing the my-project-path/config.xml file adding the the following lines:
Option a.
<widget>
<preference name="android-manifest/application/activity/#android:windowSoftInputMode" value="adjustPan" />
</widget>
Option b.
<widget>
<preference name="android-windowSoftInputMode" value="adjustPan" />
</widget>
Then I do:
$ ionic cordova build android
And I was expecting the following change on my-project-path/platform/android/AndroidManifest.xml:
<manifest>
<application>
<activity android:windowSoftInputMode="adjustPan">
</activity>
</application>
</manifest>
But I get the same result as without adding the preference settings:
<manifest>
<application>
<activity android:windowSoftInputMode="adjustResize">
</activity>
</application>
</manifest>
How can I apply the desired effect to the AndroidManifest.xml?
Thanks!

I found how to do it. If your Cordova version is above 6.4.0 you can use the tag <edit-config> (http://cordova.apache.org/docs/en/7.x/plugin_ref/spec.html#edit-config) and I think that if you are using the latest version of Ionic probably you'll have a Cordova version above 6.4.0 (I have 7.1).
So the way to make the desired change that I wanted I had to set the my-project-path/config.xml file as follows:
<widget xmlns:android="http://schemas.android.com/apk/res/android">
<platform name="android">
<edit-config file="AndroidManifest.xml" mode="merge" target="/manifest/application/activity">
<activity android:windowSoftInputMode="adjustPan" />
</edit-config>
</platform>
</widget>
Check that the widget has a new attribute.
With this change when I build the Android version the manifest my-project-path/platform/android/AndroidManifest.xml looks like this:
<manifest>
<application>
<activity android:windowSoftInputMode="adjustPan">
</activity>
</application>
</manifest>

It looks like AndroidManifest.xml is something that's get derived from config.xml and not something you would want to directly edit.
I would edit config.xml and sections of it are reflected into the various AndroidManifest.xml used for building Android APKs

Related

How to set Android exported for Cordova application

I am need to publish a Cordova application on Google Play targeting Android 12. When I uploaded my APK file, I get error
You uploaded an APK or Android App Bundle which has an activity, activity alias, service or broadcast receiver with intent filter, but without the 'android:exported' property set. This file can't be installed on Android 12 or higher. See: developer.android.com/about/versions/12/behavior-changes-12#exported
I did some reaserch on internet and I found, that this configuration should be add to config.xml:
<edit-config file="app/src/main/AndroidManifest.xml" mode="merge" target="/manifest/application/activity">
<activity android:exported="true"/>
</edit-config>
It works fine for some of my applications, but one of them still shows the error, when uploaded to Google Play. Its AndroidManifest.xml looks like this:
<?xml version='1.0' encoding='utf-8'?>
<manifest android:hardwareAccelerated="true" android:versionCode="750" android:versionName="7.5.0" package="cz.foxtrot.motoquest" 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" />
<application android:hardwareAccelerated="true" android:icon="#mipmap/ic_launcher" android:label="#string/app_name" android:supportsRtl="true" android:usesCleartextTraffic="true">
<activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode" android:exported="true" android:label="#string/activity_name" android:launchMode="singleTask" android:name="MainActivity" android:theme="#android:style/Theme.DeviceDefault.NoActionBar" 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>
<receiver android:enabled="true" android:name="nl.xservices.plugins.ShareChooserPendingIntent">
<intent-filter>
<action android:name="android.intent.action.SEND" />
</intent-filter>
</receiver>
<provider android:authorities="${applicationId}.sharing.provider" android:exported="true" android:grantUriPermissions="true" android:name="nl.xservices.plugins.FileProvider">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="#xml/sharing_paths" />
</provider>
<meta-data android:name="com.transistorsoft.locationmanager.license_key" android:value="b2c8e0bf1863da91b0f941ddf8278f699d320a320182cf7eb1d1e5c660ee17be" />
</application>
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<uses-permission android:name="com.android.vending.BILLING" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>
Any ideas, what can be wrong?
Following up to the answer from Carl Smith.
You might need to set the exported on more tags. The edit-config tag does as the name says, it edits the XML configuration file after it has been generated. In this case it will add the android:exported tag.
Try adding this to your config.xml file inside the tag:
<edit-config file="app/src/main/AndroidManifest.xml" target="/manifest/application/activity" mode="merge">
<activity android:exported="true"/>
</edit-config>
<edit-config file="app/src/main/AndroidManifest.xml" target="/manifest/application/service" mode="merge">
<service android:exported="true" />
</edit-config>
<edit-config file="app/src/main/AndroidManifest.xml" target="/manifest/application/provider" mode="merge">
<provider android:exported="true" />
</edit-config>
<edit-config file="app/src/main/AndroidManifest.xml" target="/manifest/application/receiver" mode="merge">
<receiver android:exported="true" />
</edit-config>
It will not only set the flag for the activity and service tags but also for the provider and the receiver.
Notice that this will set the exported flag to true. The best solution is to wait until all maintainers of your plugins have updated the plugin but until then at least you can submit your working apps to the Play Store and confirm to the required use of API 31+.
Please notice that you might not need all these 4 edits for your config. This depends on the plugins you use and how well they are updated. Start with one (from top to bottom) if it doesn't work add more and if it works try to remove the others to find out what the minimum is you need. Don't change more then needed.
try adding this to your cordova config.xml under <platform name="android">:
<edit-config file="app/src/main/AndroidManifest.xml" target="/manifest/application/activity" mode="merge">
<activity android:exported="true" />
</edit-config>
<edit-config file="app/src/main/AndroidManifest.xml" target="/manifest/application/service" mode="merge">
<service android:exported="true" />
</edit-config>
With the above solutions I get a build error
Unable to graft xml at selector "/manifest/application/service"
My solution after hours of research is quite easy:
In AndroidManifest.xml (in platforms/android/app/src/main)
I extended the activity tag:
<activity android:configChanges="...." android:exported="true" ....>
...
Now build works fine and I can send the app-release.aab to Google without error.
In my case, I tried to add the changes in config.xml that is in this comment https://stackoverflow.com/a/74278418/7078094, but it didn't work.
The app compiled with out errores, but when I tried to install in a phone with Android 12, it didn't work.
My solution, (in a app that is make with Ionic 3 and Cordova) was:
(If you have some / , remove it)
ionic cordova platform rm android
ionic cordova platform add android
Then, modifiy manually the file app/src/main/AndroidManifest.xml:
In this file, you should have something like this:
<manifest ... />
<supports-screens ... />
<uses-permission ... />
<application ... />
<activity ... />
<intent-filter ... />
<action ... />
<category ... />
</intent-filter>
</activity>
<provider ... android:exported="false" />
<meta-data ... />
</provider>
</application>
<uses-sdk ... />
<uses-permission ... />
Inside from <application ... />, in my case I have , activity and provider. (but I believe that you could also have a service and receiver here )
already have the tag android:exported="false" , so I did not modify it
But , It didn't have none. So, I added android:exported="true"
(If you have someone (provider, activity, service, receiver) that doesn't have this tag, added it like I did with activity )
<manifest ... />
<supports-screens ... />
<uses-permission ... />
<application ... />
<activity ... android:exported="true" />
<intent-filter ... />
<action ... />
<category ... />
</intent-filter>
</activity>
<provider ... android:exported="false" />
<meta-data ... />
</provider>
</application>
<uses-sdk ... />
<uses-permission ... />
I couldn't automate this change from config.xml, nothing worked.
I know it's not the best solution, because it's something you have to do manually after creating the platform, but it works
Then, I built the app with ionic cordova build android --release
Sign the app. (*)
And this work for me.
I could run a app made in Ionic 3 in Android 12,8 y 6
IMPORTANT
To sign the app is necessary do it something like this (maybe can be different , depends the app and sign):
You should have installed SDK 31 and ( Probably at a later date, I will increase the version required.)
Open a console in platforms/android/app/build/outputs/apk/release
zipalign -v 4 app-release-unsigned.apk myapp.apk
apksigner sign --ks my-ks.keystore --ks-pass file:my-passfile.txt --v1-signing-enabled true --v2-signing-enabled true myapp.apk
If when you try execute zipalign or apksigner, and not exist/not found de commmand you can find this directly in the sdk folder and execute like this (on Windows in my case)
C:/Users/[user]/AppData/Local/Android/sdk/build-tools/31.0.0/zipalig -v 4 app-release-unsigned.apk myapp.apk
C:/Users/[user]/AppData/Local/Android/Sdk/build-tools/31.0.0/apksigner sign --ks my-ks.keystore --ks-pass file:my-passfile.txt --v1-signing-enabled true --v2-signing-enabled true myapp.apk
I was facing the same problem, if you are using this plugin cordova-plugin-x-socialsharing
you just need to modify your AndroidManifest.xml and add this property android:exported="true" like This
<receiver android:enabled="true" android:exported="true" android:name="nl.xservices.plugins.ShareChooserPendingIntent">
<intent-filter>
<action android:name="android.intent.action.SEND" />
</intent-filter>
</receiver>
To save people some time, the file is in node_modules/cordova-plugin-x-socialsharing/plugin.xml
In the plugin.xml file manually added
android:exported="true" to receiver element
<config-file target="AndroidManifest.xml" parent="/*/application">
<receiver android:name="nl.xservices.plugins.ShareChooserPendingIntent" android:enabled="true" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.SEND"/>
</intent-filter>
</receiver>
</config-file>

Adding google_analytics_adid_collection_enabled meta-data tag to Cordova AndroidManifest.xml

I'm trying to add the google_analytics_adid_collection_enabled meta-data tag <meta-data android:name="google_analytics_adid_collection_enabled" android:value="false" /> to the application tag in my AndroidManifest.xml in my Cordova project but I can't find the correct way.
I think it should be something like:
<edit-config file="AndroidManifest.xml" target="/manifest/application/meta-data" mode="merge" >
<meta-data android:name="google_analytics_adid_collection_enabled" android:value="false" />
</edit-config>
But this gives me an error:
Unable to graft xml at selector "/manifest/application/meta-data" from "[MY_PROJECT_PATH]\platforms\android\app\src\main\AndroidManifest.xml" during config install
I've tried a couple of other options too but they either give errors as well or they just don't put the tag in at all.
Does anybody have an idea how to add this tag (preferably without plugins or hooks)?
A bit more trail and error but I finally found it!
<platform name="android">
<config-file target="AndroidManifest.xml" parent="/manifest/application" xmlns:android="http://schemas.android.com/apk/res/android">
<meta-data android:name="google_analytics_adid_collection_enabled" android:value="false" />
</config-file>
</platform>

Add specific android version

I'm trying to add a specific android platform.
Now all answers to these same questions look approximately the same:
Add
<preference name="android-targetSdkVersion" value="XX" /> to your config.xml
So, I tried:
Adding that line to my config.xml where XX = 23
cordova platform remove android --save
ionic cordova platform add android --save
My output shows me:
Using cordova-fetch for cordova-android#~6.2.2
Adding android project...
Creating Cordova project for the Android platform:
Path: platforms\android
Package: com.ionicframework.someapp
Name: MyApp
Activity: MainActivity
Android target: android-25
This looks like it's using android-25.
My myapp/platforms/android/AppManifest.xml looks like this:
<?xml version='1.0' encoding='utf-8'?>
<manifest android:hardwareAccelerated="true" android:versionCode="10000" android:versionName="1.0.0" package="com.ionicframework.someapp" 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" />
<application android:hardwareAccelerated="true" android:icon="#mipmap/icon" android:label="#string/app_name" android:supportsRtl="true">
<activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" android:label="#string/activity_name" android:launchMode="singleTop" android:name="MainActivity" android:theme="#android:style/Theme.DeviceDefault.NoActionBar" 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>
<provider android:authorities="${applicationId}.provider" android:exported="false" android:grantUriPermissions="true" android:name="android.support.v4.content.FileProvider">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="#xml/provider_paths" />
</provider>
</application>
<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="23" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest>
But my platforms/android/project.properties just shows target=android-25
So. How can I configure my android version to use android-23, eventually manually if there's no straight answer.
(I had this issue before and I believe I resolved it back then by reverting to a 5.X.X build of cordova. New requirements make that kind of impossible this time)
I'm not sure if this is exactly what you're looking for, but this might help. If you are trying to only use a certain API level / android version, you can use the command on cli:
cordova platform add android#[cordova android version]
ie: cordova platform add android#4.1.1
You can check out the documentation on which versions of cordova android support which API level.
Note:
Please note that the versions listed here are for Cordova's Android package, cordova-android, and not for the Cordova CLI. To determine what version of Cordova's Android package is installed in your Cordova project, run the command cordova platform ls in the directory that holds your project.
Struggle with the same problem. Is there a final solution for this problem?
This seems to be ignored in the config.xml:
<preference name="android-minSdkVersion" value="16"/>
<preference name="android-targetSdkVersion" value="23"/>
"cordova platforms add android" always install android version 6.2.2

Add an attribute at the "application" tag in the AndroidManifest from a cordova plugin

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.
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 are using cordova-custom-config you may need to add a new custom-preference to your config.xml:
<platform name="android">
<!-- ... other settings ... -->
<custom-preference name="android-manifest/application/#android:isGame" value="true" />
</platform>

Overwriting windowSoftInputMode preference in Visual Studio Tools for Apache Cordova config.xml file

I'm facing an issue in which the Android soft keyboard is appearing over the last edittext field on the page. Suggested solutions include changing the windowSoftInputMode, so I added the following preference in the config.xml file:
<preference name="android-windowSoftInputMode" value="adjustResize|stateHidden" />
However, after I do my build, the AndroidManifest.cordova.xml file in the release folder always has a windowSoftInputMode of "adjustResize" and thus nothing changes when I run the app.
<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>
Does anyone know if this setting can be overridden and if so, what the mechanism is for doing so? I'm using Visual Studio (2013 Update 4) Tools for Apache Cordova CTP3.
I've had a similar issues in the past, here's how i solved it.
Create a custom AndroidManifest.xml file in the res\native\android folder. All the info in this file will get copied to the debug folder (and will overwrite what is contained in the config.xml file) when you do a build for Android Platform.
Here's a link to the MSDN documentation which has alot more info about custom configurations for the different platforms:
https://msdn.microsoft.com/en-us/library/dn757053.aspx

Categories

Resources