Android: How do I add custom uses-feature/uses-permission?

Hi JUCE devs - I was wondering what the expected process would be to add custom uses-permission and uses-feature items to the AndroidManifest.xml?

I noticed this option in the Projucer/Android exporter exists, but adding anything there completely clobbers the manifest file:

For example, here’s the outcome of adding <uses-permission android:name="android.permission.BATTERY_STATS"/> to the DemoRunner’s Android exporter (link to the original here for a quick comparison). Note that this is just a random example.

<?xml version="1.0" encoding="utf-8"?>

<uses-permission android:name="android.permission.BATTERY_STATS" xmlns:android="http://schemas.android.com/apk/res/android"
                 android:versionCode="1" android:versionName="8.0.8">
  <supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:anyDensity="true"
                    android:xlargeScreens="true"/>
  <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28"/>
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32"/>
  <uses-permission android:name="android.permission.READ_MEDIA_VIDEO"/>
  <uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
  <uses-permission android:name="android.permission.READ_MEDIA_AUDIO"/>
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" android:maxSdkVersion="30"/>
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="30"/>
  <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30"/>
  <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30"/>
  <uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
  <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE"/>
  <uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation"/>
  <uses-permission android:name="android.permission.CAMERA"/>
  <uses-permission android:name="android.permission.RECORD_AUDIO"/>
  <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
  <uses-permission android:name="android.permission.INTERNET"/>
  <uses-feature android:glEsVersion="0x00030000" android:required="true"/>
  <application android:label="@string/app_name" android:name="com.rmsl.juce.JuceApp" android:icon="@drawable/icon" android:hardwareAccelerated="false">
    <receiver android:name="com.rmsl.juce.Receiver" android:exported="false"/>
    <activity android:name="com.rmsl.juce.JuceActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|navigation|smallestScreenSize|screenLayout"
              android:launchMode="singleTask" android:hardwareAccelerated="true" android:exported="true">
      <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
      </intent-filter>
    </activity>
    <provider android:name="com.rmsl.juce.JuceSharingContentProvider" android:authorities="com.rmsl.jucedemorunner.sharingcontentprovider"
              android:grantUriPermissions="true" android:exported="true"/>
  </application>
</uses-permission>

IMO, my preference is that Projucer shouldn’t do anything fancy here - my expected UX would have been to insert the XML data as directly possible, and overwrite anything that JUCE generates.

I’m just realising now that this box is intended to be a direct replacement of the AndroidManifest.xml, or something (?) like that. Weird!

I haven’t taken a look, but just based on what you’ve shared, what happens if you add this to the Projucer?

<manifest>
  <uses-permission android:name="android.permission.BATTERY_STATS"/>
</manifest>

My guess is that it tries to merge the two XMLs and so I think it’s assigning your “uses-permission” as the root node rather than a child of “manifest”.

Yep, that does it - here’s the end result at a glance using the DemoRunner again:

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="8.0.8">
  <uses-permission android:name="android.permission.BATTERY_STATS"/>