Unity Gradle & maxSdkVersion

I was working on some improvements for Gallery API, and after minor changes, whole Camera & Gallery API just stopped working.

The reason I was getting from the log was:

Exception 'open failed: EACCES (Permission denied)' 

Wich looks like I do not have proper permission to work with the external storage (I was trying to save an image to the device gallery). I was frustrated since I had following permissions I manifest + that API was working perfectly before.

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

But since AndroidManifests are merged when you''re making an apk build, I was wondering if my permissions are 100% there. So I used an aapt to find out if I have permissions set in my apk.

The aapt tool can be found inside android SDK build tools. In my case, it was located under 

C:\Users\<User-name>\AppData\Local\Android\Sdk\build-tools\<version>\aapt.exe

After using a command that will print all permissions form provided apk

aapt d permissions <path-to-apk>

I found that my storage permissions look a bit weird:

uses-permission: name='android.permission.WRITE_EXTERNAL_STORAGE' maxSdkVersion='18'
uses-permission: name='android.permission.READ_EXTERNAL_STORAGE' maxSdkVersion='18'

So maxSdkVersion means, that this permission will only be requested with platforms that equal or bellow maxSdkVersion. Mine was above 18, so it's safe to say that it wasn't part of the app.

After a bit more googling I found some contradictory statement's..

  • After API level 18 WRITE_EXTERNAL_STORAGE & READ_EXTERNAL_STORAGE are granted automatically. - Well, make sense then why maxSdkVersion set to, but why do I have Permission denied then.
  • Starting from Android 6.0 - API level 23 all you may aks user approval before using Dangerous permissions and WRITE_EXTERNAL_STORAGE & READ_EXTERNAL_STORAGE are part of STORAGE permission Group - Well' that's true. Here is an Android Documentation link. But statement was no matter what you need to request the permissions explicitly (haven't found verification for that statment)

But here is few more lines from Android Documentation, same article link as above:

For example, the READ_EXTERNAL_STORAGE permission is enforced beginning with API level 19 to restrict access to the shared storage space. If your targetSdkVersion is 18 or lower, this permission is added to your app on newer versions of Android.

So I tried to use Runtime Permissions API to request permission before using it. No luck as well. API was telling me that I do not have this permission, but when I tried to start and approval dialog, there was no dialog box shown by a system.

After a little bit more investigation, I found that  I only have this issue when Unity build set to Gradle, If I build with Internal, there is no issue like this, and I my output from aapt  looks like this:

uses-permission: name='android.permission.WRITE_EXTERNAL_STORAGE'
uses-permission: name='android.permission.READ_EXTERNAL_STORAGE'

And of course,  API started to work again.

Make sense for me so far, It means that maxSdkVersion was simply removing this permission for my APP since the platform was at a higher API level. And since permission wasn't mentioned for an app RequestPermissions method will not do a thing.

The next step was to try to add permission modifications like tools:remove="android:maxSdkVersion" 

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:remove="android:maxSdkVersion" />

or tools:node="replace"

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="replace"/>

no luck so far.