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.
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#
- 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>.1You should seeA list of apps with labels and icons. - Build the list
Render the results in a
LazyColumnwith 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. - Launch on tap
Build an explicit intent from the component name and call
startActivity. HandleActivityNotFoundException: an app can be uninstalled between the query and the tap.You should seeThe tapped app opens. - 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. - Register as a home app
Add
CATEGORY_HOMEto the activity's intent filter in the manifest, alongsideCATEGORY_DEFAULT. The system may show a chooser if there is more than one home app.2You should seeThe system offers your app when Home is pressed. - 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. - 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.
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() }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/.MainActivityExample 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#
- Add an app widget host and place a widget on the home screen; the widget model is its own lesson in cross-process views.
- Add folders by grouping components and persisting the grouping.
- 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.
- docsPackage visibility filtering on Androiddeveloper.android.comaccessed 2026-10-27↩
- docsIntents and intent filters | App architecturedeveloper.android.comaccessed 2026-10-27↩
- docs活動簡介 | App architecturedeveloper.android.comaccessed 2026-10-27↩
- docsApp Linksdeveloper.android.comaccessed 2026-10-27↩
- docsApp manifest overviewdeveloper.android.comaccessed 2026-10-27↩