App widgets are miniature app views users place on the Android home screen to display information or provide quick interactions without launching the full app.
This modern guide on javatechig.com explains how to create robust and production-ready Android app widgets with real update logic, configuration settings, and best practices covering both Kotlin and Java implementations aligned with current Android standards.
What Are Android App Widgets?
Android app widgets are interactive views that live on the home or lock screen. They provide glanceable information and lightweight control from outside your app.
Common examples include:
- Weather widgets
- Music control widgets
- Calendar overview
- Notes and to-do lists
Widgets are powered by a dedicated component: AppWidgetProvider.
App Widget Architecture (Modern Overview)
Widget functionality is driven by:
- AppWidgetProvider – BroadcastReceiver extension handling widget events
- AppWidgetProviderInfo – XML metadata describing size and update frequency
- RemoteViews – Remote UI that updates widget layout
Widgets are updated via scheduled or manual triggers.
Step 1 – Create Widget Layout
Define your widget UI in XML (res/layout/widget_layout.xml):
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:padding="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:background="@color/widget_background">
<TextView
android:id="@+id/widget_text"
android:text="Hello Widget"
android:textSize="16sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
Step 2 – Define AppWidgetProviderInfo
In res/xml/widget_info.xml:
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider
xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="180dp"
android:minHeight="60dp"
android:updatePeriodMillis="1800000"
android:initialLayout="@layout/widget_layout"
android:resizeMode="horizontal|vertical"
android:previewImage="@drawable/widget_preview"/>
Key attributes:
updatePeriodMillis: Time interval for scheduled updatesinitialLayout: Default view layoutresizeMode: Size flexibility
Step 3 – Create AppWidgetProvider Class
In Kotlin:
class SimpleWidget : AppWidgetProvider() {
override fun onUpdate(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetIds: IntArray
) {
for (widgetId in appWidgetIds) {
val views = RemoteViews(context.packageName, R.layout.widget_layout)
views.setTextViewText(R.id.widget_text, "Updated at ${System.currentTimeMillis()}")
appWidgetManager.updateAppWidget(widgetId, views)
}
}
}
Java version:
public class SimpleWidget extends AppWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
for (int widgetId : appWidgetIds) {
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
views.setTextViewText(R.id.widget_text, "Updated at " + System.currentTimeMillis());
appWidgetManager.updateAppWidget(widgetId, views);
}
}
}
Step 4 – Register Widget in Manifest
<receiver
android:name=".SimpleWidget"
android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget_info"/>
</receiver>
This allows Android to know your widget exists and how to manage it.
Updating Widgets Manually
Widgets can be updated:
From Activity or Service
val mgr = AppWidgetManager.getInstance(context)
val widgetIds = mgr.getAppWidgetIds(ComponentName(context, SimpleWidget::class.java))
widgetIds.forEach { id ->
val views = RemoteViews(context.packageName, R.layout.widget_layout)
views.setTextViewText(R.id.widget_text, "Refreshed")
mgr.updateAppWidget(id, views)
}
Interactive Widget Elements
You can add click listeners to widgets using PendingIntent.
val intent = Intent(context, MainActivity::class.java)
val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
views.setOnClickPendingIntent(R.id.widget_text, pendingIntent)
This lets users interact without opening the app.
Widget Configuration Activity (Optional)
If your widget needs user preferences:
- Create a configuration activity
- Register it in
widget_info.xml:
android:configure="com.example.WidgetConfigActivity"
Config activities allow users to customize widget behavior.
Common Widget Issues & Fixes
Widget Not Appearing
Cause: Incorrect widget_info setup
Fix: Verify minWidth and minHeight values match launcher grid.
Updates Not Triggering
Cause: updatePeriodMillis too low
Fix: Android may throttle updates. Use manual or WorkManager triggers.
Click Not Working
Cause: Missing PendingIntent binding
Fix: Ensure setOnClickPendingIntent() is set for each view.
Best Practices (2026 Updated)
- Avoid frequent automatic updates — use WorkManager for periodic tasks
- Use RemoteViews sparingly for performance
- Support all screen sizes and densities
- Provide meaningful widget previews
- Respect battery and memory constraints


