咱们一般能够在告诉栏上看到“飞行形式”、“移动数据”、“屏幕录制”等开关按钮,这些按钮都属于告诉栏上的方便开关,点击方便开关能够容易调用某种体系才干或翻开某个应用程序的特定页面。那是否能够在告诉栏上自界说一个方便开关呢?答案是能够的,具体是经过TileService的方案完成。
TileService承继自Service,所以它也是Android的四大组件之一,不过它是一个特别的组件,开发者不需要手动敞开调用,体系能够自动识别并完结调用,体系会经过绑定服务(bindService)的方式调用。
创立使用:
方便开关是Android 7(target 24)的新才干,因而在使用该才干前有必要先判别版别巨细(大于等于target 24)。
1、自界说一个TileService类。
class MyQSTileService: TileService() {
overridefunonTileAdded(){
super.onTileAdded()
}
overridefunonStartListening(){
super.onStartListening()
}
overridefunonStopListening(){
super.onStopListening()
}
overridefunonClick(){
super.onClick()
}
overridefunonTileRemoved(){
super.onTileRemoved()
}
}
TileService是经过绑定服务(bindService)的方式被调用的,因而,绑定服务生命周期包含的四种典型的回调办法(onCreate()、onBind()、onUnbind()和 onDestroy())都会被调用。但是,TileService也包含了以下特别的生命周期回调办法:
- onTileAdded():当用户从修改栏添加方便开关到告诉栏的快速设置中会调用。
- onTileRemoved():当用户从告诉栏的快速设置移除方便开关时调用。
- onClick():当用户点击方便开关时调用。
- onStartListening():当用户翻开告诉栏的快速设置时调用。当方便开关并没有从修改栏拖到设置栏中不会调用。在TileAdded添加之后会调用一次。
- onStopListening():当用户翻开告诉栏的快速设置时调用。当方便开关并没有从修改栏拖到设置栏中不会调用。在TileRemoved移除之前会调用一次。
2、在应用程序的清单文件中声明TileService
。
<service
android:name=".MyQSTileService"
android:label="@string/my_default_tile_label"
android:icon="@drawable/my_default_icon_label"
android:exported="true"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
</service>
- name:自界说的
TileService
的类名。 - label:方便开关在告诉栏上显示的称号。
- icon:方便开关在告诉栏上显示的图标。
- exported:该服务能否被外部应用调用。该属性有必要为true。假如为false,那么方便开关的功能将失效,原因是exported=”false”时,
TileService
将不支持外部应用调起,手机体系天然不能再和该方便开关交互。有必要装备。 - permission:需要给service装备的权限,BIND_QUICK_SETTINGS_TILE即允许应用程序绑定到第三方快速设置。有必要装备。
- intent-filter:意图过滤器,只要匹配内部的action,才干调起该service。有必要装备。
监听形式
TileService的监听形式(或理解为发动形式)有两种,一种是自动形式,另一种是规范形式。
- 自动形式
在自动形式下,TileService被恳求时该服务会被绑定,并且TileService的onStartListening也会被调用。该形式需要在AndroidManifeast清单文件中声明:
<service ...>
<meta-data android:name="android.service.quicksettings.ACTIVE_TILE"
android:value="true" />
...
</service>
经过TileService.requestListeningState()这一静态办法,就能够完成对TileService的恳求,示例如下:
TileService.requestListeningState(
applicationContext, ComponentName(
BuildConfig.APPLICATION_ID,
MyQSTileService::class.java.name
)
)
自动形式下值得注意的是:
- 用户在告诉栏快速设置的当地点击方便开关时,TileService会自动完结绑定、TileService的onStartListening会被调用。
- TileService无论是经过点击被绑定还是经过requestListeningState恳求被绑定,TileService地点的进程都会被调起。
规范形式
在规范形式下,TileService可见时(即用户下拉告诉栏看见方便开关)该服务会被绑定,并且TileService的onStartListening也会被调用。规范形式不需要在AndroidManifeast清单文件中进行额外的声明,默许便是规范形式。
规范形式下值得注意的是:
- 和自动形式相同,TileService被绑定时,TileService地点的进程就会被调起。
- 而和自动形式不同的是,规范形式绑定TileService是经过用户下拉告诉栏完成的,这意味着TileService地点的进程会被屡次调起。因而为了防止主进程被频繁调起、防止DAU等数据计算受到影响,咱们还需要为TileService指定一个特定的子进程,在Androidmanifest清单文件中设置:
<service
......
android:process="自界说子进程的称号">
......
</service>
更新方便开关
假如需要对方便开关的数据进行更新,能够经过getQsTile()获取方便开关的对象,然后经过setIcon(更新icon)、setLable(更新称号)、setState(更新状况,包含STATE_ACTIVE——表明敞开或启用状况、STATE_INACTIVE——表明封闭或暂停状况、STATE_UNAVAILABLE:表明暂时不可用状况,在此状况下,用户无法与您的磁贴交互)等办法设置方便开关新的数据,最后调用updateTile()办法完成。
override fun onStartListening() {
super.onStartListening()
if (qsTile.state === Tile.STATE_ACTIVE) {
qsTile.label = "inactive"
qsTile.icon = Icon.createWithResource(context, R.drawable.inactive)
qsTile.state = Tile.STATE_INACTIVE
} else {
qsTile.label = "active"
qsTile.icon = Icon.createWithResource(context, R.drawable.active)
qsTile.state = Tile.STATE_ACTIVE
}
qsTile.updateTile()
}
操作方便开关
- 假如想要完成点击方便开关时、封闭告诉栏并跳转到某个页面,能够调用以下办法:
startActivityAndCollapse(Intent intent)
- 假如想要在点击方便开关时弹出对话框进行交互,能够调用以下办法:
override fun onClick() {
super.onClick()
if(!isLocked()) {
showDialog()
}
}
由于方便开关有可能在用户锁屏时呈现,所以有必要加上isLocked()的判别。只要非锁屏的情况下,对话框才会呈现。
- 假如方便开关含有敏感信息,需要使用isSecure()进行设备安全性判别,当设备安全时,才干履行方便开关相关的逻辑(如点击的逻辑)。当设备不安全时(手机处于锁屏状况时),可调用unlockAndRun(Runnable runnable),提示用户解锁屏幕并履行自界说的runnable操作。
以上是告诉栏添加方便开关的悉数介绍。欢迎重视公众号度熊君,一起共享沟通。