安卓源码里有谷歌给的关于 Tile 的说明。
frameworks/base/packages/SystemUI/docs/qs-tiles.md
SystemUI QuickSettings 简称QS,指的是 下拉菜单里的区域。区域里的一个选项就是一个 Tile 。
下图是 frameworks/base/packages/SystemUI/docs/ 里的附图示例,
SystemUI 会加载自己的Tile ,也会加载第三方应用的 Tile 。
SystemUI 里有配置,会默认加载一些Tile到QS面板 ,如 wifi 、蓝牙的Tile 。未配置的Tile不会显示的QS面板里,但备选区域里有,用户点击 编辑 按钮,可以通过拖拽的方式添加、删除Tile。
SystemUI QuickSettings 的加载流程先按住不表。
先试试作为第三方应用,如何实现添加Tile到SystemUI。
1.创建Service继承TileService
package com.test.luodemo.tileservice;import android.content.Intent;
import android.service.quicksettings.TileService;
import android.util.Log;public class ClickTileService extends TileService {public static final String TAG = ClickTileService.class.getSimpleName();public ClickTileService() {}@Overridepublic void onTileAdded() {super.onTileAdded();Log.d(TAG,"onTileAdded");}@Overridepublic void onTileRemoved() {super.onTileRemoved();Log.d(TAG,"onTileRemoved");}@Overridepublic void onStartListening() {super.onStartListening();Log.d(TAG,"onStartListening");}@Overridepublic void onStopListening() {super.onStopListening();Log.d(TAG,"onStopListening");}@Overridepublic void onClick() {super.onClick();Log.d(TAG,"onClick");}@Overridepublic void onDestroy() {super.onDestroy();Log.d(TAG,"onDestroy");}
}
示例创建了 ClickTileService ,继承 android.service.quicksettings.TileService ,重写 TileService 的方法。
onTileAdded
: Tile 被添加到 QS 面板时的回调。onTileRemoved
: Tile 从 QS 面板移除时的回调。onStartListening
: called when QS is opened and the tile is showing. This marks the start of the window when callinggetQSTile
is safe and will provide the correct object.onStopListening
: called when QS is closed or the tile is no longer visible by the user. This marks the end of the window described inonStartListening
.onClick
: 点击事件。
观察原生的选项,点击事件主要有两种:
- 做切换功能,作用是打开、关闭某个功能,如打开关闭wifi。
- 做跳转功能,如点击打开应用的某个页面。
点击做切换功能
@Overridepublic void onClick() {super.onClick();Log.d(TAG,"onClick");Tile tile = getQsTile();int curState = tile.getState();if (curState == Tile.STATE_ACTIVE) {tile.setState(Tile.STATE_INACTIVE);tile.setStateDescription("StateDescriptionOff");tile.setSubtitle("SubtitleOff");tile.updateTile();} else if (curState == Tile.STATE_INACTIVE) {tile.setState(Tile.STATE_ACTIVE);tile.setStateDescription("StateDescriptionOn");tile.setSubtitle("SubtitleOn");tile.updateTile();}}
通过 getQsTile() 可以获取到 Tile 对象,就可以更新状态、描述。
本例 on/off 对比,
点击做跳转功能
@Overridepublic void onClick() {super.onClick();Log.d(TAG,"onClick");Intent intent = new Intent(ClickTileService.this, TileActivity.class);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//startActivity(intent);//会打开页面,下拉菜单不会收起startActivityAndCollapse(intent);//会打开页面,下拉菜单收起}
跳转功能 ,一看便知。
- startActivity :会打开页面,但是下拉菜单不会自动收起。手动收起下拉菜单后才能看到 TileActivity 。不友好,不推荐。
- startActivityAndCollapse :TileService 里的方法,会打开页面,下拉菜单会自动收起,然后显示 TileActivity 。操作方式友好,推荐。
2.Service注册到AndroidManifest
前面写了 Service ,四大组件之一 ,注册到 AndroidManifest ,无需解释了。
TileService 的源码注释有说明。
A TileService provides the user a tile that can be added to Quick Settings. Quick Settings is a space provided that allows the user to change settings and take quick actions without leaving the context of their current app.
The lifecycle of a TileService is different from some other services in that it may be unbound during parts of its lifecycle. Any of the following lifecycle events can happen independently in a separate binding/ creation of the service.
When a tile is added by the user its TileService will be bound to and onTileAdded() will be called.
When a tile should be up to date and listing will be indicated by onStartListening() and onStopListening().
When the user removes a tile from Quick Settings onTileRemoved() will be called.
onTileAdded() and onTileRemoved() may be called outside of the onCreate() - onDestroy() window
TileService will be detected by tiles that match the "android. service. quicksettings. action. QS_TILE" and require the permission "android. permission. BIND_QUICK_SETTINGS_TILE". The label and icon for the service will be used as the default label and icon for the tile. Here is an example TileService declaration.<serviceandroid:name=".MyQSTileService"android:label="@string/ my_default_tile_label"android:icon="@drawable/ my_default_icon_label"android:permission="android. permission. BIND_QUICK_SETTINGS_TILE"><intent-filter><action android:name="android. service. quicksettings. action. QS_TILE" /></ intent-filter></ service>
照葫芦画瓢,
- icon :自定义图标。
- label :描述。可以通过 tile.setLabel() 修改。
- android:permission=“android.permission.BIND_QUICK_SETTINGS_TILE” :固定写法。
- < action android:name=“android.service.quicksettings.action.QS_TILE” /> :固定写法。
两个固定写法,frameworks/base/packages/SystemUI/docs/qs-tiles.md
里也有说明。
This is an abstract Service that needs to be implemented by the developer. The Service manifest must have the permission
android.permission.BIND_QUICK_SETTINGS_TILE
and must respond to the actionandroid.service.quicksettings.action.QS_TILE
. This will allow SystemUI to find the available tiles and display them to the user.
示例代码,
<serviceandroid:name=".tileservice.SwitchTileService"android:enabled="true"android:exported="true"android:icon="@drawable/icon_info"android:label="MySwitchLabel"android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"><intent-filter><action android:name="android.service.quicksettings.action.QS_TILE" /></intent-filter></service><serviceandroid:name=".tileservice.ClickTileService"android:enabled="true"android:exported="true"android:icon="@drawable/icon_vector_red_star"android:label="MyClickLabel"android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"><intent-filter><action android:name="android.service.quicksettings.action.QS_TILE" /></intent-filter></service>
run ,添加到 QS ,两个 Tile 的效果,