查看原文
其他

掌握Android 7.0 新增特性 Quick Settings

2017-08-23 强波 承香墨影


作者简介

本文由 强波 原创并授权发布,未经原作者允许请勿转载。

本文介绍 Quick Settings ,方便你在 Quick Settings 里定制你 App 的专属 Setting,写的很好,希望你喜欢。

强波 的博客地址:

http://qiangbo.space/2017-08-01/AndroidAnatomy_QuickSettings



本文中,我们详细了解一下 Android N(7.0)上的新增特性:Quick Settings。

Quick Settings 功能如下图所示:

该功能位于下拉的通知面板中,在用户单手指下拉通知面板的时候,Quick Settings 区域显示成一个长条,用户可以点击右上角的尖号展开这个区域。

Quick Settings 提供给用户非常便捷的按钮,用户甚至无需解锁就可以操作这个区域,通过点击 Quick Settings 中的 Tile 来切换某个功能的状态,例如:打开/关闭手电筒,蓝牙,Wifi 等功能。这对于用户来说是非常便捷的。

开发者API

使用 Quick Settings 功能非常的简单,只需要与 Tile 和 TileService 两个类打交道即可。它们的类图如下图所示:

TileService 是 android.app.Service 的子类,开发者通过继承 TileService 并覆写其对应的方法来完成功能的实现。TileService 中提供的状态回调方法如下:


在这些状态变更的时候,开发者可以根据状态的不同来调整 Tile 的状态。调整的方法就是:先通过 TileService.getQsTile() 获取到当前 Tile ,然后通过 Tile 的 setXxx 方法来修改。最后调用 Tile.updateTile() 来使刚刚的设置生效。

下面是一段代码示例。这段代码的功能是根据用户点击来将 Tile 在 Active 和非 Active 状态之间进行切换。

这段代码说明如下:

  1. 处理用户的点击事件

  2. 获取自身的Tile对象

  3. 设置 Tile 的状态,包括:Label,Icon,State

  4. 设置完成之后真正让状态生效


在实现完成这个 TileService 之后,我们还需要将其注册到 AndroidManifest.xml 中。TileService 需要设置一个特殊的权限和 Intent-Filter 的 Action ,如下所示:

当我们将包含这个 TileService 的应用安装到设备上之后,下划通知面板然后展开 Quick Settings 区域便可以看到我们开发的 Tile 了。

系统实现

我们可以通过 Layout Inspector 来分析 Quick Settings 的结构。

Quick Settings 位于下拉的通知面板中。在布局上,这个部分通过 QSContainer 作为外部的容器,其中包含了一个 QSPanel

QSPanel 中,包含了一个调节屏幕亮度的控件,这是通过一个 LinearLayout 来进行布局的,接下来就是PagedTileLayout 中包含的多个 Tile 了,每个 Tile 用一个 QSTileView 来进行布局。 PagedTileLayout 正如其名称所示,这是一个可以分页的 Layout 。

QSContainer 中包含的元素如下图所示:

在 Android 系统中,包含两类 Tile :

  • 一类是系统预置的

  • 另一类的第三方应用中包含的


Quick Settings 功能实现主要位于这个目录中: /frameworks/base/packages/SystemUI/src/com/android/systemui/qs。

系统预置Tile

qs 目录下,包含了布局结构中用到的几个元素的实现类,包括:QSContainer,QSPanel,PagedTileLayout,QSTileView,QSIconView 等。

系统本身包含了一些预装的 Tile ,例如:飞行模式的开关,位置信息的开关,热点功能的开关,手电筒功能开关等等。这些Tile的实现位于 qs/tiles 目录下,包含下面这些:

  • AirplaneModeTile.java

  • BatteryTile.java

  • BluetoothTile.java

  • CastTile.java

  • CellularTile.java

  • ColorInversionTile.java

  • DataSaverTile.java

  • DndTile.java

  • FlashlightTile.java

  • HotspotTile.java

  • IntentTile.java

  • LocationTile.java

  • NightDisplayTile.java

  • RotationLockTile.java

  • UserTile.java

  • WifiTile.java

  • WorkModeTile.java


在 res 目录下,有一个名称为 quick_settings_tiles_stock 的字符串列出了所有系统内置的 Quick Setting 的名称,它们通过逗号进行分隔。

<string name="quick_settings_tiles_stock" translatable="false"> wifi,cell,battery,dnd,flashlight,rotation,bt,airplane,location,hotspot,inversion,saver,work,cast,night </string>

QSTileHost 中为这里的名称和实现类做了映射:


TileQueryHelper 负责了 Tile 的初始化工作。在这个类中,会读取 R.string.quick_settings_tiles_stock 中的值,然后根据配置来初始化系统内置的 Quick Setting :

这段代码应该很简单,这里就不多做说明了。

第三方应用中包含的 Tile

对于 SystemUI 来说,除了要列出系统内置的 Quick Setting 之外,还有开发者开发的 Quick Setting 也需要读取。这部分逻辑通过 QueryTilesTask 以一个异步的Task来完成,这在这个异步任务中,会通过 PackageManager 查询所有开发者开发的 Quick Setting。

这段代码说明如下:

  1. 通过 PackageManager 查询所有设置了 TileService.ACTION_QS_TILE 的组件。 PackageManager 负责了所有应用包信息的管理。

  2. 遍历查询到的所有组件

  3. 跳过系统预置的 Tile

  4. 为每个Tile读取标签和图标


相关资料:

  • Android N Quick Settings:

    https://codelabs.developers.google.com/codelabs/android-n-quick-settings/index.html

  • Android 7.0 开发者版本:

    https://developer.android.com/about/versions/nougat/android-7.0.html

  • android.service.quicksettings:

    https://developer.android.com/reference/android/service/quicksettings/package-summary.html


推荐阅读:



您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存