quicksettingsAndroid’s Quick Setting Tiles enable users to quickly access important system settings and applications with a simple swipe and click. These tiles represent several system settings, including Wi-Fi, Bluetooth, location, and rotation, but there has never been a way for non-system applications to participate. That has all changed with the release of Android Nougat and the Quick Settings Tile API, which empowers any developer to add their own setting with just a few lines of code. These new APIs have been enabled in the latest release of Xamarin.Android, now available as part of Cycle 8 Service Release 1.

Adding a Tile Service

Quick Setting Tiles are completely controlled by a new Android service, a TileService that can be executed without the application running. We can create our own TileService by inheriting from it once the compile and target APIs have been set to 24 (Android Nougat):

using Android.App;
using Android.Graphics.Drawables;
using Android.Service.QuickSettings;
using Android.Views;
using Java.Lang;

public class GetMonkeyService : TileService
{
}

Manifest Settings

Inheriting and creating the TileService will not be enough to actually get a Quick Setting Tile to show up, as we must specify particular metadata and intent filters for our new service. This can be accomplished with a few attributes on top of the class we just created:

[Service(Name = "com.refractored.monkeysapp.GetMonkeyService",
             Permission = Android.Manifest.Permission.BindQuickSettingsTile,
             Label = "@string/tile_name",
             Icon = "@drawable/ic_tile_default")]
[IntentFilter(new[] { ActionQsTile })]
public class GetMonkeyService : TileService
{

}

The Service’s Label and Icon will show up in the Quick Settings area, so be sure to set those specific to your application. With just this code, the tile will show up and the user could possibly add it to their Quick Settings.

Quick Setting Events

Our new tile has four extremely important events that it can respond to: when it’s added or removed and when it’s visible or not. Each of these events are exposed with a simple override:

//First time tile is added to quick settings
public override void OnTileAdded()
{
  base.OnTileAdded();
}

//Called each time tile is visible
public override void OnStartListening()
{
  base.OnStartListening();
}

//Called when tile is no longer visible
public override void OnStopListening()
{
  base.OnStopListening();
}

//Called when tile is removed by the user
public override void OnTileRemoved()
{
  base.OnTileRemoved();
}

Updating Quick Setting Tiles

Once the user has added the tile, our service will receive an OnStartListening each time the user swipes down. This gives us an opportunity to update the tile with additional information. We can update the tile by getting reference to the QsTile and then modifying properties and applying an Update() such as the following:

public override void OnStartListening()
{
  base.OnStartListening();

  //Tile associated with the service
  var tile = QsTile;

  //Update label, icon, description, and state
  tile.Icon = Icon.CreateWithResource(this, Resource.Drawable.ic_tile_default);
  tile.Label = GetString(Resource.String.tile_name);
  //Set state here and UI will respond automatically
  tile.State = TileState.Active;
  tile.UpdateTile();
}

Responding to Tile Clicks

Now it’s time to actually respond to clicks on our fancy new tile. This is done with another method that we can override, conveniently named “OnClick”. When the tile is clicked, we can do one of three things:

  • Start a background service to process information
  • Open Dialog if the user needs more context
  • Start an activity

In this example, we’ll open a new dialog that will show an adorable monkey. It’s important to remember that our tile can be visible even if the phone is locked, so we must prompt the user to unlock first before opening it.

public override void OnClick()
{
  base.OnClick();

  if (IsLocked)
  {
    //Open Dialog is unavailable here
    //Option 1: Kick of background service
    //Option 2: Prompt user to unlock
    UnlockAndRun(new Runnable(() =>
    {
      //Show Dialog when unlocked
      ShowDialog(MonkeyDialog);
    }));
  }
  else
  {
    //Show Dialog
    ShowDialog(MonkeyDialog);
  }
  //Additionally, update tile if needed here.
}

Learn More

You can grab the full source code from my Monkeys App sample on GitHub, or download the app today on Google Play. Be sure to dive through the API documentation on the new Tile API.