So after some time I finally solved the problem while trying to make a stripped down project to submit as a bug report…
The cause was that external libraries in the project had their own manifest files, and were overwriting this line in my manifest:
\<uses-permission android:name="android.permission.WRITE\_EXTERNAL\_STORAGE" /\>
with this from their manifests:
\<uses-permission android:name="android.permission.WRITE\_EXTERNAL\_STORAGE" android:maxSdkVersion="18"/\>
The solution was to add this line:
\<uses-permission android:name="android.permission.WRITE\_EXTERNAL\_STORAGE" android:maxSdkVersion="23" tools:replace="android:maxSdkVersion" /\>
I haven’t tested on devices running 6.0+ to see how this line affects them, but it has fixed the issue on < 6.0
For future reference, I found it by looking at this file:
MyProject/Android/android/app/build/outputs/logs/manifest-merger-release-report.txt
Which will show something along these lines:
MERGED from com.company.theirLibrary:1.0.1 android:maxSdkVersion ADDED from AndroidManifest.xml:21:76
where com.company.theirLibrary will show the name of the library causing the issue.
I think that anyone using the old Ant methods probably wouldn’t run into this because you have to set everything in the manifest manually. As I’m using Android Studio and pulling the libraries in using Gradle, those manifest entries were kind of “hidden” until I went searching for the cause of the issue.