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

是什么?
是將應(yīng)用程序的常見操作或任務(wù)暴露給啟動項的一種方法。通過長按應(yīng)啟動圖標(biāo)顯示快捷方式。
快捷方式可以拖拽到桌面單獨放置,變成單獨的桌面快捷方式。
-
靜態(tài):在
xml文件中定義 - 動態(tài):由ShortcutManager發(fā)布,可根據(jù)用戶的行為或偏好添加,支持動態(tài)更新
靜態(tài) 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目錄下創(chuàng)建shortcuts.xml文件,里面包含靜態(tài)的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>
根標(biāo)簽<shortcuts>,可以包含多個<shortcut>,每一個代表一個靜態(tài)shortcut:
-
enabled:shortcut是否可用 -
icon:shortcut左側(cè)顯示的圖標(biāo) -
shortcutDisabledMessage:選擇不可用的shortcut時給用戶的一個提示 -
shortcutId:唯一的id,id相同時只顯示第一個 -
shortcutShortLabel:配置短名稱,長名稱顯示不下時顯示短名稱 -
shortcutLongLabel:配置長名稱,launcher優(yōu)先選擇顯示 -
intent:確定一個或多個意圖,并綁定shortcut-
targetPackage: 指定目標(biāo)應(yīng)用的包名 -
targetClass: 要跳轉(zhuǎn)的目標(biāo)類 -
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>
點擊快捷方式會創(chuàng)建一個intents棧(MainActivity -> Static ShortcutActivity),當(dāng)返回時回到MainActivity:

動態(tài) Shortcuts
可以在使用應(yīng)用的過程中構(gòu)建,更新,或者刪除。
相關(guān)方法: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
可對動態(tài)shortcut完成以下操作:
- 發(fā)布(Publish):
setDynamicShortcuts(List)、addDynamicShortcuts(List) - 更新(Update):
updateShortcuts(List) - 刪除(Remove):
removeDynamicShortcuts(List)、removeAllDynamicShortcuts()
ShortcutInfo.Builder
方法中第二個參數(shù)是shortcut的id,多個shortcut的id相同時,前面的shortcut會被覆蓋。
多個Intent構(gòu)建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>
和靜態(tài)一樣,最后一個Intent打開TwoActivity頁面,前面的構(gòu)建back stack, 即返回退回到MainActivity。
注意:
Intent必須指定Action,否則拋出異常。
Shortcut 排序
含多個Shortcuts時,默認(rèn)按照添加順序排列,通過setRank()可改變排序。
ShortcutInfo webShortcut = new ShortcutInfo.Builder(MainActivity.this, "shortcut_web")
.setRank(1) //參數(shù)不能為負(fù)數(shù)
.build();
ShortcutInfo dynamicShortcut = new ShortcutInfo.Builder(MainActivity.this, "shortcut_dynamic")
.setRank(0)
.build();
shortcutManager.updateShortcuts(Arrays.asList(webShortcut, dynamicShortcut));
只能改變動態(tài)shortcuts的排序,且按照xml中先后順序排列,故:靜態(tài)的shortcuts離應(yīng)用圖標(biāo)最近,動態(tài)shortcuts在其之上排序,首位級別為0,依次類推。

其他
ShortcutInfo.Builder的setShortLabel(CharSequence)接收一個CharSequence作為參數(shù),這意味著可以添加自定義的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));

數(shù)量限制
靜態(tài)和動態(tài)shortcuts加起來總數(shù)最多五個,否則拋出異常:java.lang.IllegalArgumentException: Max number of dynamic shortcuts exceeded,但當(dāng)正好有5個時, 長按只顯示4個。