Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

System settings force close when opening widget picker

My users report a crash that occurs when they try to pick a widget with my application (not a launcher app). I'm using the standard widget picker code and it always worked and still works on all devices, except on LG G2 and LG G3.

I've found some similar questions but they all refer to the crash that Android 2.1 suffered from that was solved with the empty data workaround (which is already implemented in my code).

Also used an alternative way to get the widgets, without the official picker - which works, but requires the app to be a system app for the BIND_APPWIDGET permission.

Anyone experienced this issue as well and maybe found a workaround or a solution?

Thanks

Here's the code:


public static void selectWidget(AppWidgetHost appWidgetHost, final Activity activity) {
        try {
            int appWidgetId = appWidgetHost.allocateAppWidgetId();
            Intent pickIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_PICK);
            pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
            addEmptyData(pickIntent);
            activity.startActivityForResult(pickIntent, R.id.REQUEST_PICK_APPWIDGET);

        } catch (ActivityNotFoundException e) {
            activity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(activity, activity.getString(R.string.widget_config_no_activity), Toast.LENGTH_SHORT).show();
                }
            });
        }
    }

    /**
     * This avoids a bug in the com.android.settings.AppWidgetPickActivity, which is used
     * to select widgets. This just adds empty extras to the intent, avoiding the bug. See
     * more: http://code.google.com/p/android/issues/detail?id=4272
     */
    private static void addEmptyData(Intent pickIntent) {
        ArrayList customInfo = new ArrayList();
        pickIntent.putParcelableArrayListExtra(AppWidgetManager.EXTRA_CUSTOM_INFO, customInfo);
        ArrayList customExtras = new ArrayList();
        pickIntent.putParcelableArrayListExtra(AppWidgetManager.EXTRA_CUSTOM_EXTRAS, customExtras);
    }

Here's the crash stacktrace:

 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.android.settings/com.android.settings.AppWidgetPickActivity}: android.content.res.Resources$NotFoundException: File res/drawable-xhdpi-1280x960/ic_launcher_calendar.png from drawable resource ID #0x7f02007e
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2200)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2250)
            at android.app.ActivityThread.access$800(ActivityThread.java:139)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1200)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5105)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:608)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: android.content.res.Resources$NotFoundException: File res/drawable-xhdpi-1280x960/ic_launcher_calendar.png from drawable resource ID #0x7f02007e
            at android.content.res.Resources.loadDrawable(Resources.java:2156)
            at android.content.res.Resources.getDrawableForDensity(Resources.java:789)
            at com.android.settings.AppWidgetPickActivity.createItem(AppWidgetPickActivity.java:139)
            at com.android.settings.AppWidgetPickActivity.createItem(AppWidgetPickActivity.java:47)
            at com.android.settings.AppWidgetLoader.putAppWidgetItems(AppWidgetLoader.java:145)
            at com.android.settings.AppWidgetLoader.putInstalledAppWidgets(AppWidgetLoader.java:209)
            at com.android.settings.AppWidgetLoader.getItems(AppWidgetLoader.java:182)
            at com.android.settings.AppWidgetPickActivity.getItems(AppWidgetPickActivity.java:92)
            at com.android.settings.ActivityPicker.onCreate(ActivityPicker.java:143)
            at com.android.settings.AppWidgetPickActivity.onCreate(AppWidgetPickActivity.java:70)
            at android.app.Activity.performCreate(Activity.java:5275)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2164)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2250)
            at android.app.ActivityThread.access$800(ActivityThread.java:139)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1200)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5105)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:608)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.io.FileNotFoundException: res/drawable-xhdpi-1280x960/ic_launcher_calendar.png
            at android.content.res.AssetManager.openNonAssetNative(Native Method)
            at android.content.res.AssetManager.openNonAsset(AssetManager.java:415)
            at android.content.res.Resources.loadDrawable(Resources.java:2147)
            at android.content.res.Resources.getDrawableForDensity(Resources.java:789)
            at com.android.settings.AppWidgetPickActivity.createItem(AppWidgetPickActivity.java:139)
            at com.android.settings.AppWidgetPickActivity.createItem(AppWidgetPickActivity.java:47)
            at com.android.settings.AppWidgetLoader.putAppWidgetItems(AppWidgetLoader.java:145)
            at com.android.settings.AppWidgetLoader.putInstalledAppWidgets(AppWidgetLoader.java:209)
            at com.android.settings.AppWidgetLoader.getItems(AppWidgetLoader.java:182)
            at com.android.settings.AppWidgetPickActivity.getItems(AppWidgetPickActivity.java:92)
            at com.android.settings.ActivityPicker.onCreate(ActivityPicker.java:143)
            at com.android.settings.AppWidgetPickActivity.onCreate(AppWidgetPickActivity.java:70)
            at android.app.Activity.performCreate(Activity.java:5275)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2164)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2250)
            at android.app.ActivityThread.access$800(ActivityThread.java:139)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1200)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5105)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:608)
            at dalvik.system.NativeStart.main(Native Method)
like image 730
Lior Iluz Avatar asked Nov 11 '22 03:11

Lior Iluz


1 Answers

It seems like I managed to solve the issue on Android 4.1 and above (API 16), using the AppWidgetManager.ACTION_APPWIDGET_BIND Intent. For some reason, Google states that we must add the BIND_APPWIDGET permission to the AndroidManifest.xml in order for this to work, but it works for me anyway (tested on multiple devices). I use the bindAppWidgetIdIfAllowed method to check if I need to request the bind or not.

I still haven't figure out how to bind widgets prior to Android 4.1, even with reflection to bindAppWidgetId. This is good enough for me know but I'll accept any other answer with a solution for pre-JellyBean (Android below 4.1)

like image 94
Lior Iluz Avatar answered Nov 15 '22 05:11

Lior Iluz