Populating Android-App Widgets with Room-Database

Siddharth Singh
4 min readJun 25, 2022

In this tutorial-guide we will be exploring the use of Android-App Widgets and how can we parallelly use them with databases like SQLite, Room-database, etc. You will learn how you can customize your widgets, but mainly we will be learning on how we can display a list of items in a ListView or StackView using room-database as our data source.

Before getting started, what is an Android-App Widget? If you prefer 🧑‍💻 rather than 📖, you can directly hop to this repo. Feel free to star and fork the repository. All sorts of contributions are welcome!

App Widgets are miniature application views we like to embed on the home screen. You can imagine them as “at-a-glance” views of an app’s most important data and functionality that is accessible right from the user’s home screen.

If you have not worked with app widgets before, it is recommended to first learn basic functionality and how to create one. Please refer to this article which in-depth explains how you can create a widget.

Enough Chit-chatting, Lets Get Started!

In order to have a functionable app-widget we require 3 files:

  • A Widget-layout which gets inflated when user places widget on the home screen.
  • An XML file which defines the properties of widgets.
  • A class for widget actions.

You can either manually create these files and specify these files in Manifest or you can directly create a basic app-widget by navigating in android studio to: File->New->Widget->AppWidget.

Now let us modify our appwidget_layout.xml and create listview item layout:

Our goal is to display the list of editable items in the widget_listview from room-database. The configurations for room database is already set-up. I have created an Entity for a ShoppingItem which have name of the item as primary-key and one property and amount as another property. The DAO consists of 4 major suspended functions:

  • Upsort: To insert new item in the list. This function can also be used to modify amount of a particular item.
  • UpdateAmount: To modify amount of a particular item.
  • Delete: To delete an item from the list.
  • GetAllShoppingItems: Returns a Obervable-List of ShoppingItems present in the database.

In order to use MVVM Architecture, ViewModel and Repository Classes are also defined. But since App-Widget run with the help of Broadcast receivers, it does not have lifecycle. An instance of your AppWidgetProvider lives for exactly one callback method (e.g., onUpdate()). Hence, there is no mapping to Lifecycle events, just as there is no mapping of Lifecycle events to an ordinary BroadcastReceivers. We will looking at a significantly different approach in order to Room-database and its methods.

Firstly, let us write the code to configure ListView and to populate it. The WidgetproviderClass or AppWidget.kt will have code to to bind our views to an object to RemoteView. A ServiceIntent will be require to set adapter for our ListView. This is what AppWidget.kt would look like:

We don’t want our ListView to be static. Hence to register onClick events and populate it with room database, we will require to create a RemoteViewsService class with RemoteViewsFactory inner class. The WidgetItemFactory delivers the following methods:

  • onCreate(): Called when your factory is first constructed.
  • onDataSetChanged(): Called when notifyDataSetChanged() is triggered on the remote adapter.
  • onDestroy(): Called when the last RemoteViewsAdapter that is associated with this factory is unbound.
  • getCount(): How many items are in the data set represented by this Adapter.
  • getViewAt(): Get a View that displays the data at the specified position in the data set. This is where we bind views to RemoteView.
  • getLoadingView(): This allows for the use of a custom loading view which appears between the time that getViewAt() is called and returns.
  • getViewTypeCount(): Returns the number of types of Views that will be created by getView(int,View,ViewGroup).
  • getItemId(): Get the row id associated with the specified position in the list.
  • hasStableIds(): Indicates whether the item ids are stable across changes to the underlying data.

Once we have bonded our views we can initialize our room database and access the entities and methods through our Repository Object. We will now set onClick events on the buttons which will either increment/decrement amount or delete an item. We will require to create Intent() objects and pass data to the onReceive() function in our AppWidget.kt. In the onUpdate() method we will create PendingIntent and set it our ListView’s PendingIntentTemplete. Again in order to access our room database we will initialize our repository object. In the onReceive() method, depending on the intent received we will call our repository methods to update the room database entities.

Also don’t forget to use notifyAppWidgetViewDataChanged() method to update the views of all the app-widgets deployed when the data has been changed.

With this we come to an end. You now will be able to use Room-Database in along with App-Widget to add new feature to your android projects. If you made it at this far, personally thank you for reading. Here is the promised Github-Repo which includes whole project in this article.

To help others to reach the article don’t forget to recommend 💚. It means a lot to me. Follow up on me. Signing Out, Siddy!

--

--

Siddharth Singh

As a tech enthusiast, I ventured into development, bridging imagination and code through research, experimentation, and blog posts, offering insights.