Android Nougat 7.1(API 25) 新功能:App Shortcuts 快捷方式

是什么?
是将应用程序的常见操作或任务暴露给启动项的一种方法。通过长按应启动图标显示快捷方式。
快捷方式可以拖拽到桌面单独放置,变成单独的桌面快捷方式。
-
静态:在
xml文件中定义 - 动态:由ShortcutManager发布,可根据用户的行为或偏好添加,支持动态更新
静态 Shortcuts##
- 在
AndroidManifest.xml中的main activity上添加<meta-data>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data
android:name="android.app.shortcuts"
android:resource="@xml/shortcuts" />
</activity>
activity需满足两个条件:
-
action是android.intent.action.MAIN -
category是android.intent.category.LAUNCHER - 在
res/xml目录下创建shortcuts.xml文件,里面包含静态的shortcuts
<?xml version="1.0" encoding="utf-8"?>
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
<shortcut
android:enabled="true"
android:icon="@drawable/ic_static_shortcut"
android:shortcutDisabledMessage="@string/static_shortcut_disabled_message"
android:shortcutId="static"
android:shortcutLongLabel="@string/static_shortcut_long_label"
android:shortcutShortLabel="@string/static_shortcut_short_label">
<intent
android:action="android.intent.action.VIEW"
android:targetClass="com.gssn.appshortcutsdemo.StaticShortcutActivity"
android:targetPackage="com.gssn.appshortcutsdemo" />
</shortcut>
</shortcuts>
根标签<shortcuts>,可以包含多个<shortcut>,每一个代表一个静态shortcut:
-
enabled:shortcut是否可用 -
icon:shortcut左侧显示的图标 -
shortcutDisabledMessage:选择不可用的shortcut时给用户的一个提示 -
shortcutId:唯一的id,id相同时只显示第一个 -
shortcutShortLabel:配置短名称,长名称显示不下时显示短名称 -
shortcutLongLabel:配置长名称,launcher优先选择显示 -
intent:确定一个或多个意图,并绑定shortcut-
targetPackage: 指定目标应用的包名 -
targetClass: 要跳转的目标类 -
action: 必须配置,否则崩溃 -
categories: 目前官方只给提供了android.shortcut.conversation
每个<shortcut>可以添加多个<intent>
-
<?xml version="1.0" encoding="utf-8"?>
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
<shortcut
...>
<intent
android:action="android.intent.action.MAIN"
android:targetClass="com.gssn.appshortcutsdemo.MainActivity"
android:targetPackage="com.gssn.appshortcutsdemo" />
<intent
android:action="android.intent.action.VIEW"
android:targetClass="com.gssn.appshortcutsdemo.StaticShortcutActivity"
android:targetPackage="com.gssn.appshortcutsdemo" />
</shortcut>
</shortcuts>
点击快捷方式会创建一个intents栈(MainActivity -> Static ShortcutActivity),当返回时回到MainActivity:

动态 Shortcuts
可以在使用应用的过程中构建,更新,或者删除。
相关方法:ShortcutManager、ShortcutInfo.Builder
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ShortcutManager shortcutmanager = getSystemService(ShortcutManager.class);
ShortcutInfo webShortcut = new ShortcutInfo.Builder(this, "shortcut_web")
.setShortLabel("web")
.setLongLabel("Open baidu.com web site")
.setIcon(Icon.createWithResource(this, R.mipmap.ic_launcher))
.setIntent(new Intent(Intent.ACTION_VIEW, Uri.parse("https://baidu.com")))
.build();
shortcutmanager.setDynamicShortcuts(Collections.singletonList(webShortcut));
}
ShortcutManager
可对动态shortcut完成以下操作:
- 发布(Publish):
setDynamicShortcuts(List)、addDynamicShortcuts(List) - 更新(Update):
updateShortcuts(List) - 删除(Remove):
removeDynamicShortcuts(List)、removeAllDynamicShortcuts()
ShortcutInfo.Builder
方法中第二个参数是shortcut的id,多个shortcut的id相同时,前面的shortcut会被覆盖。
多个Intent构建back stack
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ShortcutManager shortcutmanager = getSystemService(ShortcutManager.class);
ShortcutInfo dynamicShortcut = new ShortcutInfo.Builder(this, "shortcut_dynamic")
.setShortLabel("Dynamic")
.setLongLabel("Open dynamic shortcut")
.setIcon(Icon.createWithResource(this, R.mipmap.ic_launcher))
.setIntents(new Intent[]{
new Intent(Intent.ACTION_MAIN, Uri.EMPTY, this, MainActivity.class)
.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK),
new Intent("TwoActivity.action")
})
.build();
shortcutmanager.setDynamicShortcuts(Arrays.asList(dynamicShortcut));
}
//AndroidManifest.xml
<activity android:name=".TwoActivity">
<intent-filter>
<action android:name="TwoActivity.action" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
和静态一样,最后一个Intent打开TwoActivity页面,前面的构建back stack, 即返回退回到MainActivity。
注意:
Intent必须指定Action,否则抛出异常。
Shortcut 排序
含多个Shortcuts时,默认按照添加顺序排列,通过setRank()可改变排序。
ShortcutInfo webShortcut = new ShortcutInfo.Builder(MainActivity.this, "shortcut_web")
.setRank(1) //参数不能为负数
.build();
ShortcutInfo dynamicShortcut = new ShortcutInfo.Builder(MainActivity.this, "shortcut_dynamic")
.setRank(0)
.build();
shortcutManager.updateShortcuts(Arrays.asList(webShortcut, dynamicShortcut));
只能改变动态shortcuts的排序,且按照xml中先后顺序排列,故:静态的shortcuts离应用图标最近,动态shortcuts在其之上排序,首位级别为0,依次类推。

其他
ShortcutInfo.Builder的setShortLabel(CharSequence)接收一个CharSequence作为参数,这意味着可以添加自定义的span。
ForegroundColorSpan colorSpan = new ForegroundColorSpan(getResources().
getColor(android.R.color.holo_red_dark, getTheme()));
String label = "catinean.com";
SpannableStringBuilder colouredLabel = new SpannableStringBuilder(label);
colouredLabel.setSpan(colorSpan, 0, label.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
ShortcutInfo webShortcut = new ShortcutInfo.Builder(MainActivity.this, "shortcut_web")
.setShortLabel(colouredLabel)
.setRank(1)
.build();
shortcutmanager.setDynamicShortcuts(Collections.singletonList(webShortcut));

数量限制
静态和动态shortcuts加起来总数最多五个,否则抛出异常:java.lang.IllegalArgumentException: Max number of dynamic shortcuts exceeded,但当正好有5个时, 长按只显示4个。