Search code examples
androidcordovaionic-frameworkcapacitor

add attribute to capacitor-cordova-android-plugins ShareChooserPendingIntent receiver


In attempt to update the targetSdkVersion to 31 I have encountered this merge manifest error:

Error: android:exported needs to be explicitly specified for . Apps targeting Android 12 and higher are required to specify an explicit value for android:exported when the corresponding component has an intent filter defined.

The file causing this issue is capacitor-cordova-android-plugins/src/main/AndroidManifest.xml at application/receiver "nl.xservices.plugins.ShareChooserPendingIntent".

<receiver android:name="nl.xservices.plugins.ShareChooserPendingIntent" android:enabled="true">
  <intent-filter>
    <action android:name="android.intent.action.SEND"/>
  </intent-filter>
</receiver>

Build works fine when I manually add the attribute android:exported="false" to the receiver but the problem is that this file is regenerated upon sync/build.

How can I add this attribute without manually editing the file?


Solution

  • I had to use Capacitor CLI Hooks to rewrite the file as seen here.

    package.json:

    "scripts": {
        ...
        "capacitor:update:after": "cd scripts/capacitor-cordova-android-plugins && CapacitorCordovaAndroidPlugins",
        "capacitor:sync:after": "cd scripts/capacitor-cordova-android-plugins && CapacitorCordovaAndroidPlugins"
    }
    

    CapacitorCordovaAndroidPlugins.cs:

    where src is you path to the manifest file (stackoverflow was having trouble posting with that string???)

    using System;
    using System.IO;
    using System.Text.RegularExpressions;
    
    namespace CapacitorCordovaAndroidPlugins {
        public class App {
            [STAThread]
            static void Main() {
                string src = "";
    
                string content = File.ReadAllText(src);
                string pattern = @"(<receiver .*(?<!android:exported=""false""))(?=>)";
                string replacement = @"$1 android:exported=""false""";
    
                content = Regex.Replace(content, pattern, replacement);
    
                File.WriteAllText(src, content);
            }
        }
    }