Creating Android App Widget with Kotlin

Esracangungor
5 min readMay 4, 2023

--

This article covers a complete tutorial about how to make an application with Android Widgets. We will make a simple Todo list application which has Android app widget with Room database and Koin in Kotlin language.

Before we getting started, what is an Android-App Widget? If you prefer 🧑‍💻 rather than 📖, you can directly jump to this repository.

First, let’s briefly explain on the technical concepts and then try to make understanding the source codes of an application.

What is an Android Widget?

Widgets are an important aspect of home screen customization. You can think of these as “at-a-glance” views of your app’s key data and functionality, accessible directly from the user’s home screen. Users can move widgets around their homepage and, where supported, resize them to customize the amount of information in a widget to their liking. App widgets can receive periodic updates. Please refer to this link for more information about widgets.

What are the steps to create widgets?

  1. Create app widget layout which is appropriate for RemoteViews.
  2. Create xml file for defining the app widget properties.
  3. Create AppWidgetProvider class for the widget actions.
  4. Add need files to AndroidManifest.xml file.

What is RemoteViews?

A class that describes a view hierarchy that can be displayed in another process. The hierarchy is inflated from a layout resource file, and this class provides some basic operations for modifying the content of the inflated hierarchy.

Be conscious that RemoteViews, the core of widget layouts, do not support all types of layouts or view widgets. If custom views, subclasses etc. are not supported RemoteViews you can not use them in your app widget layout implementation. Additionally, ViewStub, an invisible, zero-sized View that you can use to lazily inflate layout resources at runtime, is supported by RemoteViews.

RemoteViews can only support the following layout classes:

Þ AdapterViewFlipper Þ FrameLayout Þ GridLayout Þ GridView

Þ LinearLayout Þ ListView Þ RelativeLayout Þ StackView Þ ViewFlipper

And the following widget classes:

Þ AnalogClock Þ Button Þ Chronometer Þ ImageButton Þ ImageView

Þ ProgressBar Þ TextClock Þ TextView

As of API 31, the following widgets and layouts may also be used:

Þ CheckBox Þ RadioButton Þ RadioGroup Þ Switch

How can we enable users to configure app widgets?

App widgets can be configurable at creation. Create a widget configuration activity to allow users to change your widget’s settings. Depending on the configuration settings you choose, the app widget host may automatically start this activity when the widget is created or at a later time.

There are two important points to remember when you implement the activity:

The app widget host calls the configuration activity, and the configuration activity must always return a result. The result must include the App Widget ID passed by the intent that launched the activity — saved in the intent extras as EXTRA_APPWIDGET_ID.

The system doesn’t send the ACTION_APPWIDGET_UPDATE broadcast when a configuration activity is launched, which means it doesn’t call the onUpdate() method when the widget is created. It’s the responsibility of the configuration activity to request an update from the AppWidgetManager when creating the widget for the first time. However, onUpdate() is called for subsequent updates — it is only skipped the first time.

Now let’s try this on a sample application!

The app’s functionality includes:

Þ Displaying the list of todos in Recycler View which is added by the user.

Þ Add, edit, delete a todo to your app.

Þ Add widget with selected category (Daily, School, Office, Other) show list of todos.

Þ Add, edit, delete a todo with widget.

I have created TodoItem(entity), TodoDao, TodoDatabase, TodoRepository classes to display the list of editable items in the recylerView from room database. TodoItem has title, description, timestamp, category columns and id for primary key. TodoDatabase abstract class is to build our database using Room.

TodoViewModel and TodoRepository classes are also defined for the MVVM Architecture. However, because App-Widget uses Broadcast receivers to function, it lacks a lifecycle. Your AppWidgetProvider instance only exists for one callback method, like onUpdate(). As a result, neither a mapping to Lifecycle events nor a mapping from Lifecycle events to a standard BroadcastReceivers exists. So we won’t use viewModel on the app widget implementation.

1.Create app widget layout which appropriate for RemoteViews.

For Widget part our first file is going to be todo_list_app_widget_layout.xml an it is item todo_widget_item

2.Create xml file for defining the app widget properties.

The basic characteristics of an app widget, such as its initial layout, preview, description, minimum size, and resize mode, are defined by the widget’s metadata. In res/xml, it is defined.

3.Create AppWidgetProvider class for the widget actions.

TodoListAppWidget class have code to bind our views to an object to RemoteView in onUpdate() function. We are getting category from configuration activity(We will implement later) and we use it for getting todo items. A serviceIntent which is TodoListAppWidgetService class will be require to set adapter for our listView. We will bond views and then setOnClickFillInIntent events on the buttons which will either add, edit or delete an item. We will require to create Intent() objects and pass data to the onReceive() function in TodoListAppWidget.kt. In the onUpdate() method we will create PendingIntent and set it our ListView’s PendingIntentTemplete. In the onReceive() method, depending on the intent received we will call our repository methods to update the room database entities.

After that we should call notifyAppWidgetViewDataChanged() method to update the views of all the app-widgets deployed when the data has been changed.

Here is the full code:

4.Add need files to AndroidManifest.xml file.

The TodoListAppWidget is a BroadcastReceiver and TodoListAppWidgetService is a service thus like any other Android component, it must be registered in the app’s manifest.

Configuration Widgets

In this section, we are listing categories of todos.android:configure=”com.esracangungor.todolistapp.widget.TodoConfigurationActivity” line should add to the todo_widget_info.xml.

The basic layout for configuration activity:

User selects a category and we are saving it in shared preferences. Setting setResult(RESULT_CANCELED) is the first thing we perform in the activity’s handleBunleResult() function. The reason is for that Android starts the configure activity associated with your widget and waits for the outcome information. We don’t need to generate a widget if the user’s configuration was not what we had anticipated, for example, if user pushed the back button without entering any input.

Thank you for reading! I used these steps and implemented inbox and calendar app widget for Turkcell’s mail app YaaniMail. You can download our app from this link: https://play.google.com/store/apps/details?id=com.turkcell.yaaniemail&hl=tr&gl=US

--

--