Zygote
Builder trackintermediate

I07 — A tiny launcher

The home screen is just an app that registers for a category. Build a list-based launcher: query the launchable apps, show them, and start the one that is tapped.

2 minAPI 21–37 · 17verified 2026-10-27

A launcher is the clearest demonstration that Android's components are not a fixed set of app types. The home screen is an activity with a category, and any app can declare it. Building a small one shows you the app model from the outside.

What you are building#

A launcher that shows a list of launchable apps, with a search field and a tap-to-launch action. It registers as a home app, so pressing Home offers it as a choice.

Steps#

  1. Query the launchable apps

    Use the package manager to query for activities with the main action and the launcher category. Each result has a component name, a label and an icon. On Android 11 and later, package visibility affects this query; declare the intent in <queries>.1

    You should seeA list of apps with labels and icons.
  2. The query is the whole launcher:

    val intent = Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER)
    val apps = packageManager.queryIntentActivities(intent, 0)
        .map { it.activityInfo }
        .sortedBy { it.loadLabel(packageManager).toString() }
  3. Build the list

    Render the results in a LazyColumn with the icon, label and package name. Sort by label. The list is the whole launcher; everything else is polish.

    You should seeA scrollable list of apps.
  4. Launch on tap

    Build an explicit intent from the component name and call startActivity. Handle ActivityNotFoundException: an app can be uninstalled between the query and the tap.

    You should seeThe tapped app opens.
  5. Add a search field

    Filter the in-memory list by label. A launcher's search is a filter over its own data, not a system query, which is why it can be instant.

    You should seeThe list filters as you type.
  6. Register as a home app

    Add CATEGORY_HOME to the activity's intent filter in the manifest, alongside CATEGORY_DEFAULT. The system may show a chooser if there is more than one home app.2

    You should seeThe system offers your app when Home is pressed.
  7. Handle the back behaviour

    A launcher should not exit on back. Override the behaviour or consume the event, and compare with what the system launcher does.

    You should seeBack does nothing from the home screen.
  8. Handle a long press

    Add a long press action that shows app info or a shortcut. This is where a launcher starts to look like a platform surface rather than a list.

    You should seeA context menu or a no-op.
Check the home category
adb shell cmd package resolve-activity --brief -a android.intent.action.MAIN -c android.intent.category.HOME
adb shell pm list packages -3
adb shell am start -W -n com.example.tinylauncher/.MainActivity
Example output
Illustrative — results depend on installed launchers.

Verification#

Press Home and choose your launcher. Tap an app and confirm it opens. Then uninstall that app and tap its stale entry: the launcher should show a handled error, not crash.

What you learned#

  • The home screen is a category, not a component type. Any app can claim it.
  • The package manager is the launcher's data source. Icons, labels and components all come from a query.
  • Package visibility shapes what a launcher can see, which is why the manifest matters.
  • Stale entries are normal. An app can disappear between the query and the tap.

Read Launcher and home for the system launcher, and B02 — Intent explorer for the resolution mechanics.

Extend it#

  1. Add an app widget host and place a widget on the home screen; the widget model is its own lesson in cross-process views.
  2. Add folders by grouping components and persisting the grouping.
  3. Add a work profile view and show apps from a managed profile separately.

Sources#

Sources

Every version number, API level, class name and date on this page is traced to one of these. Pages are re-verified against them; last_verified above says when.

  1. docsPackage visibility filtering on Androiddeveloper.android.comaccessed 2026-10-27↩
  2. docsIntents and intent filters | App architecturedeveloper.android.comaccessed 2026-10-27↩
  3. docs活動簡介 | App architecturedeveloper.android.comaccessed 2026-10-27↩
  4. docsApp manifest overviewdeveloper.android.comaccessed 2026-10-27↩