App widgets can be thought of as a small window or controller for an Android app that can be embedded in another application (like the home screen). They can be very useful, allowing users to view or control an app without actually launching it. The great thing about widgets is that they can be updated automatically (after a time period), or in response to user action. These views are referred to as Widgets in the user interface, and you can publish one with an App Widget provider. An application component that is able to hold other App Widgets is called an App Widget host.
To create an App Widget, you need the following:
AppWidgetProviderInfo
object : Describes the metadata for an App Widget, such as the App Widget’s layout, update frequency, and the AppWidgetProvider class. This should be defined in XML.AppWidgetProvider
class implementation : Defines the basic methods that allow you to programmatically interface with the App Widget, based on broadcast events. Through it, you will receive broadcasts when the App Widget is updated, enabled, disabled and deleted.Before Android 3.1 a widget always took a fixed amount of cells on the home screen. A cell is usually used to display the icon of one application. As a calculation rule you should define the size of the widget with the formula: ((Number of columns / rows) * 74) – 2. These are device independent pixels and the -2 is used to avoid rounding errors.
As of Android 3.1 a widget can be flexible in size, e.g., the user can make it larger or smaller. To enable this for widget, you can use the android:resizeMode=”horizontal|vertical” attribute in the XML configuration file for the widget.
A widget is restricted in the View classes it can use. As layouts you can use the FrameLayout, LinearLayout and RelativeLayout classes. As views you can use AnalogClock, Button, Chronometer, ImageButton, ImageView, ProgressBar and TextView.
As of Android 3.0 more views are available: GridView, ListView, StackView, ViewFlipper and AdapterViewFlipper. These adapter views require that you define a collection view widget which is described later in this {textselfreference}.
The only interaction that is possible with the views of a widget is via an OnClickListener event. This OnClickListener can be registered on a widget and is triggered by the user.
Your BroadcastReceiver implementation typically extends the AppWidgetProvider class.
The AppWidgetProvider class implements the onReceive() method, extracts the required information and calls the following widget life cycle methods.
As you can add several instances of a widget to the home screen, you have life cycle methods which are called only for the first instance added / removed to the home screen and others which are called for every instance of your widget. Below is the table describing all methods :
Method | Description |
---|---|
onEnabled() | Called the first time an instance of your widget is added to the home screen. |
onDisabled() | Called once the last instance of your widget is removed from the home screen. |
onUpdate() | Called for every update of the widget. Contains the ids of appWidgetIds for which an update is needed. Note that this may be all of the AppWidget instances for this provider, or just a subset of them, as stated in the method’s JavaDoc. For example, if more than one widget is added to the home screen, only the last one changes (until reinstall). |
onDeleted() | Widget instance is removed from the home screen. |
In this tutorial, we are going to learn how to create a simple Android widget, that updates automatically every 30 minutes, or in response to the user tapping the update button on the widget. Our widget generates and displays a random text on every update.
1. Create a new project in Android Studio by navigating to File ⇒ New ⇒ New Project and fill required details. By default my activity is MainActivity.java.
2. Open res ⇒ values ⇒ strings.xml and add below string values. These are some strings that we are going to use in our project.
1 2 3 4 5 6 |
<resources> <string name="app_name">Widget Demo</string> <string name="widget_provider_app">Widget Provider App</string> <string name="refreshed_data">Refreshed Data.</string> <string name="refresh">Refresh</string> </resources> |
3. Let’s create a layout for our widget naming app_widget_layout.xml and add place the below code into it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/darker_gray" android:paddingLeft="5dp" tools:context="com.widget_demo.MainActivity"> <ImageView android:id="@+id/app_widget_imageView" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:src="@mipmap/ic_launcher_round" /> <TextView android:id="@+id/app_widget_textView" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:padding="10dp" android:text="@string/refreshed_data" android:textSize="13sp" android:textStyle="bold" /> <Button android:id="@+id/app_widget_actionButton" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:background="@color/colorPrimary" android:paddingLeft="5dp" android:paddingRight="5dp" android:text="@string/refresh" android:textSize="11sp" /> </LinearLayout> |
4. Now create new java class naming MyWidgetProvider.java that extend AppWidgetProvider. AppWidgetProvider has methods that are called when the app widget is updated, deleted, enabled and disabled among others. For our implementation, we only override onUpdate(), because it is the method called whenever the widget is added to a host.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
package com.widget_demo; import android.app.PendingIntent; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; import android.content.Context; import android.content.Intent; import android.widget.RemoteViews; import java.util.Random; /** * Created by sonu on 10/04/17. */ public class MyWidgetProvider extends AppWidgetProvider { // String array to show text at textview on refresh private static final String[] refreshStrings = {"Refreshed successfully.", "Data Loaded.", "Done loading.", "Refreshed.", "Great Job."}; @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { // Perform this loop procedure for each App Widget that belongs to this provider for (int widgetId : appWidgetIds) { //get random text from refreshStrings String stringText = refreshStrings[new Random().nextInt(refreshStrings.length)]; // Create an Intent to launch MainActivity Intent intent = new Intent(context, MainActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); // Create an Intent to Refresh MyWidgetProvider Intent intent1 = new Intent(context, MyWidgetProvider.class); intent1.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE); intent1.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds); PendingIntent pendingIntent1 = PendingIntent.getBroadcast(context, 0, intent1, 0); // Get the layout for the App Widget and attach an on-click listener // to the button and imageview RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.app_widget_layout); //set the random text remoteViews.setTextViewText(R.id.app_widget_textView, stringText); //set pending intent1 to action button to refresh Widget remoteViews.setOnClickPendingIntent(R.id.app_widget_actionButton, pendingIntent1); //set the pending intent to open MainActivity remoteViews.setOnClickPendingIntent(R.id.app_widget_imageView, pendingIntent); // Tell the AppWidgetManager to perform an update on the current app widget appWidgetManager.updateAppWidget(widgetId, remoteViews); } } } |
5. Now to provide AppWidgetProviderInfo metadata we need to create xml file that defines additional information, features and data related to the widget. Data such as minimum layout dimensions (width and height), if the widget should be available on the lock screen (Android 4.2 and above), how frequently the widget should be updated, among many others. We define an xml file, called app_widget_provider_info.xml under res/xml folder.
1 2 3 4 5 6 7 8 9 |
<?xml version="1.0" encoding="utf-8"?> <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:initialLayout="@layout/app_widget_layout" android:minHeight="50dp" android:minWidth="200dp" android:previewImage="@mipmap/ic_launcher_round" android:resizeMode="horizontal|vertical" android:updatePeriodMillis="1800000" android:widgetCategory="home_screen|keyguard" /> |
6. The final step is to add the app widget to the AndroidManifest.xml file. Within the <application> </application> element tags, place the below lines.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<!-- Declare WidgetProvider --> <receiver android:name=".MyWidgetProvider"> <!-- Add APPWIDGET_UPDATE intent filter here to receiver Widget Update --> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> <!-- Add app widget provider info xml in meta data --> <meta-data android:name="android.appwidget.provider" android:resource="@xml/app_widget_provider_info" /> </receiver> |
7. Finally all done, now you can also make apps with Widgets.
Thanks.
Subscribe to us and get the latest news.