Why does my Xamarin Android application suddenly require external storage permissions? - android

I have a Xamarin Android application I've been trying to create an update for. Right when everything was hooked up and working, and I finally made the release APK, I get a message from Google Play that the uploaded APK now requires two extra permissions. For reading and writing to external storage! I don't need these permissions in my application at all. I tried looking at my project's Android Manifest, and saw no such permissions listed there. Older versions of my application (using older versions of Xamarin Android) did not require these permissions. Why would Xamarin suddenly be injecting permissions I didn't specify?
I can confirm that this is the case with any application. I just created a new android app with it, and it requires external read/write permissions, with no apparent way to disable that requirement

Look in AssemblyInfo.cs, default template has this on the bottom of it:
[assembly: UsesPermission(Android.Manifest.Permission.Internet)]
[assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage)]
Permissions can be set either through the AndroidManifest.xml file or through AssemblyInfo.cs. Delete those lines, and the permissions should not be set anymore.

Permissions from packages/components
Now that Xamarin Components and Xamarin-friendly NuGet packages are everywhere, it is worth noting that permissions can now be brought in by way of AssemblyInfo.cs from those references as well.
Since some libraries would be useless without certain permissions, this can make sense to avoid issues. However, if they aren't needed all the time, you can be introducing permissions you don't actually want simply by referencing a new package or component.
For optional permissions baked into the NuGet package, you may need to compile your own library without them to avoid the extra permission overhead. I haven't found a great way to easily identify these in packages where the source code isn't freely available. ILSpy didn't seem to output the AssemblyInfo.cs attributes.
Unfortunately, in old Xamarin.Android project templates, these permissions were added by default with a message that you could remove them if you didn't need them.
// Add some common permissions, these can be removed if not needed
[assembly: UsesPermission(Android.Manifest.Permission.Internet)]
[assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage)]
Since they are such common permissions, most authors and consumers of the library wouldn't notice (as may have happened here in the Settings library from Xam.PCL.Plugins).

Related

Unity Android wants BROADCAST_STICKY, BLUETOOTH, and MODIFY_AUDIO_SETTINGS for Microphone access

I have a problem where Unity is requiring too many permissions. Before, I was building with Unity 2017, and my app needed three android permissions. These are the only ones I think I need:
android.permission.RECORD_AUDIO
android.permission.INTERNET
android.permission.ACCESS_NETWORK_STATE
Now, I've upgraded to 2019.2.21f1, and I discovered a few extra permissions were added without changing the code:
android.permission.MODIFY_AUDIO_SETTINGS
android.permission.BROADCAST_STICKY
android.permission.BLUETOOTH
I've gone through all my code, deleting bits of it, until I found the line that caused these permissions to appear in my merged manifest (I was checking the manifest-merger-release-report) -- it's a reference to the list of microphones: Microphone.devices. When I make a reference to that, the permissions appear.
I need to reference this string array because I need to call Microphone.Start somewhere in order to get audio input, but I don't care about bluetooth or broadcasting stickies. I don't want to use any of these new permissions. Does anyone know why using Microphone.devices would cause these permissions to appear?
In the build settings, my minimum API level is 16, and the target API level is highest installed.
I don't want to downgrade my Unity version again. I want to find a way to just require the RECORD_AUDIO permission, without the three new ones -- the only other option is to not use the Microphone, which will make my game less fun. Boo hoo.
Now i don't think this answer will be of much help but since you seem pretty desperate, as in out of options since this is a problem in unity's core system, could you not try to instead use a different microphone library than the one builtin to unity?
For example i found this:
NatDevice is a cross-platform media device API for iOS, Android, macOS, and Windows. NatDevice provides powerful abstractions for using hardware cameras and microphones through a concise .NET API.
https://assetstore.unity.com/packages/tools/integration/natdevice-media-device-api-162053
You could also roll your own with native android code, like this guy describes:
https://support.frozenmountain.com/hc/en-us/community/posts/115000768894-Unity-Android-Audio-Capture-Provider
You can do it using a Unity "plugin":
https://docs.unity3d.com/Manual/PluginsForAndroid.html
Their docs go into more detail, but the general idea is that you want
to write the app component that uses the native library using Java,
and then activate it from C#. This avoids a lot of expensive
cross-calls between the two runtimes. Using this approach, you would
extend RtcLocalMedia in Java along with the rest of your component
code, and then activate that component from C#.
Another option is to completely overwrite the manifest file to exclude the permissions you don't want (although you need to make sure it all works still, because unity could still depend on them)
A good description is here:
https://stackoverflow.com/a/40931309/4122889
Hope this atleast gave you some ideas.
You will need to include these permissions if you would like to use microphone built into Bluetooth headset. They are required by AudioManager when using Bluetooth microphone.

Some questions regarding libraries in Android

I am writing an SDK to be used in other applications, to enable them to use our service. Obviously, I am writing a library for that.
Note that user here means user of SDK.
The questions:
I need to have an activity in my library. Do users have to declare my activity in their application to use it? Can I have activity defined in the manifest of my library, export library as aar? Does this work?
My library needs some permissions, like to check if internet is available or not. Like the above issue, can I have my permissions defined in manifest of my library?
aar or jar? What is the difference, beside the things mentioned in Google docs. Any support issues with aar, idk like lower API versions not supporting it or other IDEs (Eclipse? Still used?) not supporting it? I mean some practical issues with aar, if there is any.
I'm also open to any documentation or any link to help me.
I have developed for Android in the past, last time was when Android Studio was just released in alpha. It seems like a new world now :)
I need to have an activity in my library. Do users have to declare my activity in their application to use it? Can I have activity defined in the manifest of my library, export library as aar? Does this work?
Users don't need to declare library activities in app manifest. It will work. But don't forget to declare theme inside your library style file and apply on your activities(Activities which are in library).
My library needs some permissions, like to check if internet is available or not. Like the above issue, can I have my permissions defined in manifest of my library?
All permissions which you need inside library module you can mention it inside library manifest. But you have to take care of asking risky permissions. Let say if your library need WRITE_EXTERNAL_STORAGE permission so whenever you are going to call library activity you need to ask such permission at run time. You will get more here
aar or jar? If you are going for pure android then go for aar. You will get more discussion on here
aar or jar?
both:
jar (standard non-android-library) with android independant code (java-interfaces, java-datastructures, datatransportation via webservice, businesslogic, ......).
benefit: the jar can be junit-tested without android on a desktop pc
benefit: the jar can be reused in java desktop apps.
aar (android specific library) gets the android specific data/code (manifest with requested-internet-permissions, activity with resources, code for requesting android permissions, android-sqlite-database).
the aar has dependencies to the jar
I successfully use this seperation in my android projects ToGoZip and APhotoManager

What goes into AndroidManifest of a library project?

I have an Android library that contains an activity. Yet it does not appear to matter whether I include the activity in the element or not. As long as I put the full 'path' to the activity in my application that uses the library is done, I can run the activity.
Also, the package value in the manifest seems to be arbitrary. It does not have to correspond to the java package of the library classes. It seems to only be used by the generation of the R values.
What SHOULD the package value be in my AndroidManifest of the library project?
When (if ever) do I need to include some information in the element?
What SHOULD the package value be in my AndroidManifest of the library project?
Something reasonably unique, so it does not collide with other libraries that the app might use. Otherwise, AFAIK, the value only controls code generation (e.g., R), as you noted.
When (if ever) do I need to include some information in the element?
I do not know what "the element" is.
What goes into AndroidManifest of a library project?
Anything that the library wants to merge into the app's manifest:
Components (e.g., <activity>) that the hosting app is sure to need
<uses-permission> elements, for any permissions required by the library
<uses-feature> elements, for any hardware features required by the library
And so on
If your app is the only app that will be using the library, the dividing line between what goes into the library's manifest and what goes into the app's manifest is really up to you and is somewhat arbitrary. If, OTOH, the library will be used by multiple apps, particularly ones that you are not writing, try to craft the library's manifest to minimize headaches for the app developers:
Forcing app developers to add manifest entries, for things that are always needed, is a headache
Forcing app developers to add manifest-merger control attributes (e.g., tools:replace), because the library asks for things that the app does not need, is a headache
Adding things in the manifest that weaken app security (e.g., unnecessary <intent-filter> elements) is a headache
And so on

Android Studio: Can permission inspections be permanently ignored using annotations?

I'm developing an Android library which provides ways to reach into various system services and gather data for analysis. My classes make use of various system service managers (like WifiManager) to gather the data.
I'd like to structure the manifest of my library such that it doesn't grab all the possible permissions that all of these features require. Instead, I'd like to leave it up to the app consuming that library to declare only the permissions that it will need, which might be a smaller subset of what's used by the library.
This actually works in practice, because the manifests all get merged together during the build process, so the app ends up with the permissions it needs to use the features of the library. However, since the <uses-permission> tag isn't in the library's manifest, the code is all lit up with warnings from Android Studio.
Is there a way to annotate my library code such that the permission check is ignored?
Of course I can simply turn off the "Constant and Resource Type Mismatches" inspection in my Android Studio settings, but that won't help anyone else who's trying to use the library. I tried finding a reference to this inspection in the documentation (so I could kill it with #SuppressWarnings but haven't found it yet.
Is this even a worthwhile approach?
…or should I, instead, have the library grab all the permissions it needs, which would force a consumer of the library to turn off the ones it doesn't need using the tools:node="remove" property in its manifest? The problem here is that, as I add features to my library, my library's consumers would repeatedly have to circle back and explicitly remove those new permissions as well. I feel like that's not a great model and I'd rather leave the permission requests to my consumers.
Consider the following conversations on the subject —
Android: New permissions added behind my back after library updates (StackOverflow)
Hey, Where Did These Permissions Come From? (CommonsBlog)
In just randomly right-clicking around the issue I was able to choose the Suppress for method context command in Android Studio and it added the following annotation:
#SuppressWarnings( "ResourceType" )
So… yay! There's the answer to which annotation to use.
I'm still interested, though, in what people's thoughts are regarding the approach in general. Please feel free to hash that out in the answers section. ^_^

Android: find the method that uses a specific permission

I've got the source code for an Android app and its manifest includes a lot of uses-permissions, some of which I think it doesn't need. Aside from testing the whole app, is there an easy way to find which classes or methods use a specific permission?
delete all permission in Manifest, then run App. Then the logcat will show you what permission needed.
As this paper points out, the API documentation is frequently wrong about which permissions are needed, and many application are 'over-privileged' meaning the manifest declares permissions which are not necessary for the classes and methods used.
Unfortunately, the Stowaway tool described in the paper is currently off-line, and I know of no other tool that is specifically designed to perform the analysis you're looking for. One problem with such a tool is that the method->required permissions mapping must re-accomplished based on the Android source code every time a new version is released. The paper is based on Gingerbread and obviously a lot has changed since then. Maybe they are having trouble keeping it relevant.
So at this point, the quickest way to do a one-off check would be to remove all of the permissions and then add them back one-by-one based on the security exceptions you see in the logcat.

Categories

Resources