Forum Xamarin.Android

manifest merging in Xamarin.Android

Our 3rd party Android library's manifest declares uses-permission entries for android.permission.BLUETOOTH and android.permission.BLUETOOTH_ADMIN, but our app does not use those bluetooth capabilities. As a result, our users see these app permissions during installation from GooglePlay, which creates confusion.

I have tried using the manifest merging approach by adding these lines to our app's manifest:

<uses-permission android:name="android.permission.BLUETOOTH" tools:node="remove" />

However, it does not change what appears in the permissions list during app installation from Google Play.

Then I discovered @xakpc 's post saying that Xamarin does not support manifest merging. I see bug 24809, but it is marked as resolved.

If this issue is still outstanding, then I suspect that I would need to implement something like what @AlexanderMelchers did in this post.

Do I have this right? Please tell me it's much simpler than this! :/

Answers

  • stepheawstepheaw Member ✭✭

    Any update @PhilipHadley ?

  • PhilipHadleyPhilipHadley USUniversity ✭✭

    @stepheaw

    Update from Microsoft on 10/23:

    I’ve spoken with one of the Xamarin.Android developers, and we did confirm the same behavior you are seeing. MSBuild does not appear to accept modified manifest elements, and reverts the change. The workaround you found in the forum post does seem to be the best way to correct this, although it is not desired.

    Due to the complexity of the workaround and the low priority/severity of the bug, our team opted not to fix, for now. I have requested to be notified when a fix is available, so I will provide another update when that happens.

  • JonDouglasJonDouglas USXamarin Team, University, Developer Group Leader Xamurai

    @PhilipHadley

    I believe the closer item would be this feature:

    https://bugzilla.xamarin.com/show_bug.cgi?id=52857

    I highly recommend reporting a new feature request in our github repo and backlink to this bug:

    https://github.com/xamarin/xamarin-android/issues

  • oguzhanorhaanoguzhanorhaan TRMember ✭✭

    Any update ?

  • PhilipHadleyPhilipHadley USUniversity ✭✭

    @oguzhanorhaan
    I have not been notified of any fix for this.

    I see that this feature request was submitted: https://github.com/xamarin/xamarin-android/issues/1335

  • Ended up with 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"/>
    
  • Gmoney494Gmoney494 USMember ✭✭
    edited January 2020

    @AyhamFakihani When i add the tools:node="remove" i can build as i get a error XAGAP7000: System.Xml.XmlException: 'tools' is an undeclared prefix. Any help? Your workaround sounds great, as it automates having to manually delete the permission. In my case i need it to remove a duplicate permission that cancels mine out.

    Edit: Nvm, i saw the tools url, but i still cant get it to work with that as i have a service tag i need removed, not a uses-permission. Will try to edit to see if it works.

  • Gmoney494Gmoney494 USMember ✭✭

    I ended up doing a similar solution 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.

    I managed to get @AyhamFakihani version working, however it would remove all the tags with the same name, including the one i set and need. My route just removes the exact line.

  • DonMesserli.1843DonMesserli.1843 USMember ✭✭✭

    @AyhamFakihani

    If I add xmlns:tools="http://schemas.android.com/tools" to the manifest section of my AndroidManifest.xml, I get errors in styles.xml

Sign In or Register to comment.