Easy way
I think this simpler approach applies if your Unity project is built using gradle . If this is not the case, here is another reason to upgrade.
Also, a big cry in an article called " Hey, where did these permissions come from? )
- Create your own project
- Open the file /path/to/my/project/Temp/gradleOut/build/outputs/logs/manifest-merger-release-report.txt
Profit!- Locate the file with the name of your permission and it will show you where it came from.
Here is the part of the file where I am looking for WRITE_EXTERNAL_STORAGE permission.
uses-permission#android.permission.WRITE_EXTERNAL_STORAGE ADDED from /Users/clinton/Projects/<<ProjectName>>/Temp/gradleOut/src/main/AndroidManifest.xml:7:3-79 MERGED from [gradleOut:IronSource:unspecified] /Users/clinton/Projects/<<ProjectName>>/Temp/gradleOut/IronSource/build/intermediates/bundles/default/AndroidManifest.xml:13:5-81 android:name ADDED from /Users/clinton/Projects/<<ProjectName>>/Temp/gradleOut/src/main/AndroidManifest.xml:7:20-76
Hard way
Three permissions are added to your project.
- They are listed in the Android manifest file.
- They are listed in the library (.aar file).
- Unity adds permission when you use a specific function. (Added)
My examples use command-line tools on a Mac. I do not know the equivalents of Windows, but there you can find and run unix tools (using the linux subsystem for Windows 10, cygwin, custom binaries, etc.),
1. Find all permissions used in (uncompressed) Android Manifests.
cd /path/to/my/project/Assets grep -r "uses-permission" --include "AndroidManifest.xml" .
This will detect all files with the name AndroidManifest in the current folder ( . ) Or in any of its subfolders ( -r says that it searches recursively) and spits out any line with the words "use-permission".
In my current project, I get the output something like this:
./Plugins/Android/AndroidManifest.xml: <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> ./Plugins/Android/AndroidManifest.xml: <uses-permission android:name="android.permission.INTERNET" /> ./Plugins/Android/AndroidManifest.xml: <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> ./Plugins/Android/AndroidManifest.xml: <uses-permission ./Plugins/Android/IronSource/AndroidManifest.xml: <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> ./Plugins/Android/IronSource/AndroidManifest.xml: <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
2. Find the permissions required for Android libraries
Your project probably contains android libraries (.aar files) and java archives (.jar files). Some Android libraries contain the android manifest and specify the permissions required to use the library. (I donโt think that .jar files actually do this, but .aar files do not work at all). Both .aar and .jar files are .zip files with a different extension and specific metadata in specific places.
Find them by running:
find . -iname "*.?ar" -print -exec zipgrep "uses-permission" "{}" "AndroidManifest.xml" ";" 2> /dev/null
Here is what it does. It finds any file (in the current folder ( . ) And its subfolders) has the extension (something) ar, thus .jar or .aar ( -name "*.?ar" ). It displays the name of the archive file ( -print ). Then it starts zipgrep ( -exec ). Zipgrep is invited to search for any files in the archive ( {} ) called "AndroidManifest.xml" and display any line with the words "use-permission". Then we pass the errors to the bucket bit ( 2>/dev/null ), so we do not see many errors in archives that do not have an Android manifest in them.
An example output is as follows:
./OneSignal/Platforms/Android/onesignal-unity.aar AndroidManifest.xml: <uses-permission android:name="android.permission.INTERNET" /> AndroidManifest.xml: <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> AndroidManifest.xml: <uses-permission android:name="android.permission.WAKE_LOCK" /> AndroidManifest.xml: <uses-permission android:name="android.permission.VIBRATE" /> ... ./Plugins/Android/android.arch.core.common-1.1.0.jar ./Plugins/Android/android.arch.core.runtime-1.1.0.aar ./Plugins/Android/android.arch.lifecycle.common-1.1.0.jar ... ./Plugins/Android/com.google.android.gms.play-services-gcm-11.8.0.aar AndroidManifest.xml: <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> AndroidManifest.xml: <uses-permission android:name="android.permission.INTERNET" /> ./Plugins/Android/com.google.android.gms.play-services-gcm-license-11.8.0.aar ./Plugins/Android/com.google.android.gms.play-services-iid-11.8.0.aar AndroidManifest.xml: <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> AndroidManifest.xml: <uses-permission android:name="android.permission.INTERNET" /> ./Plugins/Android/com.google.android.gms.play-services-iid-license-11.8.0.aar ...
File names begin with periods. Thus, I can see, for example, that singleignal-unity.aar sets several permissions, several .jar files were searched without any permissions inside them, and some game service libraries set permissions.
If I needed to change the library, I could rename .aar to .zip, extract it, edit, compress and rename. (It is not necessary to intelligently change permissions within the library, but it is possible.)
3. Unity Adds Permission
I had nothing to add; as said above, if you use the microphone API, Unity will add you permission to make your application work.
However, since then I realized that you can do the following:
- display build settings for Android
- check the box "Export project"
- Export the project by marking the location
- go to /my/project/export/src/main/AndroidManifest.xml. This is what Unity emits for the Android manifest (before google tools do all the merging).
- compare it (using your favorite diff tool) with Assets / plugins / Android / AndroidManifest.xml; differences come from Oneness.