App Shortcuts & Widgets (Java)
Not every entry point into RecipeBox has to go through the launcher icon and main screen. App Shortcuts surface quick actions when a user long-presses the launcher icon, and App Widgets place a small live view of the app right on the home screen. Both give an app a presence outside its own UI.
App Shortcuts: Static vs Dynamic
Long-pressing RecipeBox's launcher icon can pop up a small menu of shortcuts. There are two kinds: static shortcuts, declared once in XML and unchanging until the next app update, and dynamic shortcuts, set and updated at runtime based on user behavior.
Static Shortcuts
A static shortcut is defined in res/xml/shortcuts.xml and referenced from the manifest. This is the natural fit for an action that never changes — like jumping straight to RecipeBox's "add a new recipe" screen:
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
<shortcut
android:shortcutId="add_new_recipe"
android:enabled="true"
android:icon="@drawable/ic_shortcut_add"
android:shortcutShortLabel="@string/shortcut_add_short"
android:shortcutLongLabel="@string/shortcut_add_long">
<intent
android:action="android.intent.action.VIEW"
android:targetPackage="com.recipebox"
android:targetClass="com.recipebox.AddRecipeActivity" />
</shortcut>
</shortcuts>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.shortcuts"
android:resource="@xml/shortcuts" />
</activity>
Dynamic Shortcuts
A dynamic shortcut is pushed at runtime through ShortcutManager — perfect for something that changes per user, like offering fast access to the recipe they viewed most recently:
// Called right after the user opens a recipe's detail screen
public void pinRecentRecipeShortcut(Context context, Recipe recipe) {
ShortcutManager shortcutManager = context.getSystemService(ShortcutManager.class);
Intent intent = new Intent(context, RecipeDetailActivity.class);
intent.setAction(Intent.ACTION_VIEW);
intent.putExtra("recipe_id", recipe.getId());
ShortcutInfo shortcut = new ShortcutInfo.Builder(context, "recent_recipe")
.setShortLabel(recipe.getTitle())
.setIcon(Icon.createWithResource(context, R.drawable.ic_shortcut_recipe))
.setIntent(intent)
.build();
shortcutManager.setDynamicShortcuts(Collections.singletonList(shortcut));
}
- setDynamicShortcuts() replaces the current dynamic set — call it again whenever the "most recent" recipe changes.
- Android also allows a user to explicitly pin a dynamic shortcut to their home screen, which then persists independently of your app updating the dynamic list.
- A device typically limits how many dynamic shortcuts an app may have active at once — keep the list short and relevant.
App Widgets: Glanceable Home Screen UI
A widget is a small, self-updating piece of UI living on the home screen — for RecipeBox, imagine a "Today's Recipe Suggestion" box showing a photo and title without opening the app at all. Widgets are built by extending AppWidgetProvider and overriding onUpdate():
// RecipeSuggestionWidget.java
public class RecipeSuggestionWidget extends AppWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
for (int widgetId : appWidgetIds) {
Recipe suggestion = RecipeRepository.getTodaysSuggestion(context);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_recipe_suggestion);
views.setTextViewText(R.id.widgetRecipeTitle, suggestion.getTitle());
views.setImageViewUri(R.id.widgetRecipeImage, Uri.parse(suggestion.getPhotoUri()));
appWidgetManager.updateAppWidget(widgetId, views);
}
}
}
The widget's own layout is a separate, simple XML file:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="12dp">
<ImageView
android:id="@+id/widgetRecipeImage"
android:layout_width="match_parent"
android:layout_height="80dp" />
<TextView
android:id="@+id/widgetRecipeTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="bold" />
</LinearLayout>
Declaring the Widget Provider
The widget needs a small info XML describing its size and update behavior, plus a manifest entry registering the provider:
<!-- res/xml/recipe_suggestion_widget_info.xml -->
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="180dp"
android:minHeight="110dp"
android:updatePeriodMillis="1800000"
android:initialLayout="@layout/widget_recipe_suggestion"
android:resizeMode="horizontal|vertical" />
<receiver android:name=".RecipeSuggestionWidget"
android:exported="false">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/recipe_suggestion_widget_info" />
</receiver>
Both Increase Visibility
Shortcuts and widgets share one goal: making RecipeBox visible and reachable without a user having to open the app first. A well-placed shortcut or widget genuinely increases engagement, because it turns a multi-tap journey into a single glance or tap.