Better Programming

Advice for programmers.

Exploring and Building Android App Widgets With Glance APIs

Ngenge Senior
Better Programming
Published in
4 min readFeb 9, 2022

--

Photo by Sebastian Bednarek on Unsplash

According to the Android developers website, app widgets are miniature applications that can be embedded in other applications(for example, the home screen).

For some time now, I have been experimenting and building a few apps with the new Jetpack Compose toolkit.

Jetpack Compose has streamlined development time significantly for me and this is a big win. To make things better, there has been the introduction of what is referred to as the Glance API.

With the old Android View system, we built app widgets using XML, while with Glance, we use the same knowledge we have gotten from Jetpack Compose and we build the Android app widgets in Kotlin code. How cool is that? Let me show you how to implement android app widgets using Glance.

Setting Up the Dependency

First things first, create a project in Android Studio and choose the Jetpack Compose template project. Then next, add the glance dependency in your app-level build.gradle file as follows;

implementation "androidx.glance:glance-appwidget:1.0.0-alpha02"

Next, ensure that you sync your project and you are good to go. The glance dependency gives us access to Glance’s own composables such as Column, Row, etc. When building the app widgets, ensure that your imports are from androidx.glance.

The Glance composables behave almost similar to Jetpack Compose specific Composables. We will build a sample weather app widget with static data that looks like the one in the emulator screenshot below.

Android emulator with app Widget.

Define app widget provider info in XML

You probably thought everything here will be replaced with Kotlin, but well, same as with the old view system, you will have to define the app widget provider using XML.

Ours will be as simple as the one below.

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minHeight="180dp"
android:minWidth="180dp"
android:description="@string/app_widget_description"
android:previewLayout="@drawable/example_appwidget_preview"
android:minResizeHeight="90dp"
android:minResizeWidth="90dp"
android:targetCellHeight="2"
android:targetCellWidth="2"
android:resizeMode="horizontal|vertical"
android:updatePeriodMillis="86400000"
android:widgetCategory="home_screen"
/>

The AppWidgetProviderInfo information above is gotten by creating an xml resource and giving it the name you chose(it should be in the res/xmldirectory). I named this one my_widget_provider.xml . We define several attributes like the minHeight, minWidth , previewLayout, etc. Android 12 brings new attributes like targetCellWidth and targetCellHeight.

Creating the Glance Widget

The next thing for us to do is to create the actual widget. This is done by extending the GlanceWidget abstract class from androidx.glance.appwidget , and override the most important method called Content.

Content is marked with the @Composable annotation and it is here that we define what our widget layout will look like. We will start with a composable which is simply a column named DayItem

Note the difference from our normal composables. Here, Modifier is replaced by GlanceModifier . The imports are from androidx.glance .

Next, let us do the actual work by extending the GlanceAppWidget class.

The most important thing as I said is for us to extend the GlanceAppWidget class and override the Content method which is marked with @Composable.

The next thing for us to do is to extend GlanceAppWidgetReceiver and override the value for glanceAppWidget and return our GlanceNewWidget

The next thing for us to do is to register our receiver in the AndroidManifest file.

Ensure that you register the receiver as a child of the application tag. In the meta-data , we specify our provider XML file.

This should be enough for us. Run your application and long click on an empty section of the screen and select Widgets , and look for the name of your app and drag the widget to the screen. You should see what looks like what we have in the above screenshot.

Note that it is not some sort of magic. These composables are transformed to RemoteViews .

Invoking actions With Glance

The purpose of your app widget might be that when some portion or button is clicked, something happens like starting an activity, a service or maybe just saving something to the database.

Glance provides us with actions to perform and we can create our own actions. By default, there are actions for starting an activity, a service, a broadcast receiver and others.

Okay at this point, let us say we want to launch a new activity NewActivity when 32° is clicked and we pass an extra called name and receive it in NewActivity.

How do we do this? For this, we will apply GlanceModifier.clickable and pass an action to it. Thus the Text becomes:

The method actionStartActivity takes an intentand a parameters parameters. In the parameters, we pass the data we want to pass to the activity. In this case, we give it the key ActionParameters.Key<String>("name") and the value Lionel Messi . Below is how we will receive it in NewActivity

If you run the app now and create a widget and click on the text, it will launch the NewActivity. You will see the text Lionel Messi . That is how you can pass data to activities using actions.

For now, this is the simplest way of creating app widgets using composables rather than XML. There is a lot that you can do but I will leave that for you to do some research.

--

--

No responses yet