Cheok Yan Cheng
Cheok Yan Cheng

Reputation: 42690

What are possible reasons that my AppWidgetProvider will receive data from 3rd party app in onReceive?

Recently, I am experiencing some weird crash report from Firebase Crashlytics.

Caused by android.os.BadParcelableException: ClassNotFoundException when unmarshalling: id.dana.model.CurrencyAmountModel
       at android.os.Parcel.readParcelableCreator(Parcel.java:2305)
       at android.os.Parcel.readParcelable(Parcel.java:2255)
       at android.os.Parcel.readValue(Parcel.java:2162)
       at android.os.Parcel.readArrayMapInternal(Parcel.java:2495)
       at android.os.BaseBundle.unparcel(BaseBundle.java:221)
       at android.os.BaseBundle.getIntArray(BaseBundle.java:1164)
       at android.appwidget.AppWidgetProvider.onReceive(AppWidgetProvider.java:64)
       at com.yocto.wenote.widget.CalendarAppWidgetProvider.onReceive(CalendarAppWidgetProvider.java:234)

I feel weird because my app never have use/ access to class id.dana.model.CurrencyAmountModel. I have totally clueless where does the class id.dana.model.CurrencyAmountModel come from?

It seems like a 3rd party app is able to "inject" data into my AppWidgetProvider?

My AppWidgetProvider is defined as follow.

<receiver android:name="com.yocto.wenote.widget.CalendarAppWidgetProvider"
    android:label="@string/widget_calendar_name"
    android:exported="true" >
    <intent-filter >
        <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
    </intent-filter>

    <meta-data
        android:name="android.appwidget.provider"
        android:resource="@xml/calendar_widget_info" />
</receiver>
        
public class CalendarAppWidgetProvider extends AppWidgetProvider {

    @Override
    public void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();

        ...

        super.onReceive(context, intent);
    }
}

Do you have any idea why does my AppWidgetProvider is receiving an unknown data id.dana.model.CurrencyAmountModel, and how I can avoid such?

Thanks.

Upvotes: 4

Views: 251

Answers (1)

CommonsWare
CommonsWare

Reputation: 1006614

It seems like a 3rd party app is able to "inject" data into my AppWidgetProvider?

Sure. Your AppWidgetProvider is publicly accessible by any other app. Any app can send a broadcast to it that it will pick up.

Do you have any idea why does my AppWidgetProvider is receiving an unknown data id.dana.model.CurrencyAmountModel

Some app is sending a broadcast with a CurrencyAmountModel as an extra. Based on the stack trace and the implementation of AppWidgetProvider, my guess is that this invalid value is under the AppWidgetManager.EXTRA_APPWIDGET_IDS key. Hopefully, this is a bug in the other app and not something malicious.

how I can avoid such?

AFAIK, an AppWidgetProvider has to be exported for it to work. You could run an experiment and see if android:exported="false" still gives you a working app widget, but it would surprise me.

If that fails, you could wrap the super.onReceive() in a try/catch block to prevent the crash. Given the AppWidgetProvider implementation, if your catch block is invoked, probably your provider did not get called with any of the standard callbacks (e.g., onUpdate()). You could add some logging to try to get a sense of whether affected users get any good super.onReceive() calls:

  • If they do, the probably the app widget is working normally other than these rogue broadcasts, so you could write off the failures as just some annoyance

  • If they are always affected, you might need to try calling onUpdate() yourself from time to time

Upvotes: 1

Related Questions