New tiles in Android N with the Edit Screen showing

Quick Settings in Android N

Android N introduced a new Quick Settings Tile API, which will no doubt be used innovatively and exploited by developers in the future when the version reaches release level. However, what exactly can we expect these tiles to be used for, how can they be used and how are they likely going to be abused?

Note: Although it has not changed between Preview 1 and Preview 2, the tile API may change before N’s release. It’s possible therefore if you’re reading this in the far future that there may be things that have changed

What exactly is this API?

Quick Settings in Android are not new. They’ve been in AOSP since 4.2 Jelly Bean and have taken a few forms; firstly their own page off the notification drawer, then as an expanded state from the drawer, and in N they gained a collapsed state also.

Although N is the first version to include a proper API, the ability to create custom tiles is not new, in fact the Broadcast (Intent) Tile has existed since 5.0 Lollipop, which provided a very non-user-friendly way of adding their own tiles with the help of third party apps for this purpose, including my own Custom Quick Settings. In N the Intent tile still exists in the code, however it does not appear to be able to be added from the “edit” interface of the quick settings.

Adding a tile using the edit interface in Android N

Instead, developers can create their own tiles, using the new TileService class, and declaring the tiles in the Manifest. They then appear in the “edit” interface and need to be dragged into their preferred position by a user before being able to be initalised by the app. (left)

This means that, in order to use the API, developers must declare all their tiles before the app is run in the Manifest, as they are extensions of Services. They then all appear in the edit screen with the default title and icon declared in that same Manifest node. There does not appear to be a maximum number of tiles that can be declared in the Manifest, however services can be enabled and disabled using the package manager as a normal service would, which allows for showing and hiding tiles from this screen, just so long as they were declared initially.

Similarly, deleting the tiles is done by dragging tiles back to the list from the currently added tiles. Note that when rearranging & deleting tiles, tiles will have their default title and icon from the Manifest, regardless of whether they have been updated by a TileService.

How will the API be used & abused by apps?

The following section is all speculation about how this API will be used. Only the future will bring what will actually happen.

In the API Overview for N, Google say this about Quick Settings:

Quick Settings tiles are reserved for controls or actions that are either urgently required or frequently used, and should not be used as shortcuts to launching an app.

This is advise, and I predict that it is unlikely to be followed by a fair few developers, especially when under pressure from companies and users.

The three main uses for tiles that are likely to surface are as follows:

Shortcuts

Shortcuts are what many would think as the first use for this new API, allowing for developers to simply open their apps from the Quick Settings, which some may argue falls under the “frequently used”, however many of these shortcuts will only clutter the “edit” interface. Not advised, but will probably happen. Google already broke this advise and added a Calculator tile in Preview 2

Activity Shortcuts

Arguably coming under shortcuts, however not exactly the same thing. Like launcher shortcuts, which allow a specific activity or part of an app to be opened, tiles could be used to do the same thing. A user may want to open the Bookmarks activity of Chrome for example. Again, this is not advised and is less likely to happen than just app shortcuts, but would have the same disadvantages to them.

Actions

The only real recommendation from Google, and possibly a chance for developers to get rid of single-button widgets. I’ve showed an example of a toggle that could turn on and off a smart-bulb, but it could be applied to millions of actions that are toggled frequently by the user. A good idea, however too many tiles will only cause the same cluttering…

Tile Abuse

Task killers, SD cleaners, offers/adverts (they’re technically not notifications, it may be a loophole around the notification advert restriction), app icons with tickers, you can probably guess what developers will come up with just to get a tile in the list. Thankfully, as all tiles must be added by the user, there’s far less chance of spam adverts and unwanted tiles simply appearing, and if they do you can just remove them.

Tile Restrictions

One major difference between system tiles and custom tiles is that the long click action is disabled for opening the “app info” screen. It’s possible to use double click however. Intent tiles on 5.0 to before N allowed for long click actions also, but were significantly slower at performing their action after being clicked.

Tiles can only have icons of a single colour, which is always tinted to either white (on state) or one of two shades of grey (for the inactive states). Unless an app icon is also a single colour and could work when being fully replaced with the listed colours, it’s not going to work here

Custom tiles can’t have RemoteViews, unlike system ones. You can’t have an expanded state for a tile, so you must either launch an activity on click or perform the activity there and then, and optionally update the tile to a new state to show what it’s done. It would be nice to see RemoteViews implemented in a future release, à la CyanogenMod, but this is the choice of Google.


I’m a developer, how exactly do I use these tiles?

Your first step is to download the Android N API reference as it’s not available on the Android site yet. Specifically, read the documentation for TileService ( android.service.quicksettings.TileService) and Tile ( android.service.quicksettings.Tile)

TileService

To create a tile, you must have a class that extends TileService. Declare this in your manifest as you would a normal service, with a few changes

<service
android:name=".MyTileService"
android:icon="@drawable/my_tile_icon"
android:label="@string/my_tile_label"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"
>
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
</service>

Change the icon and label, and obviously the class name

Optionally, disable the tile (hide it from the “edit” interface for enabling programmatically)

android:enabled="false"

You must do this for all tiles you wish to add, regardless of whether they will be enabled when the app starts.

In the class, override the following methods as you like:

/* 
Called when the tile is added to the quick settings from the edit interface by the user. If you keep track of added tiles, override this and update it.
Return either TILE_MODE_ACTIVE or TILE_MODE_PASSIVE depending on your requirements
*/
public int onTileAdded()
/*
Called when the tile is removed from the quick settings using the edit interface. Similarly to onTileAdded, override this and update your tracking here if you need to
*/
public void onTileRemoved()
/*
Called when the tile is brought into the listening state. Update it with your icon and title here, using getQsTile to get the tile (see below)
*/
public void onStartListening ()
/*
Called when the tile is brought out of the listening state. This represents when getQsTile will now return null.
*/
public void onStopListening ()
/*
Called when the tile is clicked. Can be called multiple times in short succession, so double click (and beyond) is possible
*/
public void onClick ()

The class has a single method to get the Tile:

/*
Returns the Tile or null if the method is called when the tile is not in the listening state
*/
public final Tile getQsTile ()

A single method used when the tile is in active mode:

/*
Moves the tile into the listening state, which will call onStartListening
*/
public static final void requestListeningState (Context context, ComponentName component)

And it has a few methods for useful extras:

/*
Returns whether the device is showing the lock screen or not. The API reference recommends using this if you wish to launch an activity on top of the lockscreen using startActivity(intent) from ContextWrapper
*/
public final boolean isLocked ()
/*
Returns if the device is secure
*/
public final boolean isSecure ()
/*
Can be used to show a Dialog, but does not work on top of the lock screen
*/
public final void showDialog (Dialog dialog)
/*
Collapses the notification drawer and launches an intent
*/
public final void startActivityAndCollapse (Intent intent)
/*
Unlocks the device (or shows the password prompt) and runs the Runnable. Use isLocked to check if the device is locked before running this
*/
public final void unlockAndRun (Runnable runnable)

Tile

The tile class is fairly simple, holding a label, state, icon and content description. It has an update method, which you must call to update the tile after changing any of these.

Setters

/*
Sets the icon of the tile, which will be tinted to a single colour by the system. You must call updateTile to update the tile to display this
*/
public void setIcon (Icon icon)
/*
Sets the label of the tile. You must call updateTile to update the tile to display this
*/
public void setLabel (CharSequence label)
/*
Sets the state of the tile. It can be one of the following:
- STATE_ACTIVE: Normal colour of tile (white on AOSP), can be clicked. Use for "on"
- STATE_INACTIVE: Tile is inactive (grey) but can still be clicked. Use for "off".
- STATE_UNAVAILABLE: Tile is disabled and cannot be clicked. It has a different grey to INACTIVE, and could be optionally used for a "working" state when it is processing
You must call updateTile to update the tile to display this
*/
public void setState (int state)
/*
Sets the content description of the tile. You must call updateTile to update the tile to change this
*/
public void setContentDescription (CharSequence contentDescription)

Getters

/*
Gets the icon of the tile
*/
public Icon getIcon ()
/*
Gets the label of the tile
*/
public CharSequence getLabel ()
/*
Gets the state of the tile, one of the following:
- STATE_ACTIVE: Normal colour of tile (white on AOSP), can be clicked. Use for "on"
- STATE_INACTIVE: Tile is inactive (grey) but can still be clicked. Use for "off".
- STATE_UNAVAILABLE: Tile is disabled and cannot be clicked. It has a different grey to INACTIVE, and could be optionally used for a "working" state when it is processing
*/
public int getState ()
/*
Gets the content description of the tile
*/
public CharSequence getContentDescription ()

There’s also an updateTile method, mentioned above, that you must call to update the tile when ready:

/*
Update the tile, you must call this when you change the label, icon, content description or state
*/
public void updateTile ()

Helpful hints

Any number of classes can extend from an extension of TileService. If you need multiple tiles that are configurable to do the same set of tasks, you may consider having a single class that controls this and many extensions of that class