What is an app widget?
App Widgets are miniature application views that can be embedded in other applications (such as the Home screen) and receive periodic updates. These views are referred to as Widgets in the user interface, and you can publish one with an App Widget provider. – (Android Documentation).
Android widget is an important functionality that any app can take advantage of. It could be used to show important dates, things that the user personalizes on the app etc. In the context of the Open Event Android App, it was necessary to create a bookmark widget for the Android phones so that the user could see his bookmarks on the homescreen itself and need not open the app for the same. In the open event android app, the widget was already created but it needed bug fixes and UI enhancements due to migration to the Realm database migration. Therefore, my majority of work circled around that.
Implementation
Declare the app widget in the manifest. All the updates in the application would be received by the class which extends the AppWidgetProvider if it needs to be reflected in the widget.
<receiver android:name=".widget.BookmarkWidgetProvider" android:enabled="true" android:label="Bookmarks"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> <action android:name="${applicationId}.ACTION_DATA_UPDATED" /> <action android:name="${applicationId}.UPDATE_MY_WIDGET" /> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/widget_info" /> </receiver>
Create a layout for the widget that is to be displayed on the homescreen. Remember to use only the views defined in the documentation. After the creation of the layout, create a custom widget updater which will broadcast the data from the app to the receiver to update the widget.
public class WidgetUpdater { public static void updateWidget(Context context){ int widgetIds[] = AppWidgetManager.getInstance(context.getApplicationContext()).getAppWidgetIds(new ComponentName(context.getApplicationContext(), BookmarkWidgetProvider.class)); BookmarkWidgetProvider bookmarkWidgetProvider = new BookmarkWidgetProvider(); bookmarkWidgetProvider.onUpdate(context.getApplicationContext(), AppWidgetManager.getInstance(context.getApplicationContext()),widgetIds); context.sendBroadcast(new Intent(BookmarkWidgetProvider.ACTION_UPDATE)); } }
Next, create a custom RemoteViewService to update the views in the widget. The reason this is required is because the app widget does not operate in the usual lifecycle of the app. And therefore a remote service is required which acts as the remote adapter to connect to the remote views. In your class, override the onGetViewFactory() method and create a new remoteViewsFactory object to get the the data from the app on updation of the bookmark list. To populate the remote views, override the getViewsAt() method.
public class BookmarkWidgetRemoteViewsService extends RemoteViewsService { @Override public RemoteViewsFactory onGetViewFactory(Intent intent) { return new RemoteViewsFactory() { private MatrixCursor data = null; @Override public void onCreate() { //Called when your factory is first constructed. } @Override public void onDataSetChanged() { } @Override public RemoteViews getViewAt(int position) { } } }
Finally, create a custom AppWidgetProvider which parses the relevant fields out of the intent and updates the UI. It acts like a broadcast receiver, hence all the updates by the widgetUpdater is received here.
public class BookmarkWidgetProvider extends AppWidgetProvider { public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.bookmark_widget); setRemoteAdapter(context, views); } @Override public void onReceive(@NonNull Context context, @NonNull Intent intent) { super.onReceive(context, intent); } private void setRemoteAdapter(Context context, @NonNull final RemoteViews views) { views.setRemoteAdapter(R.id.widget_list, new Intent(context, BookmarkWidgetRemoteViewsService.class)); } }
Conclusion
For any event based apps, it is crucial that it regularly provide updates to its users and therefore app widget forms an integral part of that whole experience.
References
- Android Documentation on App Widget https://developer.android.com/guide/topics/appwidgets/index.html
- Complete Code Reference https://github.com/fossasia/open-event-android/pull/1824
- StackoverFlow for android widget listview https://stackoverflow.com/questions/28941472/update-listview-widget-with-application
- Android Authority post to create an Android widget. http://www.androidauthority.com/create-simple-android-widget-608975/