Android Build: use edit-config for uses-feature issue

Hi,

I am struggling a little with the “edit-config” to have the gps set as not mandatory in “AndroidManifest.xml”.

By default, it is set as

<uses-feature
        android:name="android.hardware.location.gps" />

And I need to have it set as

<uses-feature
        android:name="android.hardware.location.gps" android:required="false" />

When I was using phonegap adding edit-config instruction to config.xml did the job:

In Phonegap:

<edit-config file="AndroidManifest.xml" target="/manifest/uses-feature" mode="merge">
<uses-feature
        android:name="android.hardware.location.gps"
		android:required="false" />
</edit-config>

I tried Cordova CLI to build the APK and had to change it to

<edit-config file="AndroidManifest.xml" target="/*/uses-feature[@android:name='android.hardware.location.gps']" mode="merge">
<uses-feature
        android:name="android.hardware.location.gps"
		android:required="false" />
</edit-config>

But Cordova CLI is not as easy than VOLT and we would like to use it instead. I expected that the same edit-config instruction works. Unfortunately, it is not the case. I tried to change the value of target in several ways none of them works.

Keeping the same than Cordova CLI, I get the following error :

Unable to graft xml at selector "/manifest/uses-feature[@android:name='android.hardware.location.gps']" from "/platforms/android/app/src/main/AndroidManifest.xml" during config install

Going through the Cordova documentation, I do not find an alternative to have it done. Has someone an idea how to make it work ?

I successfully tested “edit-config” with the value below, so I know it can works but not (yet) for uses-feature tag:

<config-file target="AndroidManifest.xml" parent="/manifest">
   <uses-sdk android:minSdkVersion="23" android:maxSdkVersion="28" />
</config-file>

Thanks in advance for your help.

Best Regards,
Michael O

Tip : If you’re pasting code, html or config files, surround the code with triple back ticks (```), before the first line and after the last one. It will be formatted properly.

Thanks - we’re looking into this.

You’re right in your assumption that if it works in Cordova, it should work in VoltBuilder. (as far as we know).

I tried using Cordova to build a project with

<edit-config file="AndroidManifest.xml" target="/*/uses-feature[@android:name='android.hardware.location.gps']" mode="merge">
<uses-feature
        android:name="android.hardware.location.gps"
		android:required="false" />
</edit-config>

as you did - but I get the same “Unable to graft xml” error message. Can you check if that actually works for you in Cordova? If it does, can you give me a step by step?

Another way to do this might be to use the cordova-custom-config plugin.

Thank you for your swift reply.

I am using Neptune Planet 8 to build the cordova package but I did a project in plain Cordova CLI and edit-config works.

What I did to reproduce it without Neptune Planet 8 :

  1. create a project : cordova create hello com.example.hello HelloWorld
  2. add android platform : cordova platform add android
  3. add in config.xml the following plugins (the same plugins I have in my Neptune project)
<plugin name="cordova-plugin-battery-status" source="npm" spec="2.0.3"/>
<plugin name="cordova-plugin-contacts" source="npm" spec="3.0.1"/>
<plugin name="cordova-plugin-camera" source="npm" />
<plugin name="cordova-plugin-device" source="npm" />
<plugin name="cordova-plugin-dialogs" source="npm" />
<plugin name="cordova-plugin-file" source="npm" />
<plugin name="cordova-plugin-geolocation" source="npm" />
<plugin name="cordova-plugin-inappbrowser" source="npm" />
<plugin name="cordova-plugin-media" source="npm" />
<plugin name="cordova-plugin-media-capture" source="npm" />
<plugin name="cordova-plugin-network-information" source="npm" />
<plugin name="cordova-plugin-splashscreen" source="npm" />
<plugin name="cordova-plugin-statusbar" source="npm" />
<plugin name="cordova-plugin-vibration" source="npm" />
<plugin name="cordova-plugin-whitelist" source="npm" />
  1. If a build now the APK, in the AndroidManifest.xml, I have
<uses-feature android:name="android.hardware.location.gps"  />
  1. I add the edit-config in config.xml and do a build again
<edit-config file="AndroidManifest.xml" target="/*/uses-feature[@android:name='android.hardware.location.gps']" mode="merge">
  <uses-feature
        android:name="android.hardware.location.gps"
		android:required="false" />
</edit-config>
  1. Build is successful and if I check the AndroidManifest.xml, now I have the android:required=“false” attributes added for the gsp. Between two builds, I have to remove the uses-feature for GPS in the AndroidManifest.xml at specified location to avoid a build error (message is : Element uses-feature#android.hardware.location.gps at AndroidManifest.xml:30:5-66 duplicated with element declared at AndroidManifest.xml:29:5-91 )

The cordova version installed on my PC is 10.0.0.

Best Regards,
Michael

Thanks - we’ll give this a try.

That was very helpful!

First, just a note if anyone is trying to duplicate this. This line needs to be added to the <widget spec:

xmlns:android="http://schemas.android.com/apk/res/android"

We were about to find the problem - VoltBuilder was doing the build steps in a different way. We can fix it, but we’ll need to do some careful testing. It will take a day or two.

Thanks for spotting this!

Great, thank you for the support.

Indeed, when describing the steps I forgot to tell we have an additional namespace to declare in widget.

Just for info, I did not explain why we need the GPS marked as not required. The APK we are building will be available on (Enterprise) Play Store which performs an app filtering according to the device capabilities. So if the GPS is marked as required, device without it (like old Zebra or tablet) will not see the application in the Store.

Best Regards,
Michael

Thanks for explaining the use case. We’re continuing to work on this issue.

We found a solution which worked well for your project, but broke many others. Back to the drawing board.

This might be a workaround:

Thank you for the status. I am not yet in a hurry and will wait for the edit-config solution but I keep in mind the workaround you proposed.

KR,
Michael

We’re still working on this one.

This turned out to be very interesting. I dug deep to find that the original setting for android.hardware.location.gps was being set in plugin.xml, within the code for cordova-plugin-geolocation. But wait: there was a conditional setting for its value so this should work:

    <plugin name="cordova-plugin-geolocation" source="npm">
      <variable name="GPS_REQUIRED" value="false" />
    </plugin>

Digging deeper, I found this was just added yesterday in version 4.1 of the control. But the problem was still happening!

From the VoltBuilder logs, it appears that npm still thinks 4.0.2 is the current version.

I opened an issue in the cordova-plugin-geolocation repo. I expect it will be fixed quickly by the plugin’s author.