In this article, we will talk about Android Widgets, how to add Widgets into our application and also how to work with it with a simple example.
What is an App Widget?
App Widgets are miniature application views of an app’s most important data and functionality that is accessible right from the user’s home screen and receive periodic updates. Using widgets users can see the information they need “at-a-glance” without unlocking their phone or launching the related app. An application component that is able to hold other App Widgets is called an App Widget host (such as the Home screen).
Get GITHUB code from here.
Creating New Project
1. Create a new project in Android Studio from File ⇒ New Project and fill the project details.
2. Now to set up a widget for your application thanks to Android Studio, it does this for you automatically. To create a widget right click on project root folder under Java folder -> New -> Widget -> App Widget.
3. Once you click on it, a New Android Component window will open. Android Studio has an amazing interface for creating widgets.

- Provide a name for your widget (We give it MyAppWidget).
- Select placement which defines whether your App Widget can be displayed on the home screen (home_screen), the lock screen (keyguard), or both.
Note: Only Android versions lower than 5.0 support lock-screen widgets. For Android 5.0 and higher, only home_screen is valid.
- Select Resizable option which specifies the rules by which a widget can be resized. You can make widgets resizeable—horizontally, vertically, none, or on both axes.
- Provide MinimumHeight and MinimumWidth which specifies the minimum height and width(in cells) to which the widget can be resized.
- You can implement an App Widget configuration Activity by checking the configuration screen checkbox. This is an optional Activity that launches when the user adds your App Widget and allows them to modify App Widget settings at create-time, such as the App Widget color, size, update period or other functionality settings. Here I will leave it as unchecked.
4. Now click finish. You can see some files and folder gets added in your application.
Widget Creation Steps :
- create a layout for the widget.
- create XML for defining the widget properties.
- create a class for the widget actions.
- add all these to the AndroidManifest.xml file.
Widget-Layout File
Now you have to define the layout of your widget in your default XML file (my_app_widget.xml ).
By default it creates a very simple layout for a widget as shown below:
my_app_widget.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#09C" android:padding="@dimen/widget_margin"> <TextView android:id="@+id/appwidget_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:layout_margin="8dp" android:background="#09C" android:contentDescription="@string/appwidget_text" android:text="@string/appwidget_text" android:textColor="#ffffff" android:textSize="24sp" android:textStyle="bold|italic" /> </RelativeLayout>
This layout is displayed as a widget on the user’s home screen.
Widget-XML File
In res folder it creates a new xml folder which contains an xml file that defines the widget properties.
my_app_widget_info.xml is an xml file that contains various properties for your widget such as refresh time, preview image, minimum height/width, etc.
my_app_widget_info.xml
<?xml version="1.0" encoding="utf-8"?> <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:initialKeyguardLayout="@layout/my_app_widget" android:initialLayout="@layout/my_app_widget" android:minWidth="110dp" android:minHeight="110dp" android:previewImage="@drawable/example_appwidget_preview" android:resizeMode="horizontal|vertical" android:updatePeriodMillis="86400000" android:widgetCategory="home_screen"> </appwidget-provider>
A quick look for these properties:
- initialLayout: points to the layout resource that defines the App Widget layout.
- minHeight and minWidth: The values for the minWidth and minHeight attributes specify the minimum amount of space the App Widget consumes(in dp) by default. Every 60dp means 1 cell in android home-screen. The widget takes min 1×1 cell(s).
- previewImage: specifies a preview of what the app widget will look like after it’s configured, which the user sees when selecting the app widget.
- resizeMode: specifies the rules by which a widget can be resized. You use this attribute to make homescreen widgets resizeable—horizontally, vertically, or on both axes.
- updatePeriodMillis: The widget’s update method is called when the specified time is reached in a millisecond.
- widgetCategory: declares whether your App Widget can be displayed on the home screen (home_screen), the lock screen (keyguard), or both.
Widget-Java File
It creates a java file which defines the basic methods that allow you to programmatically interface with the App Widget, based on broadcast events.
MyAppWidget.Java
package com.example.androidwidgetexample; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; import android.content.Context; import android.widget.RemoteViews; /** * Implementation of App Widget functionality. */ public class MyAppWidget extends AppWidgetProvider { static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) { CharSequence widgetText = context.getString(R.string.appwidget_text); // Construct the RemoteViews object RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.my_app_widget); views.setTextViewText(R.id.appwidget_text, widgetText); // Instruct the widget manager to update the widget appWidgetManager.updateAppWidget(appWidgetId, views); } @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { // There may be multiple widgets active, so update all of them for (int appWidgetId : appWidgetIds) { updateAppWidget(context, appWidgetManager, appWidgetId); } } @Override public void onEnabled(Context context) { // Enter relevant functionality for when the first widget is created } @Override public void onDisabled(Context context) { // Enter relevant functionality for when the last widget is disabled } }
The AppWidgetProvider class extends BroadcastReceiver as a convenience class to handle the App Widget broadcasts. The AppWidgetProvider receives only the event broadcasts that are relevant to the App Widget, such as when the App Widget is updated, deleted, enabled, and disabled.
AppWidgetProvider extends BroadcastReceiver. MyAppWidget is indirectly a child of BroadcastReceiver. So our widget class is a receiver class.
Adding Created files in AndroidManifest.xml
In AndroidManifest file you can see the below changes:
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.androidwidgetexample"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <receiver android:name=".MyAppWidget"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/my_app_widget_info" /> </receiver> </application> </manifest>
The <receiver> element requires the android:name attribute, which specifies the AppWidgetProvider used by the App Widget.
The <intent-filter> element must include an <action> element with the android:name attribute specifies that the AppWidgetProvider accepts the ACTION_APPWIDGET_UPDATE broadcast.
The <meta-data> element specifies the AppWidgetProviderInfo resource and requires the following attributes:
- android:name – Specifies the metadata name. Use android.appwidget.provider to identify the data as the AppWidgetProviderInfo descriptor.
- android:resource – Specifies the AppWidgetProviderInfo resource location.
RemoteView
RemoteView is 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.
RemoteView is limited to support for the following layouts:
- FrameLayout,
- LinearLayout,
- RelativeLayout,
- GridLayout.
- ViewFlipper
- ListView
- GridView
- StackView
- AdapterViewFlipper
RemoteView supports only the following views::
Note: If you use another view, RemoteView has no operation for the view.
Receiving App Widget broadcast Intents
AppWidgetProvider is just a convenience class. If you would like to receive the App Widget broadcasts directly, you can implement your own BroadcastReceiver or override the onReceive(Context, Intent) callback. The Intents you need to care about are as follows:
- ACTION_APPWIDGET_UPDATE
- ACTION_APPWIDGET_DELETED
- ACTION_APPWIDGET_ENABLED
- ACTION_APPWIDGET_DISABLED
- ACTION_APPWIDGET_OPTIONS_CHANGED
Understanding Override Methods
The AppWidgetProvider receives only the event broadcasts that are relevant to the App Widget, such as when the App Widget is updated, deleted, enabled, and disabled. When these broadcast events occur, the AppWidgetProvider receives the following method calls:
onUpdate():
onUpdate() is called to update the App Widget at intervals defined by the updatePeriodMillis attribute in the AppWidgetProviderInfo.
This method is also called when each App Widget is added to a host (unless you use a configuration Activity), so it should perform the essential setup, such as define event handlers for Views (For example, if you want an App Widget with a button that launches an Activity when clicked) and start a temporary Service, if necessary.
If you have declared a configuration Activity, this method is not called when the user adds the App Widget, but is called for the subsequent updates. It is the responsibility of the configuration Activity to perform the first update when the configuration is done.
onAppWidgetOptionsChanged() :
onAppWidgetOptionsChanged() is called when the widget is first placed and also whenever the widget is resized. You can use this callback to show or hide content based on the widget’s size ranges.
onDeleted(Context, int[]):
onDeleted() is called every time an App Widget is deleted from the App Widget host.
onEnabled(Context):
onEnabled() is called when an instance the App Widget is created for the first time.
For example, if the user adds two instances of your App Widget, this is only called the first time. If you need to open a new database or perform other setup that only needs to occur once for all App Widget instances, then this is a good place to do it.
onDisabled(Context):
onDisabled() is called when the last instance of your App Widget is deleted from the App Widget host.
This is where you should clean up any work done in onEnabled(), such as delete a temporary database.
onReceive(Context, Intent):
onReceive() is called for every broadcast and before each of the above callback methods.
You normally don’t need to implement this method because the default AppWidgetProvider implementation filters all App Widget broadcasts and calls the above methods as appropriate.
Confused? No problem. The below GIF shows you when these methods will call.
Whenever we add/remove the app widget, the two methods onUpdate() and onDeleted() will call for each app widget instance. But onEnabled() will call only when an instance the App Widget is created for the first time and onDisabled() will only be called when the last instance of your App Widget is deleted.
In the above GIF you can see onEnabled() is called only for the first app widget instance(Creation) and onDisabled() is called only for the last instance of the App Widget(deletion).
Widget updates
A widget gets its data on periodic updates. There are two methods to update a widget, one is based on an XML configuration file and the other is based on the Android AlarmManager service.
In the widget configuration file, you can specify a fixed update interval. If the device is asleep when it is time for an update (as defined by updatePeriodMillis), then the device will wake up in order to perform the update and call your broadcast receiver to update the widget. The minimum update interval is 1800000 milliseconds (30 minutes). If you don’t update more than once per hour, this probably won’t cause significant problems for the battery life.
If, however, you need to update more frequently and/or you do not need to update while the device is asleep, then you can instead perform updates based on an alarm that will not wake the device. To do so, set an alarm with an Intent that your AppWidgetProvider receives, using the AlarmManager.
Set the alarm type to either ELAPSED_REALTIME or RTC, which will only deliver the alarm when the device is awake. Then set updatePeriodMillis to zero (“0”).
Adding Code in Widget’s Java Class
Let’s create a simple example, demonstrating the use of application Widget. It creates a basic widget application that will be opening a website on widget clicks.
Let’s add some code to our widget class.
MyAppWidget.java
public class MyAppWidget extends AppWidgetProvider { static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) { // Construct an Intent object includes web adresss. Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://c1ctech.com")); // In widget we are not allowing to use intents as usually. //We have to use PendingIntent instead of 'startActivity' PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); // Construct the RemoteViews object RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.my_app_widget); views.setOnClickPendingIntent(R.id.appwidget_text, pendingIntent); // Instruct the widget manager to update the widget appWidgetManager.updateAppWidget(appWidgetId, views); } @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { // There may be multiple widgets active, so update all of them for (int appWidgetId : appWidgetIds) { updateAppWidget(context, appWidgetManager, appWidgetId); } } }
As we can see there is an override method onUpdate which is called when the specified time defined in updatePeriodMillis attribute has reached.
After updating your AppWidgetProvider class with the above code run your app.
I hope this article will help you in understanding what is App Widget, its lifecycle and also how to add widgets into our application without doing more efforts.