Android SharedPreferences Tutorial and Example

Building a home screen widget for your Android application

Android widgets sit directly on the home screen, giving users a glanceable window into your app's most useful features. In Australia, where Android runs on roughly three out of every four smartphones, a well-crafted widget can be the difference between an app that gets installed and one that earns daily engagement. Australians increasingly rely on widgets for quick access to weather, transport feeds across Sydney and Melbourne, sports scores from the AFL and NRL, and local news from the ABC.

This walkthrough covers the full path from a blank Android Studio project to a working widget that survives reboots, responds to taps, and updates itself on a sensible schedule. You will write an AppWidgetProvider, design the layout with RemoteViews, wire up PendingIntents for user actions, and explore different update strategies. The examples lean on Kotlin, but the same patterns apply if you are still working in Java or gradually migrating a legacy codebase.

Grasping the widget architecture

A home screen widget is essentially a tiny live broadcast that the system launcher reads on your behalf. The core building block is AppWidgetProvider, a specialised BroadcastReceiver that receives system messages such as APPWIDGET_UPDATE, APPWIDGET_ENABLED, and APPWIDGET_DELETED. Each of these callbacks gives you a chance to redraw the interface through RemoteViews, the only object the launcher will accept across process boundaries.

Four pieces come together behind every widget: the AppWidgetProvider class itself, a layout file with the visual structure, an XML metadata file in res/xml, and a <receiver> entry inside AndroidManifest.xml. RemoteViews supports a constrained subset of the Android view hierarchy, including LinearLayout, FrameLayout, RelativeLayout, GridLayout, plus primitives like TextView, ImageView, Button, ProgressBar, ListView, and the newer AdapterViewFlipper. Anything outside that list, including custom views, will throw a runtime exception the first time the launcher tries to inflate it.

Australians running Android 12 or newer, which most devices do given how aggressively Telstra, Optus, and Vodafone Australia push OS upgrades, also benefit from a cleaner theming system where your widget automatically picks up light or dark variants of the launcher wallpaper.

Preparing your project structure

Begin by creating a new module or adding the widget pieces to an existing app. Drop a new layout file into res/layout/ for the visual design, then create res/xml/widget_info.xml to describe the widget's dimensions, preview image, and update period. The minimum widget dimensions you should declare are minWidth of at least 110dp for a single cell, scaling up to 250dp or beyond for richer tiles.

The metadata file is also the right place to set widgetCategory, which lets you expose the widget on the home screen, the lock screen, or both. On Android 12 and later, you can also specify targetCellWidth and targetCellHeight in cells rather than dp, which is far easier to reason about when designing around the standard 4x4 launcher grid popular on Samsung and Pixel devices sold down here.

Register the provider in the manifest with an intent filter for android.appwidget.action.APPWIDGET_UPDATE. If your app stores its data in SQLite, the same database you have been using across your main activities can back your widget directly, and a quick detour through Android SQLite tutorials is worthwhile before you design the data layer.

Designing the RemoteViews layout

Treat the widget layout like any other Android layout, with two key restrictions. First, every interactive element must be addressable by ID so a PendingIntent can be wired to it later. Second, the entire layout must fit comfortably on a standard launcher without scrolling, which means leaning on compact typography and avoiding scrollable containers.

A practical pattern is to combine a header TextView, a single piece of dynamic content, and an action Button at the bottom. For example, an Australian weather widget might show the current temperature in Celsius for your capital city along with a "refresh now" button, while a transport widget could show the next three trains from Central Station in Sydney or Flinders Street in Melbourne.

Keep the colour palette aligned with Material You, and reuse theme attributes rather than hard-coded hex values. That way the widget respects any dynamic colour scheme the user has chosen on their Pixel 7 or Galaxy S24 in their Brisbane apartment, and the tile blends in with the rest of the launcher's accent colours.

Wiring up updates and interactions

The heart of any widget is how it stays current. The Android system offers three practical update mechanisms: the periodic updatePeriodMillis defined in metadata, AlarmManager for exact-time refreshes, and WorkManager for resilient background jobs that survive reboots. Each has trade-offs worth weighing.

Mechanism Best for Battery cost Survives reboot
updatePeriodMillis Static info refreshed hourly or less Low Yes, via system
AlarmManager Time-of-day schedules across AEST, ACST, AWST Moderate Only if a BOOT_COMPLETED receiver restarts it
WorkManager Network-backed content, conditional fetches Low to moderate, OS-managed Yes, built-in

For most Australian scenarios, a combined approach works well. Schedule a daily midnight refresh in local AEST with AlarmManager to reset counters, then let WorkManager handle interval updates whenever the user opens a related screen in your app. Pair every interactive view with a PendingIntent that calls AppWidgetManager.notifyAppWidgetViewDataChanged or triggers a manual refresh through the InvalidateRect refresh approach when handling cross-process UI.

Reading and writing local data

If your widget shows information that lives inside the app, share the data through your existing Repository rather than opening a fresh database query from the provider. Use a ContentProvider or pass serialised data through the widget's RemoteViews extras, then refresh through notifyAppWidgetViewDataChanged whenever the underlying data changes.

A common Aussie use case is a takeaway menu widget that opens when you tap the tile. Store the restaurant's last viewed order in SQLite, expose it through your provider, and the widget can render the cached order count even when the device is offline on a regional train through the Hunter Valley or up in Far North Queensland. No worries if the network drops, because the widget still reads accurately from disk.

Another nice touch on Android 12 and above is the requestPinAppWidget API, which lets you offer a one-tap shortcut from inside your activity straight onto the user's home screen. Combine it with a polite in-app prompt after a successful order to grow your active widget footprint organically.

Testing across devices and launchers

Real-world testing matters more with widgets than with most Android features, because launchers behave differently. Samsung One UI, Google Pixel Launcher, and the open-source Lawnchair all size widgets slightly differently and respect slightly different drag thresholds. Spin up an emulator with a Pixel 6 Pro profile, a Galaxy S22 profile, and a budget Motorola to confirm the widget looks right across each resize configuration.

Drop into a local meetup such as the Sydney or Melbourne Google Developer Group sessions if you want feedback on real devices. The Droid Down Under community runs regular show-and-tell nights where you can preview a widget on phones owned by designers, testers, and fellow devs. Once you have polished the layout and confirmed the update path survives a reboot and a process kill, publish the new release to the Play Store and watch the adoption roll in.