-
Notifications
You must be signed in to change notification settings - Fork 101
Custom Tiles
A custom tile is a UI widget you can display to the user outside of your application's normal UI. When you tell the system to issue a custom tile, it will appear as an icon within the status bar panel. The status bar panel is system-controlled areas that the user can view at any time.
Figure 1. A custom tile within the status bar panel
You specify the UI information and actions for a custom tile in a CustomTile.Builder object. To create the custom tile itself, you call CustomTile.Builder.build(), which returns a CustomTile object containing your specifications. To issue the custom tile, you pass the CustomTile object to the system by calling [CMStatusBarManager.publishTile()](https://cyanogenmod.github.io/cm_platform_sdk/reference/cyanogenmod/app/CMStatusBarManager.html#publishTile(java.lang.String, int, cyanogenmod.app.CustomTile)).
A CustomTile object must contain the following:
- An identifying icon, set by setIcon()
- A label, set by setLabel()
- Description text, set by setContentDescription()
To use these Custom Tile API, your application must first declare the publish custom tile permission in AndroidManifest.xml:
<uses-permission android:name="cyanogenmod.permission.PUBLISH_CUSTOM_TILE" />
The following snippet illustrates a simple custom tile that specifies an intent to be broadcasted when the user clicks the tile.
From our main activity we can generate a custom tile and publish it.
// Define an intent that has an action of toggling a state
Intent intent = new Intent();
intent.setAction(ACTION_TOGGLE_STATE);
// initialize this state to off
intent.putExtra(MainActivity.STATE, States.STATE_OFF);
// Retrieve a pending intent from the system to be fired when the
// clicks the custom tile
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
intent , PendingIntent.FLAG_UPDATE_CURRENT);
// Instantiate a builder object
CustomTile customTile = new CustomTile.Builder(this)
.setOnClickIntent(pendingIntent) // set the pending intent
.setContentDescription("Generic content description")
.setLabel("CustomTile " + States.STATE_OFF) // display current state
.shouldCollapsePanel(false)
.setIcon(R.drawable.ic_launcher)
.build(); // build
//Publish our tile to the status bar panel with CUSTOM_TILE_ID defined elsewhere
CMStatusBarManager.getInstance(this)
.publishTile(CUSTOM_TILE_ID, customTile);
Then we define our receiver for the broadcast to receive the action and toggle the state of the tile, publishing updates as needed.
public class TileReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (MainActivity.ACTION_TOGGLE_STATE.equals(intent.getAction())) {
Intent newIntent = new Intent();
newIntent.setAction(MainActivity.ACTION_TOGGLE_STATE);
String label = "CustomTile " + States.STATE_OFF;
int state = getCurrentState(intent);
switch (state) {
case States.STATE_OFF:
newIntent.putExtra(MainActivity.STATE, States.STATE_ON);
label = "CustomTile " + States.STATE_ON;
break;
case States.STATE_ON:
newIntent.putExtra(MainActivity.STATE, States.STATE_OFF);
label = "CustomTile " + States.STATE_OFF;
break;
}
PendingIntent pendingIntent =
PendingIntent.getBroadcast(context, 0,
newIntent , PendingIntent.FLAG_UPDATE_CURRENT);
CustomTile customTile = new CustomTile.Builder(context)
.setOnClickIntent(pendingIntent)
.setContentDescription("Generic content description")
.shouldCollapsePanel(false)
.setLabel(label)
.setIcon(R.drawable.ic_launcher)
.build();
CMStatusBarManager.getInstance(context)
.publishTile(MainActivity.CUSTOM_TILE_ID, customTile);
}
}
private int getCurrentState(Intent intent) {
return intent.getIntExtra(MainActivity.STATE, 0);
}
}
The effect you get then is a tile that toggles between states!
The below snippet utilizes the new RemoteExpandedStyle to publish a tile containing a RemoteViews which receives a layout defined by the developer.
// Create a remoteviews object
RemoteViews contentView = new RemoteViews(getPackageName(),
R.layout.remote_view);
// Create intent for the onclick button
Intent cyngnIntent = new Intent(Intent.ACTION_VIEW)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.setData(Uri.parse("http://www.cyngn.com"));
// Get a pending intent for the defined intent
PendingIntent intent = PendingIntent.getActivity(this, 0,
cyngnIntent, 0);
// Set the pending intent on the button in our layout
contentView.setOnClickPendingIntent(R.id.whats_hot_click, intent);
// Create the new RemoteExpandedStyle
CustomTile.RemoteExpandedStyle remoteExpandedStyle =
new CustomTile.RemoteExpandedStyle();
remoteExpandedStyle.setRemoteViews(contentView);
// Build the custom tile
CustomTile customTile = new CustomTile.Builder(CMStatusBarTest.this)
.setLabel("Remote Style From SDK")
.setIcon(R.drawable.ic_launcher)
.setExpandedStyle(remoteExpandedStyle)
.setOnSettingsClickIntent(new Intent(thiis, DummyClass.class)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK))
.setContentDescription("Description of content for expanded style")
.build();
// Publish the custom tile
CMStatusBarManager.getInstance(this)
.publishTile(CUSTOM_TILE_ID, customTile);
You end up with a remoteviews with a custom button that launches an external site!
For further details about the capabilities for the CustomTile API, see the javadoc for it.