Android 应用快捷方式 Shortcuts(二)
简介: 快捷方式可帮助用户快速访问您的应用的某些部分,从而为他们呈现特定类型的内容。一次最多可以为应用发布五个快捷方式(静态和动态快捷方式加在一起),但大多数启动器只能显示四个。不过,用户可创建的应用固定快捷方式数量没有限制。应用无法移除固定快捷方式,但仍然可以停用它们。
效果图:
1. 快捷方式的类型:
- 静态快捷方式:最适合在用户与应用互动的整个生命周期内使用一致结构链接到内容的应用。 由于大多数启动器一次只能显示四个快捷方式,因此静态快捷方式对常见 Activity 非常有用。例如,如果用户希望以特定的方式查看他们的日历或电子邮件,使用静态快捷方式可确保他们在执行日常任务时始终获得一致体验。
- 动态快捷方式:用于应用中与上下文相关的操作。 例如,如果您构建的游戏允许用户在启动时就处于当前等级,则需要经常更新快捷方式。动态快捷方式允许游戏在每次用户通关后更新快捷方式。
- 固定快捷方式:用于用户驱动的特定操作。 例如,用户可能需要将特定网站固定到启动器。这很有用,因为它允许用户执行自定义操作,比如一步导航到网站,这比使用浏览器的默认实例速度更快。
1.2 创建动态快捷方式
动态快捷方式提供指向应用内特定的上下文相关操作的链接。这些操作可能会在应用的不同使用场景间发生变化,甚至会在应用运行时发生变化。适合使用动态快捷方式的操作包括致电特定人员、导航到特定位置,以及从用户的上一个存档点加载游戏。
ShortcutManager API 可让您对动态快捷方式完成以下操作:
- 发布:使用
setDynamicShortcuts()
重新定义整个动态快捷方式列表,或使用addDynamicShortcuts()
扩充现有的动态快捷方式列表。 - 更新:使用
updateShortcuts()
方法。 - 移除:使用
removeDynamicShortcuts()
移除一组动态快捷方式,或使用removeAllDynamicShortcuts()
移除所有动态快捷方式。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
ShortcutManager shortcutManager = getSystemService(ShortcutManager.class);
Intent mainIntent = new Intent(this, MainActivity.class);
mainIntent.setAction(Intent.ACTION_MAIN);
List<ShortcutInfo> infos = new ArrayList<>();
if (shortcutManager != null) {
for (int i = 0; i < shortcutManager.getMaxShortcutCountPerActivity(); i++) {
ShortcutInfo shortcutInfo = new ShortcutInfo.Builder(this, "shortcuts" + (i + 1))
.setShortLabel("shortcuts" + (i + 1))
.setLongLabel("shortcuts" + (i + 1))
.setIcon(Icon.createWithResource(this, R.mipmap.shortcut1))
.setIntent(mainIntent)
.build();
infos.add(shortcutInfo);
}
shortcutManager.setDynamicShortcuts(infos);
}
}
}
说明:
- 静态快捷方式等于或超过5个,不配置动态快捷方式,应用不会报错,最后只显示4个快捷方式。
- 动态快捷方式配置5个,不配置静态快捷方式,应用不会报错,最后只显示4个快捷方式。
- 动态快捷方式超过5个,不配置静态快捷方式,应用抛出错误
Max number of dynamic shortcuts exceeded
。 - 静态快捷方式+动态快捷方式等于
getMaxShortcutCountPerActivity()
个,最后只显示4个快捷方式。 - 静态快捷方式+动态快捷方式超过
getMaxShortcutCountPerActivity()
个,应用抛出错误Max number of dynamic shortcuts exceeded
。
更新快捷方式
使用 updateShortcuts()
方法可以更新现有的快捷方式,构建ShortcutInfo时需要指定相同的id,根据id去找到要更新的快捷方式。需要注意只有动态快捷方式和后面要说的固定快捷方式才能更新,如果传入了一个静态快捷方式的id,应用会抛出错误Manifest shortcut ID=XX may not be manipulated via APIs。
/**
* 根据id去找到要更新的快捷方式
* 只有动态快捷方式和固定快捷方式才能更新,如果传入了一个静态快捷方式的id,应用会抛出错误
* Manifest shortcut ID=XX may not be manipulated via APIs。
* @param i
*/
private void updateItem(int i) {
ShortcutInfo info = infos.get(i);
ShortcutInfo infoNew = new ShortcutInfo.Builder(this, info.getId())
.setShortLabel("updated label")
.setLongLabel("updated long label")
.setIcon(Icon.createWithResource(this, R.mipmap.shortcut3))
.setIntent(info.getIntent())
.build();
shortcutManager.updateShortcuts(Arrays.asList(infoNew));
}
删除快捷方式
使用 removeDynamicShortcuts()
移除一组动态快捷方式,或使用 removeAllDynamicShortcuts()
移除所有动态快捷方式。和更新一样,如果传入静态快捷方式的id会报错。
如果在删除之前将快捷方式固定到了桌面上(这种称作固定快捷方式,后面还会提到),在删除之后该快捷方式的图标不会消失,点击后依然可以完成正常跳转。这种固定在桌面上的快捷方式只能用户手动来移除,因此更好的一种做法是在删除快捷方式后判断该快捷方式是否被固定到了桌面上,如果是的话就再禁用该快捷方式,并提示用户该快捷方式已被删除,禁用快捷方式的方法下面会提到。
/**
* 根据id去找到要移除的快捷方式
* 如果传入了一个静态快捷方式的id,应用会抛出错误
* Manifest shortcut ID=XX may not be manipulated via APIs。
* @param index
*/
private void removeItem(int index) {
shortcutManager.removeDynamicShortcuts(Arrays.asList(infos.get(index).getId()));
}
禁用快捷方式
通过ShortcutManager
的disableShortcuts()
方法可以禁用快捷方式,第一个参数传入要禁用的快捷方式id
列表,第二个参数是disabledMessage
,用于提示用户禁用快捷方式的原因,该参数也可以不传。同样地,不能通过该方法禁用静态快捷方式,禁用静态快捷方式是通过在xml文件中配置来实现的。
/**
* 根据id去找到要禁用的快捷方式
* 禁用静态快捷方式是通过在xml文件中配置来实现的
* @param index
*/
private void disableItem(int index) {
shortcutManager.disableShortcuts(Arrays.asList(infos.get(index).getId()), "该快捷方式已被禁用");
}
禁用之后,长按应用图标不会显示该快捷方式,如果此前将快捷方式固定到了桌面上,禁用后图标会变成灰色,点击图标会弹出提示信息,即上面传入的第二个参数disabledMessage,没有传的话就提示默认信息。
1.3 创建固定快捷方式
在 Android 8.0(API 级别 26)及更高版本中,你可以创建固定快捷方式。与静态和动态快捷方式不同,固定快捷方式在受支持的启动器中显示为单独的图标。如图显示了这两类快捷方式之间的区别。
指用户通过拖拽任到桌面上的Shortcuts,即便App内删除了某个Shortcut,对应的Pinned Shortcut也不会被删除。Pinned Shortcuts 并没有个数限制,并且Pinned Shortcut 对应的 Shortcut 即便被动态删除了,依然可以通过 id 进行 Update 操作。
要将快捷方式固定到使用您的应用的受支持启动器上,请按顺序完成以下一系列步骤:
- 使用
isRequestPinShortcutSupported()
验证设备的默认启动器是否支持应用内固定快捷方式。 - 使用以下两种方式之一创建
ShortcutInfo
对象,具体采用哪种方式取决于是否已存在相应快捷方式:
a. 如果已存在相应快捷方式,请创建仅包含现有快捷方式 ID 的ShortcutInfo
对象。系统会自动找到与该快捷方式相关的所有其他信息,并将其固定。
b. 如果要固定原本不存在的新快捷方式,请创建包含新快捷方式 ID、intent 和简短标签的ShortcutInfo
对象。 - 尝试通过调用
requestPinShortcut()
将快捷方式固定到设备的启动器上。在此过程中,您可以传入一个PendingIntent
对象,用于仅在快捷方式成功固定后通知您的应用。
/**
* 创建固定快捷方式
* @param index
*/
private void pinnedShortcut(int index) {
if (shortcutManager.isRequestPinShortcutSupported()) {
ShortcutInfo shortcutInfo = new ShortcutInfo.Builder(this, infos.get(index).getId()).build();
// String actionName = "com.csu.shortcuts";
// IntentFilter intentFilter = new IntentFilter();
// intentFilter.addAction(actionName);
// PinnedReceiver receiver = new PinnedReceiver();
// registerReceiver(receiver, intentFilter);
//
// Intent intent = new Intent(actionName);
// PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
// shortcutManager.requestPinShortcut(shortcutInfo, pendingIntent.getIntentSender());
Intent intent = shortcutManager.createShortcutResultIntent(shortcutInfo);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
shortcutManager.requestPinShortcut(shortcutInfo, pendingIntent.getIntentSender());
}
}
class PinnedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(MainActivity.this, "固定快捷方式成功", Toast.LENGTH_SHORT).show();
}
}
快捷方式固定后,可以使用 updateShortcuts()
方法更新其内容。
参考:
https://www.jianshu.com/p/6b6f79096256?utm_source=desktop&utm_medium=timeline
https://developer.android.google.cn/guide/topics/ui/shortcuts/creating-shortcuts