Closed jzhouw closed 4 years ago
@JonDouglas : Wondering why this is tagged as an enhancement ? This feature is available in the android-system for a long time, and not at all available when using xamarin ? Any idea when this (for us a must have) will be available ?
@bartdkmediahuis Because at this time, our manifest merging does not support advance features similar to what I outlined in the Bugzilla link above. Thus we would be enhancing this feature to allow more complex merging scenarios.
We will be considering this in a future release given the 👍 count.
For me this is critical as 3rd party libraries often request permissions for features that are not going to be used by the application.
It's not only about removing unnecessary permission declaration.
Currently I'm working on an Android Things application and I'd like to run the app on a regular phone for testing purpose. So, as the Google documentation suggests, I just added the following attribute to the manifest:
<application ... >
<uses-library android:name="com.google.android.things" android:required="false"/>
</application>
And just look at what the manifest of the APK file contains:
<application ...>
<uses-library
name='com.google.android.things'
required='false'>
</uses-library>
...
<uses-library
name='com.google.android.things'>
</uses-library>
</application>
I can't believe it is still not implemented in 2018, the original bug report was submitted almost 2 years ago!
We really need full support for Androidmanifest tools. Currently as it stands if a library with permissions or metadata that needs merged or replaced, theres no easy way of achieving it. Basically makes developing Android applications with Xamarin useless unless you won't use any third party libraries, its a development environment breaking bug, not an enhancement.
This is a problem for me as well, I have a NuGet package forcing the camera permission so now I can't get my app installed for devices without cameras.
We need this as well! We are using the Firebase Cloud Messaging (FCM) library, and it automatically injects the Xxx.Yyy.Zzz.permission.C2D_MESSAGE
permission in the generated manifest. This is okay for most times, but we are experiencing that this causes the app installation to fail for thousands of our users because our Xxx.Yyy.Zzz
has capital letters!
This is from a Huawei user's bug report when trying to install our app:
Bad class name Xxx.Yyy.Zzz.permission.C2D_MESSAGE in package Xxx.Yyy.Zzz
Another user reported this as well in the original GCM library
Not having the ability to remove permissions requested by a 3rd party library means that users of our app must accept a permission that it doesn't use. Described here: https://forums.xamarin.com/discussion/comment/360660 So, I support this feature request.
I need this for managing 3rd party library permissions. Unused permissions added to the AndroidManifest.
Any plans to implement Android tools for manifest merging?
you should fix this issue as fast as you can, it's a big problem for many of us
That PR #3066 added the following targets AfterGenerateAndroidManifest and BeforeGenerateAndroidManifest.
AfterGenerateAndroidManifest will run directly after the internal _GenerateJavaStubs target. This is where the AndroidManifest.xml file is generated in the $(IntermediateOutputPath). So you you want to make any modifications to the generated AndroidManifest.xml file you can do this using this extension point. Documentation on how to use the new target is over at https://github.com/xamarin/xamarin-android/blob/master/Documentation/guides/BuildProcess.md#build-extension-points
While this is not a full implementation of the google manifest tooling (which will take a lot of work to implement) this does allow developers to modify the AndroidManifest.xml after it has been generated. The Unit Test added in that PR contains an example of adding xml to the AndroidManifest.xml using XmlPoke
and this new entry point. See https://github.com/dellis1972/xamarin-android/blob/30f7849ec3f4deec224c2bb536affa7ce0437c31/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/ManifestTest.cs#L500.
Thanks @dellis1972'.
Ended up using the solution below to remove 3rd party permissions.
In the .csproj file, add the following:
<PropertyGroup>
<AfterGenerateAndroidManifest>
$(AfterGenerateAndroidManifest);
Remove3rdPartyPremisesFromAndroidManifestXML;
</AfterGenerateAndroidManifest>
</PropertyGroup>
<Target Name="Remove3rdPartyPremisesFromAndroidManifestXML">
<!-- Remove user permissions from AndroidManifest.xml that have the attribute tools:node="remove" (similar to how it's done by the typical android manifest merge) -->
<!-- The transformed xml file will be temporarily placed in the folder "build-tasks" -->
<XslTransformation
XmlInputPaths="$(IntermediateOutputPath)android\AndroidManifest.xml"
XslInputPath="build-tasks\android-manifest-tools-remove-permissions.xsl"
OutputPaths="build-tasks\AndroidManifest.xml" />
<!-- After the transformation, copy the file "$(IntermediateOutputPath)android" to replace the original file. -->
<Copy
SourceFiles="build-tasks\AndroidManifest.xml"
DestinationFolder="$(IntermediateOutputPath)android\"/>
<!-- Remove the temp file -->
<Delete Files="build-tasks\AndroidManifest.xml" />
</Target>
And here's the android-manifest-tools-remove-permissions.xsl
which is used in the XslTransformation
task
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*" />
<xsl:variable name="removed-permissions" select=".//uses-permission[@tools:node='remove']" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="uses-permission">
<xsl:variable name="name" select="@android:name" />
<xsl:if test="count($removed-permissions[@android:name = $name]) = 0">
<xsl:copy-of select="." />
</xsl:if>
</xsl:template>
</xsl:stylesheet>
This will work in the same way android manifest merge works, for example:
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" tools:node="remove"/>
@mayhammf Glad the extension point helped you work around this issue.
A similar solutions to @mayhammf is that im using a python script set in the Android csproj options under 'Custom Command', i add a new command set "After Build". i set the command as so python remove.py ${ProjectConfig}
The script is as follows:
import os
import sys
path = "./obj/" + sys.argv[1] + "/android/"
print 'Manifest Path:',path
os.rename(path + "AndroidManifest.xml", path + "AndroidManifestOld.xml")
remove = "manifest tag to remove"
with open(path + 'AndroidManifestOld.xml') as oldfile, open(path + 'AndroidManifest.xml', 'w') as newfile:
for line in oldfile:
if (remove not in line):
newfile.write(line)
os.remove(path + "AndroidManifestOld.xml")
it simply removes the line that you dont need, in my case it was an extra service tag from a 3rd party library.
@gmoney494 the problem with using After Build is when you touch the manifest file you will change the timestamp, that might cause knock on effects and break the incremental build system we have.
We merged the manifest merger tooling recently, https://github.com/xamarin/xamarin-android/pull/4045 this should be available to enable in the next d16-5 preview. You can enable it by setting
<AndroidManifestMerger>manifestmerger.jar</AndroidManifestMerger>
in your csproj. You can then use the xmlns:tools="http://schemas.android.com/tools"
namespace as specified here https://developer.android.com/studio/build/manifest-merge
Given we now support a better AndroidManifest.xml
merging tool via https://docs.microsoft.com/en-us/xamarin/android/release-notes/10/10.2#improved-android-manifest-merging
I am closing this issue as done!
this request is similar to this bugzilla item https://bugzilla.xamarin.com/show_bug.cgi?id=52857 really needed this to override unneeded permission requests which added by 3rd party libraries.