Skip to content

Add Quick Settings tiles snippets - #16

Closed
hamen wants to merge 3 commits into
mainfrom
views-quicksettings-tiles
Closed

hamen wants to merge 3 commits into
mainfrom
views-quicksettings-tiles

Conversation

@hamen

@hamen hamen commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

This change adds the three Kotlin snippets from
Quick Settings tiles to
views/src/main/java/com/example/example/snippet/views/quicksettings/QuickSettingsTilesSnippets.kt.

Each region gives the same lines that the page shows today. You can include the snippets without a
change to the text around them.

Region tag Page section Same as the page? Lines snippet/page Lines the formatter moved
android_views_quicksettings_tile_service Create and declare your TileService Yes, but the format is different 25/25 21
android_views_quicksettings_update_tile Update your tile One line is different. Refer to the next section. 11/11 6
android_views_quicksettings_handle_taps Handle taps One line is different. Refer to the next section. 9/9 6

The last column shows what spotlessApply changed. ktlint made the indent four spaces in the place of
two. It also added a space in class MyQSTileService : TileService(). The number of lines did not
change. Each snippet stays as long as the block that it replaces.

Two lines that are not a copy of the page

Each Kotlin block uses a name that the block does not declare. Neither block compiles as published.

Update your tile sets the content description from tile.label. The Kotlin block has no tile.
All the other lines in the block use qsTile. The Java block on the same page declares
Tile tile = getQsTile(), and then uses tile. The Kotlin block reads like a translation that lost
the local variable and kept one use of it. A build of the published lines gives
Unresolved reference 'tile'. The snippet uses state.label, which is the value qsTile.label was
assigned one line earlier, so every right-hand side in the block now reads from the model the block
declares. That is the reviewer's suggestion and it is better than the first answer here, which was
qsTile.label: that compiled, but it read the property back out of the object it had just been
written into, and it was the one line in the block not sourced from state.

The Java block on the same page keeps its tile local, so the page can be repaired either way: give
the Kotlin block the Tile tile = getQsTile() line its Java sibling has, or read from state as
this snippet does.

Handle taps declares var clicks = 0, and then increases counter four times. A build of the
published lines gives four errors of Unresolved reference 'counter'. The snippet gives the name
counter to the declaration. This changes one line and not four.

You can correct the block in the other direction. If you give the name clicks to the four uses, the
block is also correct. The block cannot stay as it is, because it does not compile. The snippet takes
the smaller change. Please use the name that reads better on the page. The snippet does not hold you
to this one.

Both blocks need a correction on the page. A reader who copies them today gets a compile error.

How the file is arranged

StateModel is inside UpdateTileService, and not at the top level. The page shows the data class,
then an empty line, then the override. Two spans of one region tag cannot keep that empty line, and
the published snippet would be one line shorter than the block. One span keeps the empty line. The
nesting does not change what the page shows.

getStateFromService() is outside the region tags, and it does not appear on the page. The page calls
this function in the Kotlin block and in the Java block, but the page does not define it anywhere. It
reads as a function of the app, and not as a platform API. The stub is here only to let the module
compile.

The three regions are in three subclasses of TileService, and not in one class. The first block
overrides onStartListening() and onClick(). The second block overrides onStartListening(). The
third block overrides onClick(). The second block and the third block cannot go in the first class.

The other code blocks on the page

No other block on the page has a region tag. The line numbers are from quicksettings-tiles.md.txt.

Block Line Lines What to do with it
Java, Create and declare your TileService 101 32 Remove it with the page change
Java, Update your tile 328 23 Remove it with the page change
Java, Handle taps 379 12 Remove it with the page change
Java, Prompt the user to add your tile 513 7 Keep it. Refer to the note below.
Launch an activity 420 3 Your decision. Refer to the note below.
XML manifest, Create and declare your TileService 140 10 Not extracted. Refer to the note below.
XML manifest, Active mode (recommended) 223 5 Not extracted
XML manifest, Mark your tile as toggleable 436 4 Not extracted
XML manifest, Implementation 474 7 Not extracted

Keep the block at line 513. It shows the signature of requestAddTileService(), and it is not an
example that a reader copies. It belongs with the reference text around it.

The block at line 420 adds Intent.FLAG_ACTIVITY_NEW_TASK. It sits in the text, and not below a
Kotlin heading or a Java heading, so it reads as an example for the two languages. But it has a
semicolon, and this makes it Java as it is written. If you remove the semicolon, the block becomes
Kotlin, and it stays correct for a Java reader. This is a decision for the page, so I made no change
to it.

The four XML manifest examples are not Kotlin, and this change does not extract them. The example at
line 140 has a small defect that you can correct while the page is open:

android:label="@string/my_default_tile_label"  // 18-character limit.

XML has no // comment. The example does not parse as it is printed, and a reader who copies it gets
a manifest that does not build. Put the note above the element as <!-- 18-character limit. -->. The
note stays, and the example builds. This has no effect on the snippets.

Thanks for the review. Tell me if you prefer a different choice at any of the points above.

Extract the three Kotlin blocks from the Quick Settings tiles guide:
the TileService skeleton, the tile update in onStartListening(), and
the tap handler.

https://developer.android.com/develop/ui/views/quicksettings-tiles

Two blocks name an identifier the page never declares, so they do not
compile as published:

- Update your tile: the block sets contentDescription from tile.label,
  but the Kotlin sample has no tile local. The Java sample on the same
  page does. Use qsTile.label, as the Handle taps block already does.
- Handle taps: the block declares var clicks and then increments
  counter four times. Name the property counter.

Both need a page fix.
@hamen hamen self-assigned this Sep 2, 2026
@hamen
hamen marked this pull request as ready for review September 2, 2026 11:31

@kkuan2011 kkuan2011 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catches! Looks good.

For the block at line 420 that adds Intent.FLAG_ACTIVITY_NEW_TASK. - can we migrate this one too and make it a kotlin snippet? After you've added it, feel free to merge!

The reviewer asked for `state.label` instead of `qsTile.label`, so that every
right-hand side in the block comes from the model the block declares. She is
right, and it is a better answer than the one this branch shipped.

Both compile. The page's own line does not: it prints
`qsTile.contentDescription = tile.label` where the Kotlin block declares no
`tile`, and building that line gives `Unresolved reference 'tile'`. Something
had to replace it. `qsTile.label` was the smaller edit, but it reads the
property back out of the object it was written into one line earlier, and it
left one line in the block not sourced from `state`.

The page can be repaired either way, and the description says so: give the
Kotlin block the `Tile tile = getQsTile()` line its Java sibling on the same
page already has, or read from `state`.

Claude-Session: https://claude.ai/code/session_01P9x2zonc8Jow9hajZw96pn
@hamen

hamen commented Sep 11, 2026

Copy link
Copy Markdown
Collaborator Author

The upstream equivalent is open: android#1087

Same file, same three region tags, cut fresh off android/snippets@main. Closing this one, since the review has moved there.

@hamen hamen closed this Sep 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants