1

I have an Android system app that has a custom BroadCastReceiver in manifest (this is to be run in Android M device): My manifest:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:sharedUserId="android.uid.system"
    package="mypackagename">

   ....

    <!-- custom permissions -->
    <uses-permission android:name="mypackagename.ASK_DISPLAY_INFO"
        android:protectionLevel="signatureOrSystem"/>

    <permission android:name="mypackagename.ASK_DISPLAY_INFO" />


    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
         
        ....

        <!-- custom receiver -->
        <receiver android:name=".CustomReceiver"
            android:permission="mypackagename.ASK_DISPLAY_INFO">
            <intent-filter>
                <action android:name="GET_HDMI_SUPPORTED_MODES"/>
                <action android:name="CHANGE_HDMI_RESOLUTION"/>
            </intent-filter>
        </receiver>



    </application>

</manifest>

And I have enabled in gradle Proguard obfuscation:

        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
         
        }

I have another test app that sends broadcasts to this app. The thing is, with mignifyEnabled false works, but with mignifyEnabled true when receives a broadcast intent it gives the error:

java.lang.RuntimeException: Unable to instantiate receiver mypackagename.CustomReceiver: java.lang.ClassCastException: mypackagename.CustomReceiver cannot be cast to android.content.BroadcastReceiver

Adding the following rule to proguard-rules.pro:

-keep class android.content.BroadcastReceiver { *; }

When receiving an intent throws the error:

java.lang.AbstractMethodError: abstract method "void android.content.BroadcastReceiver.onReceive(android.content.Context, android.content.Intent)"

Here is my broadcastreceiver definition:


import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.util.Log;


public class CustomReceiver extends BroadcastReceiver {
    ...

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction() != null) {
            Log.i(TAG, "CustomReceiver received action: "+intent.getAction());

            if (intent.getAction().equals(GET_HDMI_SUPPORTED_MODES)) {
                new GetHDMIModesTask(context).execute();
            }  else if (intent.getAction().equals(CHANGE_HDMI_RESOLUTION) && intent.getExtras() != null && intent.hasExtra(EXTRA_HDMI_MODE) ) {
                new ChangeHDMIModeTask(context, intent.getStringExtra(EXTRA_HDMI_MODE)).execute();
            }
        }

    }

}

As I'm very new to Proguard rules and I need this obfuscated, I would appreciate if someone can tell me which rules can I specify to solve this issue

3
  • seems like the issue is in CustomReceiver so post make sure it extends BroadcastReceiver and imports are appropriate Commented Jan 21, 2020 at 17:31
  • Hello, thanks, for your answer, I've added my broadcastreceiver to the post. Commented Jan 22, 2020 at 9:54
  • if you are using broadcast with separate apps then add android:exported="true" though for pro guard, the answer by Nikhil should fix the issue, clean and generate new apk and try again Commented Jan 22, 2020 at 11:39

2 Answers 2

0

Add -keep public class * extends android.content.BroadcastReceiver to your proguard rules instead of -keep class android.content.BroadcastReceiver { *; }. This will prevent your custom broadcast receiver from being obfuscated.

Sign up to request clarification or add additional context in comments.

11 Comments

Hello, thanks for your suggestion, I've added to proguard rules: -keep public class * extends android.content.BroadcastReceiver but still returns the first error: java.lang.RuntimeException: Unable to instantiate receiver mypackagename.CustomReceiver: java.lang.ClassCastException: mypackagename.CustomReceiver cannot be cast to android.content.BroadcastReceiver
Try keeping both lines - -keep public class * extends android.content.BroadcastReceiver and -keep class android.content.BroadcastReceiver { *; }
Adding both rules throws the second error: java.lang.AbstractMethodError: abstract method "void android.content.BroadcastReceiver.onReceive(android.content.Context, android.content.Intent)
Try adding -keepnames class your.package.name.ClassName { } to explicity tell proguard not to obfuscate the class.
it doesn't build: AGPBI: {"kind":"error","text":"Expected [!]interface|@interface|class|enum","sources":[{"file":"C:\\...\proguard-rules.pro","position":{"startLine":34,"startColumn":11,"startOffset":1295}}],"tool":"R8"} FAILURE: Build failed with an exception.
|
0

I have done a workaround in this, removed CustomerReceiver from manifest, added an custom application class and defined the BroadcastReceiver in there. Added the proguard rules:

 -keep class android.app.Application {
        public <fields>;
        private <fields>;
       public <methods>;
    }

    -keep public class * extends android.app.Application

The issue was gone

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.