proguard causes a crash in google play services' ActivityRecognitionResult getMostProbableActivity - android

I've recently released an app to the play store, and while it works perfectly fine without proguard, i've got an unexpected crash when i did decide to use it.
I've looked here for the recommended proguard rules for google play services, i've also tried adding another line for this case. Here's what I got (the third line is for my app):
-keep class * extends java.util.ListResourceBundle {
protected Object[][] getContents();
}
-keep class * implements com.google.android.gms.internal.ae
-keep class * extends il.co.kix.minitasker.EntityBase
Here's the crash report after doing a retrace
android.os.BadParcelableException: Parcelable protocol requires a Parcelable.Creator object called CREATOR on class com.google.android.gms.location.ActivityRecognitionResult
at android.os.Parcel.readParcelable(Parcel.java:2086)
at android.os.Parcel.readValue(Parcel.java:1965)
at android.os.Parcel.readMapInternal(Parcel.java:2226)
at android.os.Bundle.unparcel(Bundle.java:223)
at android.os.Bundle.containsKey(Bundle.java:271)
at android.content.Intent.hasExtra(Intent.java:4116)
at com.google.android.gms.location.ActivityRecognitionResult.boolean hasResult(android.content.Intent)(Unknown Source)
com.google.android.gms.location.DetectedActivity getMostProbableActivity()
at il.co.kix.minitasker.ActivityRecognitionIntentService.void onHandleIntent(android.content.Intent)(Unknown Source)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.os.HandlerThread.run(HandlerThread.java:60)
The offending lines of code probably are:
...
#Override
protected void onHandleIntent(Intent intent) {
if (ActivityRecognitionResult.hasResult(intent)) {
ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent);
DetectedActivity mostProbableActivity = result.getMostProbableActivity();
...
Can anyone help out with a rule to add? I don't want to disable it all together but it does fix the issue.

The Android runtime accesses these CREATOR fields by means of reflection, which is generally impossible to detect using static analysis. You therefore need to tell ProGuard to preserve them:
-keepclassmembers class * implements android.os.Parcelable {
static ** CREATOR;
}
This doesn't seem to be a standard setting in android-sdk/tools/proguard/proguard-android.txt, but it probably should be.

This problem drove me insane. Proguard is stripping internal classes that are not explicitly imported. Even worse, this problem did not exist for me (after using Proguard) then one day is suddenly showed up after a few little code changes.
I added a swathe of Proguard flags to fix the issue. In the end, I am not sure which one did the trick:
Definitely add these three:
-keep class android.os.Parcelable.Creator
-keep class com.google.android.gms.location.ActivityRecognitionResult
-keep class com.google.android.gms.** {*;}
You can also try:
-dontshrink
-dontoptimize
at the top
Honestly it's a dependency-walker type problem and Proguard should be better than this, but I did eventually fix it as above.

Related

Is there any proguard rules should use while using EncryptedSharedPreferences?

before using EncryptedSharedPreferences my app works fine in release mode with (minifyEnabled = true), After adding the security library (version 1.0.0-rc01) to my application the app crash while opening and if i use (minifyEnabled = false) the app works fine, i think i missing something to add it in proguard-rules.pro but i have searched a lot did not found anything.
Looks like something wrong with Tink obfuscation. My current workaround is add this rule to proguard:
-keep class com.google.crypto.tink.** { *; }
But also keep track of updates of issue here.
UPDATE - 06.01.2020
There is more effective solution (thanks #jtsalva to pointing out):
-keepclassmembers class * extends com.google.crypto.tink.shaded.protobuf.GeneratedMessageLite {
<fields>;
}
UPDATE - 08.19.2020
This issue should now fixed in Version 1.0.0-rc03
This issue has been answered with a more targeted proguard rule here
-keepclassmembers class * extends com.google.crypto.tink.shaded.protobuf.GeneratedMessageLite {
<fields>;
}
This saves my app ~0.2MB compared to the currently accepted answer
i try all above . not working for my case.
this what i do and work perfect:
-keepclassmembers class * extends com.google** {
<fields>; }

‘abstract method not implemented’ on start android app with Crashlytics (Fabric)

I added Crashlytics to my android app (via Idea plugin).
When my app starts I get next error:
java.lang.AbstractMethodError: abstract method not implemented
at io.fabric.sdk.android.ActivityLifecycleManager$ActivityLifecycleCallbacksWrapper$1.onActivityStarted(ActivityLifecycleManager.java)
at android.app.Application.dispatchActivityStarted(Application.java:199)
at android.app.Activity.onStart(Activity.java:1048)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:536)
I completely can't figure out why this happens. Maybe someone faced with this issue?
As mentioned above (by Chris), proguard stripping out something it isn't able to discern as being used. And it really stripping Crashlytics/Fabric classes.
For avoid this, just need add these lines to proguard config file:
-keep class com.crashlytics.** { *; }
-keep class io.fabric.** { *; }
-dontwarn com.crashlytics.**

Proguard configuration when using Android Studio's Google Cloud Endpoints template

We need to store and retrieve the content that users generate with our app online. To do so, we decided to use Android Studio's integrated Google Cloud Endpoints template to quickly create an API (official usage example here).
It works fine in debug, but in release mode, with Proguard enabled, it fails. Worse still, I've failed to find any documentation or samples about using Proguard with the Android Studio's Endpoints templates.
After an hour or so of poking around and trying to make it work, the proguard-rules.pro now looks like this:
-keep class com.google.api.** { public *; }
-dontwarn com.google.api.**
-keep class com.google.common.** { public *; }
-dontwarn com.google.common.**
# Not allowed to post company and app names, but this line is correct in the real file
-keep class com.companyname.appname.application.backend.** { *; }
With this configuration, I'm getting a class cast exception in my ArrayAdapter:
java.lang.ClassCastException: com.google.api.client.util.ArrayMap cannot be cast to com.companyname.appname.application.backend.messageApi.model.Message
It seems the conversion of returned data isn't performed somewhere and, instead of a List of Message objects, I get a List of com.google.api.client.util.ArrayMap objects (they do contain valid data, by the way).
I COULD check whether the app is running in release mode and do the conversion manually, however, it's a hacky way and I'd prefer to do it properly. So, can someone please tell me what I'm missing in the Proguard configuration file?
I do similar things with endpoints in one of my apps. I had some problems with Proguard as well (can't remember exactly what).
This section of my Proguard rules seems applicable:
# Needed by google-api-client to keep generic types and #Key annotations accessed via reflection
-keepclassmembers class * {
#com.google.api.client.util.Key <fields>;
}
-keepattributes Signature,RuntimeVisibleAnnotations,AnnotationDefault
I don't know if it is necessary, but I also have this section:
# Play Services
-dontwarn com.google.android.gms.**
-dontwarn com.google.common.cache.**
-dontwarn com.google.common.primitives.**
-keep class * extends java.util.ListResourceBundle {
protected Object[][] getContents();
}
-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {
public static final *** NULL;
}
-keepnames #com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class * {
#com.google.android.gms.common.annotation.KeepName *;
}
Hope it helps.

Proguard and Netty 5 on Android

I've seen a couple questions regarding this issue, but they are for older versions of Netty.
I have tried their answers, switching org.jboss.netty out with io.netty, but the same error occurs.
I'm trying to compile an Android app that uses Netty 5.0.0Alpha2 (build #16) with Proguard enabled.
Without Proguard, the app runs fine.
As soon as I enable Proguard, I get this exception when it tries to use Netty:
java.lang.IllegalStateException: unknown type parameter 'I': class io.netty.channel.SimpleChannelInboundHandler
at io.netty.util.internal.TypeParameterMatcher.find0(Unknown Source)
at io.netty.util.internal.TypeParameterMatcher.find(Unknown Source)
at io.netty.channel.SimpleChannelInboundHandler.<init>(Unknown Source)
at io.netty.channel.SimpleChannelInboundHandler.<init>(Unknown Source)
...
This is my Proguard config:
# billing
-keep class com.android.vending.billing.**
# butterknife
-dontwarn butterknife.internal.**
-keep class **$$ViewInjector {
*;
}
-keepnames class * {
#butterknife.InjectView *;
}
# admob
-keep public class com.google.android.gms.ads.** {
public *;
}
-keep public class com.google.ads.** {
public *;
}
# logging
-assumenosideeffects class android.util.Log
# netty (partial)
-dontwarn io.netty.**
-dontwarn sun.**
I have tested it without the -dontwarn options to see if the warnings would point me in the right direction, but it's all missing optional dependencies like slf4j and Tomcat.
I have also tried excluding all the Netty classes like so:
-keep class io.netty.** {
*;
}
...but that does not appear to fix it either.
I have fixed this issue with some carefully* applied Proguard rules after reading through parts of the rather huge Netty sources:
-keepattributes Signature,InnerClasses
-keepclasseswithmembers class io.netty.** {
*;
}
-keepnames class io.netty.** {
*;
}
My original exception was caused by the type variables being removed from the bytecode, which Netty uses via reflection. Signature in -keepattributes keeps this information.
You get a slightly different exception if you only do Signature on -keepattributes - adding InnerClasses fixes this one by bringing back even more information in the class files.
Later, I got java.lang.NoSuchFieldException: ctl; that's what -keepnames is for. This way, the field is still called ctl like Netty expects.
Finally, some members (like ctl, seen earlier) were being removed by Proguard because Netty only uses them via reflection. The final rule, -keepclasseswithmembers, makes sure Proguard doesn't remove them.
If you take this approach, I strongly recommend you use only the Netty jars you need, instead of the -all jar. Switching from -all to just the required Netty jars brought my method count way down after I had gone past the 65k limit. Reducing your jars requires bit of trial-and-error though as the separation is unclear and there's not really any resources saying what's what.
* not carefully at all, I just slapped rules into the file and removed them if they did nothing. There's probably a better way to do this that doesn't keep this information in the entire program, but instead just Netty.
Una's answer keep too many classes, which makes my app 1MB larger than usual. So I use the rules below:
# netty
-keepclassmembernames class io.netty.buffer.AbstractByteBufAllocator {
*;
}
-keepclassmembernames class io.netty.buffer.AdvancedLeakAwareByteBuf {
*;
}
-keep public class io.netty.util.ReferenceCountUtil {
*;
}

Phonegap 2.4 Android Proguard config

I've upgraded a build from Phonegap (Cordova) 2.0 to 2.4 and everything was working fine in dev until I actually came to testing the final release apk. What I'm finding, after a lot of time wasted, is that for some reason now when I run the build my proguard config is breaking the phonegap build in some way that means that when it runs the deviceready is never called. There seem to be no errors when building, nor running and nothing as far as I can see but I'm guessing something is silently failing in the cordova js as i'm not getting compile / log errors on the device.
As I say this is ONLY when having ran the Proguard obfs in the build process. If i turn off Proguard it all works fine. I reverted all my code back to 2.0 to be sure and that is all fine so somewhere along the way there has been a stuble change that is seemingly not documented / or nobody has hit just yet (2.4 only came out a few weeks ago - at time of writing 26th feb 2013).
My Proguard config contains the following for phonegap (as well as some other standard config)
-keep public class * extends com.phonegap.api.Plugin
-keep public class * extends org.apache.cordova.api.Plugin
-keep public class org.apache.cordova.DroidGap
-keep public class org.apache.cordova.**
-keep public class org.apache.**
-dontwarn android.webkit.*
-dontwarn org.apache.**
and decompiling the dex doesn't seem to throw any light - everything looks ok at a glance...
Anyone have any ideas???
Try replacing the Cordova "keep" settings in your proguard-project.txt with the following line, which should maintain all Cordova classes, fields, and methods, both public and private (and thus reenable deviceready):
-keep class org.apache.cordova.** { *; }
Then you just need to include your class(es) (presumably extending CordovaPlugin, not just Plugin) e.g.
pre-v3:
-keep public class * extends org.apache.cordova.api.CordovaPlugin
v3+:
-keep public class * extends org.apache.cordova.CordovaPlugin
Phonegap Plugins are being excluded from the final APK I guess. Cordova.js probably doesn't even exist to give errors.

Categories

Resources