Android 7.1 新特性:快捷方式 Shortcuts 详解

article/2025/8/17 20:22:46

Android 7.1 新特性:快捷方式 Shortcuts 详解

一、Shortcuts 介绍

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


android-7.1-app-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 nameandroid.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-dataandroid: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"><shortcutandroid:enabled="true"android:icon="@drawable/search"android:shortcutId="search"android:shortcutDisabledMessage="@string/disabled"android:shortcutLongLabel="@string/menu_label"android:shortcutShortLabel="@string/launcher_label"><intentandroid: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 添加到了堆栈。
对于先跳转到某个页面,Back 键希望退回主页而不是结束 App 这类场景,多个 Intents 挺实用的。

intent可设置属性包括:
android:action、android:data、android:mimeType、android:targetClass、android: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 一些实践&问题



6. 最佳实践

这块官网已经给出了一部分建议,包括:

  1. 设计上和系统 App 的 Shortcuts 保持一致。
  2. 最多添加 4 个 Shortcuts 以保持在启动器中显示的样式最佳
    目前虽然说是 5 个,但实际最多只能添加 4 个,可见7.2 Shortcut 添加或修改无效中介绍。
  3. 限制 Label 长度
    其中shortcutShortLabel建议不超过 10 个字符,shortcutLongLabel 建议不超过 25 个字符。这块可能有些问题,可见7.1 LongLabel 和 ShortLabel中介绍。
  4. 记录 Shortcut 及其对应操作使用记录。
    这个在5.3 跟踪 Shorcut 使用情况中已经介绍了。
  5. 只在 Shortcut 意义不变的情况下更新,否则新增。
  6. 动态 Shortcuts 在 BackUp 恢复后不可以直接恢复,考虑适时新增或更新已有的 Shortcuts
    除了以上这些外,个人觉得还有几点需要遵守:
  7. 如何更好的删除(废弃)老的 Shortcut
    这里主要考虑到删除老的 Shortcut,可能会影响已经固定的 Shortcut。
    对于静态 Shortcuts,直接删除配置文件中对应的 Shortcut 即可,系统桌面会将已固定的该 Shortcut 置灰,点击会提示 shortcutDisabledMessage。
    对于动态 Shortcuts 建议通过禁用的方式而不是直接删除的方式,因为已经删除的动态 Shortcut 如果被固定了依然是可用的,所以希望该入口不可用最好的方式是禁用。
  8. 始终设置shortcutDisabledMessage
    根据上面的介绍废弃老的 Shortcut 较好的方式是禁用,通过自定义shortcutDisabledMessage去更友好的提示用户。
  9. 动态添加 Shortcut 前需要判断 API 版本不小于 25
    否则在低版本会报 ClassNotFoundException 异常。

7. 一些问题

7.1 LongLabel 和 ShortLabel

LongLabel和ShortLabel的含义,官方 API 文档解释的并不是很清楚。
在 Nexus 6 上测试,当 LongLabel 长度大于 17 个小写字符时,会显示 ShortLabel,而不是 LongLabel。这里的界限长度跟大小写、空格都有关,应该是受限于桌面 Shortcuts 列表 Item 的宽度!

7.2 Shortcut 添加、修改、点击无效

可能原因:

  1. shortcutId 被覆盖
    shortcutId 是唯一标识,相同 shortcutId 会被覆盖。
  2. intent 不对
    intent 必须设置 android:action 属性,同时目标 Activity 必须有效即已在 Manifest 中声明。
  3. 后台 App 有频率限制
    当应该完全退到后台(无 Activity 或 Service 在前台时),其操作 Shortcut(包括添加、删除、修改) 的频率是受限的。可通过isRateLimitingActive()查询是否已受限,true表示已受限。
    若已受限,可通过开发者选项中“重置 ShortcutManager 调用频率限制”或命令行adb shell cmd shortcut reset-throttling [ --user USER-ID ]解决。
  4. Shortcut 个数限制
    虽然官方文档介绍静态和动态 Shortcut 总和不能超过 5 个,通过getMaxShortcutCountPerActivity()得到的也是 5,但实际测试下来是不超过4个!即静态和动态shortcuts加起来总数最多是五个.
    当我们尝试添加第六个shortcut时, 应用会抛出异常:
    java.lang.IllegalArgumentException: Max number of dynamic shortcuts exceeded.
    虽然总数限制是5个, 但是当我正好有5个(2个静态 + 3个动态)的时候, 长按只显示了4个shortcuts.

android-7.1-app-shortcuts数量的限制

7.3 getIntents() 有 Bug

从 getIntents() 实现 中可以看出未做mIntents是否为 null 及 empty 的判断,在 null 时会出现:

java.lang.NullPointerException: Attempt to get length of null array

的异常。

8. 三方桌面支持 Shortcuts——LauncherApps

如果三方桌面希望支持这个特性,请参考 LauncherApps API 介绍,不过只有系统默认桌面才有权限得到其他 App Shortcuts 信息。

可通过hasShortcutHostPermission()查看是否拥有权限,如果没有权限,会报如下异常:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.xx/com.xx.XXActivity}: 
java.lang.SecurityException: Caller can't access shortcut informationat android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2665)at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)

通过getShortcuts API 获取到所有 Shortcuts 信息。

参考:
App Shortcuts的官方文档: App Shortcuts
Exploring Android Nougat 7.1 App Shortcuts


http://chatgpt.dhexx.cn/article/IBHadmAm.shtml

相关文章

Android7.1新特性:快捷方式Shortcuts详解

Shortcuts介绍 Android7.1&#xff08;API Level 25&#xff09;及以上系统可以自定义Shortcuts&#xff0c;通过在桌面上长按App Icon弹出Shortcut列表&#xff0c;点击某个shortcut可使用户快捷得打开App里常用的或推荐的任务。长按列表中的任一个Shortcut可拖动到桌面进行固…

oracle 左连接

oracle左连接小结 当使用左连接关联表进行查询时&#xff0c;如果右侧的表在关联的条件中有重复的数据&#xff0c;就会导致最后的查询结果比预期的多&#xff0c;比如&#xff1a; select * from A 需要关联的表 select * from B 这里的两个表的id都是主键&#xff0c;现在…

lambda多表左连接

下面是mysql多表左连接&#xff0c;对应的lambda表达式写法&#xff0c;只为快速解决你的问题&#xff0c;详细的就不介绍了&#xff0c;只出结果&#xff0c;相信稍微有点基础的都能看懂。相关知识点&#xff0c;请自行百度 关键字&#xff1a;GroupJoin、SelectMany sql语句…

实例讲解内连接、左连接、右连接、交叉连接、外连接以及全连接

目录 示例表&#xff1a;1.内连接-inner&#xff1a;实例1&#xff1a;内连接表a和表b实例2&#xff1a;内连接表a和表c实例3&#xff1a;内连接表a和表b,使用“>”号实例4&#xff1a;内连接表a和表b,使用“<”号实例5&#xff1a;内连接表a和表b,指定字段显示实例6&…

mysql 左连接查询记录数,MySQL左连接查询记录行数

最近修复一个数据问题&#xff0c;其中用到了左连接&#xff0c;我的意识里还以为A左连接B&#xff0c;查询出的记录数量会是A的记录数&#xff0c;然而实际操作后发现认知严重错。 网上关于左连接的一张图 摘自网上的一张图&#xff0c;图确实没毛病&#xff0c;但我却产生了误…

mysql左连接出现笛卡尔积_Mysql内连接、左连接会出现笛卡尔积的理解

先简单解释一下笛卡尔积。 现在,我们有两个集合A和B。 A = {0,1} B = {2,3,4} 集合 AB 和 BA的结果集就可以分别表示为以下这种形式: AB = {(0,2),(1,2),(0,3),(1,3),(0,4),(1,4)}; BA = {(2,0),(2,1),(3,0),(3,1),(4,0),(4,1)}; 以上AB和BA的结…

关于左右连接

首先来看一下两张主要的表&#xff1a; persons表 orders表 现在我们希望列出所有的人&#xff0c;以及他们的定购。 SELECTpersons.last_name,persons.first_name,orders.order_no FROMpersons LEFT JOIN orders ON persons.pid orders.pid ORDER BYpersons.last_nam…

LINQ左连接

title: linq左连接 date: 2021-12-05 08:45:48 tags: C# Linq LINQ语言继承查询 近日项目实践中遇到这样的一个事情。在一个项目需求里存在这么一个情况&#xff0c;有以下一个主表与几个基础数据表组成一个大表&#xff0c;要求主表中的有的数据必须展示出来&#xff0c;但大…

ClickHouse左连接

A左连接B>S1区域 1、等价方式一 SELECT date, ts, country, province, city,ye_no FROM (SELECT date, ts, country, province, city,0 AS yes_no FROM DBa.tba WHERE (date today()-1) ) ALL LEFT JOIN (SELECT date, ts, country, province, city FROM DBb.tbb WH…

【Mysql】图解左、右、内与全连接

一、前言 使用学生表与成绩表来演示Mysql中的各种连接查找 学生表的建表语句如下&#xff1a; CREATE TABLE student(id int(11) NOT NULL AUTO_INCREMENT COMMENT 自增序号,st_id int(11) DEFAULT NULL COMMENT 学生id,st_name varchar(255) DEFAULT NULL COMMENT 学生姓名…

使用VC和MATCOM结合开发应用程序心得笔记

使用VC和MATCOM结合开发应用程序心得笔记1. 什么是Matcom?Matcom是MathTools公司(UPenn)开发的一个基于C矩阵函数库Matrix的一个matlab m文件与cpp文件的转换程序。MIDEVA为他的一个集成调试编译环境(界面)。Matcom独立于matlab之外&#xff0c;但需要外部的c编译器&…

MATLAB与VC混合编程(1)

在本节中先介绍matcom&#xff0c;使得VC能调用Matlab 的M文件&#xff0c;从而实现混合编程。 Matcom是mathTools公司推出的一个能将M文件转化成相同功能C代码的工具。相比Matlab自带的编译器Compiler&#xff0c;用Matcom转化代码要简单和方便得多。以VC6.0和Matcom为例&…

利用Matcom实现基于MATLAB的混合编程

利用Matcom实现基于MATLAB的混合编程 来源: 神经网络 作者&#xff1a;AI俱乐部 网友评论 0 条 浏览次数 42 <script> remark_look(re_look.php?cid17&tid1843); </script> Matcom是mathTools公司推出的最早的Matlab到C的编译器。后来&#xff0c;由于Mathto…

深度学习(十二):Matconvnet小试牛刀与提特征

该节简单介绍一下如何使用Matconvnet的现有的模型进行图像分类实验以及提取图像对应层的特征。 先来看看如何用训练好的imagenet网络模型进行图像的预测&#xff0c;英文版的官网教程就在这里&#xff1a; http://www.vlfeat.org/matconvnet/quick/ 检测图像分类之前&#x…

项目总结四:神经风格迁移项目(Art generation with Neural Style Transfer)

1、项目介绍 神经风格转换 (NST) 是深部学习中最有趣的技术之一。它合并两个图像, 即 内容图像 C&#xff08;content image&#xff09; 和 样式图像S&#xff08;style image&#xff09;, 以生成图像 G&#xff08;generated image&#xff09;。生成的图像 G 将图像 C 的 内…

Matconvnet学习笔记

Introduction to Matconvnet MatConvNet是实现用于计算机视觉领域的卷积神经网络(CNN)的MATLAB工具箱。自从取得突破性工作以来,CNN在计算机视觉领域有一个重大影响&#xff0c;特别是图像理解&#xff0c;基本上取代了传统图像表示。有许多其他机器学习、深度学习和CNN开源库的…

20190812_解决anaconda下install库的问题

20190812_解决anaconda下install库的问题 一、起因二、开始解决三、解决方法1 创建虚拟环境2 在环境中安装库3 重新配置pycharm中的解释器4 运行5 其他 一、起因 在学习PYQT5例子时&#xff0c;需要在anaconda下使用plotly库 二、开始解决 使用&#xff1a; conda install …

matlab已停止工作 win7 64,win7系统笔记本运行软件弹出“Matlab已停止工作”的解决方法...

很多小伙伴都遇到过win7系统笔记本运行软件弹出“Matlab已停止工作”的困惑吧&#xff0c;一些朋友看过网上零散的win7系统笔记本运行软件弹出“Matlab已停止工作”的处理方法&#xff0c;并没有完完全全明白win7系统笔记本运行软件弹出“Matlab已停止工作”是如何解决的&#…

Map遍历方法及效率

在大学的时候记得学过通过迭代器进行Map的遍历&#xff0c;但是从参加工作后&#xff0c;基本都是通过for循环遍历&#xff0c;没用过迭代器&#xff0c;于是去了解了Map的几种遍历方法并通过运行测试各自的速度。 注意&#xff1a;这里只讲通过遍历同时能过获取key和value的遍…

java map集合如何遍历效率高 java中Map遍历的方式

java map集合如何遍历效率高 java中Map遍历的方式 一、前言 1、在看 《阿里巴巴java开发手册》时候&#xff0c;有一条推荐的规约&#xff1a; 【推荐】使用entrySet遍历Map类集合KV&#xff0c;而不是keySet方式进行遍历。 说明&#xff1a;keySet其实是遍历了2次&#xff0c…