11/09
2016

Android 7.1 新特性之 Shortcuts 介绍

Android 7.1 允许 App 自定义 Shortcuts,类似 iOS 的 3D touch。通过在桌面长按 App 弹出 Shortcut 列表,点击某个 Shortcut 快速进入某项操作,同时 Shortcut 可以拖动到桌面进行固定,如下图系统日历 App:

由于 7.1 SDK 的 Sources 尚未开放,目前大部分内容还是根据官方 API 文档而来,还有些细节还得等 Sources 开放。

 

Shortcuts 全面介绍分为三篇:
第一篇:Android 7.1 新特性之 Shortcuts 介绍
第二篇:Android 7.1 新特性之 Shortcuts 一些实践和目前的问题
第三篇:三方桌面支持 Android SDK 7.1 新特性 Shortcuts
本文为第一篇,如果对 Shortcuts 已经有所了解可直接看本篇的第五部分和上面第二篇。

 

1. Shortcuts 作用及分类

Shortcuts 为 App 常用操作提供了快速访问的方式,如上面日历的新建提醒。

 

这个功能目前只能在 Android 7.1 系统桌面进行使用,这个依然保留着“应用抽屉”古老设计的产品国内应该没多少用户。三方桌面可以通过 API 接入这个功能。
目前支持 Shortcut 的应用主要还是 Google 的 App,看到有即刻的朋友说他们在 7.1 系统发布时快速支持了这个功能并上线,速度很赞。

 

类似 BroadcastReceiver 可通过静态和动态方式注册,Shortcuts 也可以通过静态和动态方式添加。

 

2. 静态 Shortcuts(Static Shortcuts)

静态 ShortcutsStatic Shortcuts通过在 Manifest 中声明添加。缺点是不可以修改,只能通过应用升级来添加新的静态 Shortcuts。添加主要分为两步:

2.1 AndroidManifest.xml 的 Main Launcher 对应的 Activity 内添加 meta-data

meta-data name 为android.app.shortcuts,如下:

<application
    ……>
    <activity android:name=".main.MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>

            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>

        <meta-data
            android:name="android.app.shortcuts"
            android:resource="@xml/shortcuts"/>
    </activity>
</application>

必须在 Main Launcher 对应的 Activity 内设置,其中android:resource指向定义了 shortcuts 的资源文件。

 

2.2 资源文件中定义具体的 shortcuts

res 目录下新建 xml 文件夹,并新建 shortcuts.xml 文件,内容如下:

<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
    <shortcut
        android:enabled="true"
        android:icon="@drawable/search"
        android:shortcutId="search"
        android:shortcutDisabledMessage="@string/disabled"
        android:shortcutLongLabel="@string/menu_label"
        android:shortcutShortLabel="@string/launcher_label">
        <intent
            android:action="android.intent.action.VIEW"
            android:targetClass="cn.trinea.android.demo.SearchActivity"
            android:targetPackage="cn.trinea.android.demo"/>
        <intent
            ……/>
    </shortcut>
    ……
</shortcuts>

shortcuts元素为根,可以包含多个shortcut元素,每个shortcut元素表示一个 shortcut。其中属性分别表示:
(1) shortcutId表示 shortcut 唯一标识符,相同的 shortcutId 会被覆盖。必须字段。
(2) shortcutShortLabel为将 shortcut 拖动到桌面时显示的名字,官方建议不超过 10 个字符,必须字段。
(3) shortcutLongLabel为 shortcut 列表中每个 shortcut 的名字,不宜过长,如果过长或未设置默认会显示 ShortLabel,官方建议不超过 25 个字符。可选字段。
(4) icon为 shortcut 的 icon,在列表展示和拖动到桌面时显示需要,可选字段。
(5) enabled表示 shortcut 是否可用,false 表示禁用。xml 中这个属性几乎没有被设置为 false 的实际场景,具体原因可见6.7 如何更好的删除(废弃)老的 Shortcut中介绍。
(6) shortcutDisabledMessage为已固定在桌面的 shortcut 被 Disabled 后点击时的 Toast 提示内容。可选字段。
(7) intent为点击 shortcut 时响应的 intent,必须字段。
这里可以添加多个 intent,但点击时不会启动所有 intent,而是启动最后一个 intent,在这个 intent 回退时会启动它前面一个 intent,相当于自动将所有 intent 添加到了堆栈。

 

intent可设置属性包括:
android:actionandroid:dataandroid:mimeTypeandroid:targetClassandroid:targetPackage,其中android:action为必须属性。

 

3. 动态 Shortcuts(Dynamic Shortcuts)

动态 ShortcutsDynamic Shortcuts 通过 ShortcutManager API 进行操作。可以动态添加、修改、删除。

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) {
    return;
}

ShortcutManager shortcutManager = getSystemService(ShortcutManager.class);
ShortcutInfo shortcut = new ShortcutInfo.Builder(this, "id1")
    .setShortLabel("trinea.cn")
    .setLongLabel("Open trinea.cn")
    .setDisabledMessage("Disabled")
    .setIcon(Icon.createWithResource(context, R.drawable.trinea_cn))
    .setIntent(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.trinea.cn/")))
    .build();
shortcutManager.setDynamicShortcuts(Arrays.asList(shortcut));

通过ShortcutInfo.Builder新建 ShortcutInfo,再通过shortcutManager添加即可。其他:
(1) setDynamicShortcuts(List)可以替换并添加所有 shortcut 列表;
(2) addDynamicShortcuts(List)可以添加新的 shortcut 到列表,超过最大个数会报异常;
(3) updateShortcuts(List)可以更新一组 shortcuts;
(4) removeDynamicShortcuts(List)removeAllDynamicShortcuts() 可以删除部分或所有 shortcuts。

 

ShortcutInfo的属性与 xml 中定义字段含义一致,shortcutId shortcutShortLabel intent 是必须设置的字段,并且intent必须设置Action

 

4. 固定的 Shortcuts(Pinned Shortcuts)

指通过拖动固定到桌面的 Shortcuts,App 不可以添加、修改、删除这些 Shortcuts,只能禁用他们。即便 App 内删除了某个 Shorcut,对应的已固定到桌面的 Shortcuts 也不会被删除。

 

可以通过:
(1) getPinnedShortcuts()得到所有固定的 Shortcuts 的信息。
(2) disableShortcuts(List)disableShortcuts(List, CharSequence)禁用动态的 Shortcuts。

 

对于静态的 Shortcuts 需要在资源文件中设置android:enabled="false"进行禁用,不过没有必要,静态 Shortcuts 可直接通过删除达到禁用的效果,具体原因可见6.7 如何更好的删除(废弃)老的 Shortcut中介绍。

 

静态 Shortcuts 和动态 Shortcuts 是有最大个数限制的,默认为 5,超过最大个数后添加会报异常。而固定的 Shortcuts 并没有个数限制,并且固定的 Shortcut 对应的 Shortcut 即便被动态删除了,依然可以通过 id 进行 Update 操作。

 

5. 其他

5.1 动态 Shortcuts 与静态 Shortcuts 区别

(1) 静态 Shortcuts 只能通过升级应用修改,动态 Shortcuts 随时可以修改;

 

(2) 静态 Shortcuts 的 Intent 无法设置 Flag,默认为FLAG_ACTIVITY_NEW_TASKFLAG_ACTIVITY_CLEAR_TASK Flag,即若应用运行中会清除所有已存在的 Activity。动态 Shortcuts 的 Intent 可以设置 Flag;

 

(3) 静态 Shortcuts 的rank系统默认根据声明顺序设置,动态 Shortcuts 的rank可以通过setRank(int rank)接口主动设置,rank 不能小于 0,值越大表示在 shortcut 列表展示时离 App Icon 越远。静态 Shortcuts 默认比动态 Shortcuts 离 App Icon 更近。

 

(4) 静态 Shortcuts 删除可以直接删除,动态 Shortcuts 建议通过禁用删除;

 

5.2 动态 Shortcuts 操作的频率问题

当应该完全退到后台(无 Activity 或 Service 在前台时),其操作 Shortcut(包括添加、删除、修改) 的频率是受限的。可通过isRateLimitingActive()查询是否已受限,true表示已受限。

 

5.3 跟踪 Shorcut 使用情况

在 Shortcut 被选择或者其关联的操作被操作时需调用reportShortcutUsed(String shortcutId)接口上报数据,为了方便启动器收集应用 Shortcuts 使用情况,以便未来进行预测或者向开发者展示哪些操作适合作为 Shortcuts 以及其优先级。

 

PS:这个接口其实挺尴尬的,一方面需要 App 主动上报,侵入性太强。另一方面这个预测功能未来也不好加到 Shortcuts 推荐里,更多是个开发工具相关功能。
最好是由启动器自己纯粹收集 Shortcut 被选择的使用情况数据,而不需要统计 Shortcut 被关联操作通过其他方式调用的使用情况数据。至于哪些操作适合作为 Shortcuts,开发者大可通过其他监控 SDK 去判断。

 

5.4 应用备份

如果应用通过备份恢复到另外一台机器上,固定的 Shortcuts 是可以直接恢复的,不过启动器不保存这些 Shortcut 的 icon,所以应用内需要存在这些 icon 对应的资源以便启动器能找到。

 

静态 Shortcuts 需要应用重新安装、升级才能生效。
动态 Shortcuts 需要相应代码被执行过才能生效。

 

更多关于 Shortcuts 比较好的实践、使用过程中可能的问题、Launcher 如何支持可见:Android 7.1 新特性之 Shortcuts 一些实践和问题

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

2 thoughts on “Android 7.1 新特性之 Shortcuts 介绍