Setting Android feature flags in manifest

Hi all,

I ran into an issue with a mobile app on Android 10, and in order to make a temporary fix, I need to set a flag in the Android manifest:

<manifest ... >
  <application android:requestLegacyExternalStorage="true" ... >
    ...
  </application>
</manifest>

Since we can not access the manifest directly via OutSystems, I assumed that I could set something in the Extensibility Configuration, hoping it would end up on the right place in the Android manifest (via the Cordova index.xml file). My try:

{
    "preferences": {
        "android": {
            "name": "requestLegacyExternalStorage",
            "value": "true"
        }
    }
}


However, this does not seem to work.

Anyone with some experience on this? Are we technically able to set things in the Android manifest via some abstraction in OutSystems?

Hi Rob,

I don’t have an exact example but this comes pretty close to what you want to achieve which is to change an attribute value on application tag.

So the trick is basically to build a plugin that has no source code, its only used to push the configurations to the in the AndroidManifest.xml 

https://github.com/Chuckytuh/cordova-plugin-allow-backup


Please also check out this thread, it may be helpful:

https://www.outsystems.com/forums/discussion/45641/how-do-i-include-a-permission-in-the-androidmanifest-xml/


Best regards,

Daniel Martins

Thank you Daniel, I will look into this.

I was already looking at this cordova plugin to change the manifest, but it's readme also points toward the edit-config option in the Cordova configuration as a more simple alternative.

I am able to add something in the AndroidManifest.xml by adding a plugin to the code. These were my steps:

  1. Create a folder for your plugin code.
  2. Only add a plugin.xml file in the folder. See content of the file attached.
  3. Zip the folder and add it to a new (mobile) module as resource.
  4. Configure the Extensibility Configuration to use the zip as plugin source, see example below.
  5. Build the app.
  6. Check the manifest of the generated APK to see the property. You can do this with AndroidStudio via Build > Analyse APK or File > Profile and debug APK


Extensibility configuration (change-manifest.zip attached):

{
    "resource": "changemanifest.zip",
    "plugin": {
        "resource": "change-manifest"
    }
}


This worked perfectly with a new app. Thanks Daniel for the pointer. 

However, I still have issues with implementing this in my original app. MABS gives an error that I'm modifying a field that is already modified, while I use the same plugins in my newly created app.

"Failed to install 'change-manifest': Error: There was a conflict trying to modify attributes with <edit-config> in plugin change-manifest. The conflicting plugin, undefined, already modified the same attributes. The conflict must be resolved before change-manifest can be added. You may use --force to add the plugin and overwrite the conflicting attributes."

Still need to figure out what is happening there!

changemanifest.zip

Hi Rob,

That issue with the "there was a conflict trying to modify attributes with <edit-config> in plugin change-manifest", happens when 2 different plug-ins make use of the same property.


    <edit-config file="AndroidManifest.xml" target="/manifest/application" mode="merge">

            <application android:requestLegacyExternalStorage="true"

        </edit-config>


The "merge" should allow the manifest configurations to be merged, but it's not assuming the merge. It's assuming conflict and is throwing an error.


In one of the plugins manifest could you please add the merge mode?

Thank you,

Best regards

I could not find any edits on the application tag in other plugins:

  • CameraPlugin
  • FileOpener
  • FilePlugin
  • BuildInfo Plugin
  • SaveToGallery Plugin


So I just added them systematically to a new app. SaveToGallery and FilePlugin are fine, it breaks when I add FileOpener. I am using this specific version.

It adds some config to the AndroidManifest, but I don't see why it is conflicting, it is not targeting the application tag itself:

    <platform name="android">
<source-file src="src/android/io/github/pwlin/cordova/plugins/fileopener2/FileOpener2.java" target-dir="src/io/github/pwlin/cordova/plugins/fileopener2" />
<source-file src="src/android/io/github/pwlin/cordova/plugins/fileopener2/FileProvider.java" target-dir="src/io/github/pwlin/cordova/plugins/fileopener2" />
<config-file target="res/xml/config.xml" parent="/*">
<feature name="FileOpener2">
<param name="android-package" value="io.github.pwlin.cordova.plugins.fileopener2.FileOpener2" />
</feature>
</config-file>
<config-file target="AndroidManifest.xml" parent="/*">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
</config-file>
<config-file target="AndroidManifest.xml" parent="application">
<provider android:name="io.github.pwlin.cordova.plugins.fileopener2.FileProvider" android:authorities="${applicationId}.opener.provider" android:exported="false" android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/opener_paths" />
</provider>
</config-file>
<source-file src="src/android/res/xml/opener_paths.xml" target-dir="res/xml" />
<preference name="ANDROID_SUPPORT_V4_VERSION" default="27.+"/>
<framework src="com.android.support:support-v4:$ANDROID_SUPPORT_V4_VERSION"/>
</platform>

Rob Mooijman wrote:

it breaks when I add FileOpener. .... It adds some config to the AndroidManifest, but I don't see why it is conflicting, it is not targeting the application tag itself:

...
<config-file target="AndroidManifest.xml" parent="/*">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
</config-file>

But it is. Android manifest root element is <manifest> and only mandatory child is <application> tag.

Android developer guide <manifest> element has more details.

edit: Another option is that the parent="application" reference triggers this warning.

Hi Mikko thanks for your input.

Adding merge mode on those configs still don't make the error disappear. From what I get from the Manifest documentation the <uses-permission> tag is a sibling of application, so that couldn't be the issue. I've build the app with omitting the <config-file target="AndroidManifest.xml" parent="application"> part from the plugin.xml and that 'solved' the conflict. But it should be there of course, and mode=merge still gives the merge issue.

Any ideas on how to bypass this?

edit:
I've also tried to copy all the attributes that need to be on the Application tag when all plugins are added, together with my new attribute and set the mode of <edit-config> to "overwrite". That also fails (maybe this fails due to obvious reasons, but my knowledge is very limited on this topic).

Hi Rob, I've same issue too.. Any updates  from you to solve this issue ? 


No, I still don't have a solution for colliding changes of different plugins into the same manifest, as merge mode did not work for me. I tried deleting potential collisions from the plugin sources and bundle them as one plugin.xml file, but that resolved in issues that were outside my knowledge to solve.

On the particular case that resulted in my need to add things to the android manifest (external storage legacy permissions); this flag is not a solution anymore with the introduction of Android 11 (only works in Android 10). I have a support ticket with OutSystems to look at the particular external storage permissions, since you need to use the Scoped Storage frameworks nowadays on Android, which is not thoroughly supported by the Camera and File plugins.

Finally I found this thread cause a long time ago i've same problem with you and didn't solve my issue until now..

Did you try to compile your code to dummy apps ? Is it work ?

I  also create thread on file plugin 

https://www.outsystems.com/forums/discussion/60825/file-plugin-not-working-on-android-10-a-k-a-android-q/

Please  reply me if any futher information from support.. Thank a lot Rob 


My team has found out for instance that in the original cordova Camera plugin there is a fix for writing to the picture gallery location, which is an "External" storage location. In that cordova project there is also a JS API 'SaveToGallery' (or something like that), that is missing in the Outsystems source for the Camera Plugin forge component. I have highlighted in my support case that both the OutSystems Camera plugin and File plugin can make use of that implementation.

Via my support case I have received the feedback that the developers of the Camera plugin and File plugin have added this (fix for Android external storage permissions) to their backlog.

Hi Rob,

From my experience mode="merge" solved the issue.

If you can’t figure it out, I suggest you to open a support ticket.

Best regards,

Keep us updated 

It would be so cool if we could set those permissions in the Service Studio...

Hi Chris.

Feel free to check it and add it in the Ideas!

Community GuidelinesBe kind and respectful, give credit to the original source of content, and search for duplicates before posting.