From c95aff3d3f5f695cfc929a86675d3d0d56d5456f Mon Sep 17 00:00:00 2001 From: DravenLee <37170420+bo-516@users.noreply.github.com> Date: Thu, 8 Oct 2026 17:01:29 +0800 Subject: [PATCH] fix(android): keep plugin annotation types from R8 full mode R8 full mode removes annotation instances that Capacitor only reads through reflection. PluginHandle.pluginAnnotation and legacyPluginAnnotation are dropped, so getAnnotation() is null at runtime. The null check in getPermissionStates stops that crash, but requestPermissions still NPEs on the null annotation. Keep the annotation interfaces in the consumer ProGuard rules. --- android/capacitor/proguard-rules.pro | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/android/capacitor/proguard-rules.pro b/android/capacitor/proguard-rules.pro index 96db065b39..4fe4e3f2e0 100644 --- a/android/capacitor/proguard-rules.pro +++ b/android/capacitor/proguard-rules.pro @@ -15,11 +15,18 @@ -keep public class * extends com.getcapacitor.Plugin { *; } +# The annotation types are read at runtime via reflection. If they are not kept, R8 full mode +# treats them as never instantiated and optimizes the annotation cached in PluginHandle to null, +# even with -keepattributes *Annotation*. +-keep @interface com.getcapacitor.annotation.** { *; } +-keep @interface com.getcapacitor.PluginMethod { *; } + # Rules for Capacitor v2 plugins and annotations # These are deprecated but can still be used with Capacitor for now -keep @com.getcapacitor.NativePlugin public class * { @com.getcapacitor.PluginMethod public ; } +-keep @interface com.getcapacitor.NativePlugin { *; } # Rules for Cordova plugins -keep public class * extends org.apache.cordova.* {