Search code examples
javaandroidandroid-listviewandroid-widgetandroid-remoteview

Android widget not populating


I've created an android app and I'm attempting to add a basic widget. On my physical phone the widget never populates and on the virtual device I'm using the launcher "keeps stopping" whenever the widget would be visible (it's fine when my main application is visible - this might also be because the MyWidgetProvider OnUpdate is only triggered on the main application's onPause() - not on any timed interval).

I'm attempting to follow this to populate a ListView widget using remote views.

I had this working with a TextView in place of the ListView but I wanted the extra formatting and built in vertical scrolling of the ListView widget.

When debugging I can't see anything going wrong but clearly something is somewhere and I can only imagine it's going wrong within the onUpdate method.

Can anyone see what's wrong or have ideas for where to focus any debugging? Any clues appreciated!


MyWidgetProvider.java

public class MyWidgetProvider extends AppWidgetProvider {
    @Override
    public void onUpdate (Context context,
                          AppWidgetManager appWidgetManager,
                          int[] appWidgetIds) {
        // Attach the remote adaptor to each of the widgets
        for (int appWidgetId : appWidgetIds) {
            Log.d("LOG", "Updating widget " + appWidgetId);
            // Create the intent which references the list widget
            // service.
            Intent intent = new Intent(context, MyListWidgetService.class);
            RemoteViews rv = new RemoteViews(context.getPackageName(),
                                             R.layout.appwidget);
            rv.setRemoteAdapter(R.id.widgetListView, intent);

            appWidgetManager.updateAppWidget(appWidgetId, rv);
        }
    }
}

MyListWidgetService.java

public class MyListWidgetService extends RemoteViewsService {
    @Override
    public RemoteViewsFactory onGetViewFactory(Intent intent) {
        return new MyRemoteViewsFactory(this.getApplicationContext());
    }
}

class MyRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {
    public MyRemoteViewsFactory(Context context) {
        mContext = context;
    }

    public void onCreate() {
    }

    public void onDestroy() {
    }

    public int getCount() {
        return 4;
    }

    public RemoteViews getViewAt(int position) {
        RemoteViews rv;
        int val;
        rv = new RemoteViews(mContext.getPackageName(), R.layout.widget_list_item_view);
        // Dummy values
        rv.setTextViewText(R.id.widgetItemA, "Dummy Text 1");
        rv.setTextViewText(R.id.widgetItemB, "Dummy Text 2");
        val = (position % 3);
        if (val != 0) {
            rv.setTextViewText(R.id.widgetItemC, "(" + val + ")");
        }

        return rv;
    }

    public RemoteViews getLoadingView() {
        return null;
    }

    public int getViewTypeCount() {
        return 1;
    }

    public long getItemId(int position) {
        return position;
    }

    public boolean hasStableIds() {
        return true;
    }

    public void onDataSetChanged() {
    }
}

appwidget.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ListView
        android:id="@+id/widgetListView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/rounded_rect"
        android:fadeScrollbars="true" />

</LinearLayout>

widget_list_item_view.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/widgetItemA"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/padding"
        android:layout_marginTop="@dimen/padding" />

    <TextView
        android:id="@+id/widgetItemB"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/padding" />

    <TextView
        android:id="@+id/widgetItemC"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/padding"
        android:layout_marginEnd="@dimen/padding" />
</LinearLayout>

Solution

  • The issue was that I'd missed out the service property in my AndroidManifest.xml file. I needed to add

    <service android:name=".MyListWidgetService"                                    
             android:permission="android.permission.BIND_REMOTEVIEWS" />