4

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.

Anton Wolkov
  • 163
  • 2
  • 10
  • As google announced Any apk uploaded on google paly now google run proguard on apk itself , so now no need to use proguard ourside. – Biraj Zalavadia Sep 04 '13 at 09:37
  • there seems to be a very noticeable difference on the file size, with proguard it's 800kb and without it's 1.2mb. – Anton Wolkov Sep 04 '13 at 10:05
  • maybe i'm missing something but can they really do it without me signing the code afterwards? – Anton Wolkov Sep 04 '13 at 10:12
  • same issue as http://stackoverflow.com/questions/16362726/parcelable-issues-when-obfuscating-with-proguard but no answer there. – Anton Wolkov Sep 04 '13 at 11:24
  • @BirajZalavadia I search in google for the information that you said, but i don't get any link about the news that you told. Can you please give me the link where you see that Google will run proguard on apk itself ? – Mahmud Ahsan Apr 26 '14 at 16:57

2 Answers2

13

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.

Eric Lafortune
  • 45,150
  • 8
  • 114
  • 106
1

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.

D2TheC
  • 2,203
  • 20
  • 23