有的App会给用户提供快捷方式,8.0之前我们多是通过发送com.android.launcher.action.INSTALL_SHORTCUT
广播的方式来实现。但在8.0的系统行为变更中指出,该广播变为私有的隐式广播,因此原来创建快捷方式的方法在8.0的系统上将不再有效,官方推荐我们使用ShortcutManager来创建应用快捷方式。
快捷方式应用场景及类型
快捷方式应用场景
Android 7.1起,开发者可以创建一些跳转到特定页面的快捷方式,常见的应用场景如:
- 地图App中为用户导航到特定位置
- 社交App中向某个好友发送消息
- 多媒体App中播放电视剧的下一集
- 游戏App中加载上次保存的状态
快捷方式类型
Static shortcuts
静态快捷方式通过资源文件定义,并且打包到APK中,因此只能在更新App时才能修改此类快捷方式。
Dynamic shortcuts
动态快捷方式在App运行时使用ShortcutManager
API定义,可以在运行时创建、修改和删除。
Pinned shortcuts
固定快捷方式也是在App运行时通过ShortcutManager
API定义,App会弹出确认对话框来申请创建该快捷方式,如果用户允许,则此快捷方式将会显示在支持它的启动器(Launcher)上。
一个App最多可以创建5个静态、动态快捷方式,对于固定快捷方式的数量则没有限制,但一些Launcher应用可能不会全部显示出所创建的动态或静态快捷方式。
注意:虽然其他应用无法访问快捷方式的元数据,但Launcher应用可以,因此创建快捷方式时尽量不要涉及用户隐私。
使用静态快捷方式
应用场景
- 查看发送的消息
- 设置闹钟
- 显示用户当天的活动
创建步骤
在AndroidManifest.xml中,找到启动Activity,即设置了
android.intent.action.MAIN
和android.intent.category.LAUNCHER
这两个Intent Filter的Activity。-
为这个Activity设置元数据,并引用为其定义的快捷方式资源文件,如下:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapplication">
<application ... >
<activity android:name="Main">
<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>
</manifest> -
创建快捷方式的资源文件
res/xml/shortcuts.xml
,其根元素为<shortcuts>
,它包含了一个快捷方式列表,每个快捷方式用<shortcut>
标签表示,每个快捷方式中又声明了快捷方式图标、描述、intent等信息,示例如下:<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
<shortcut
android:shortcutId="compose"
android:enabled="true"
android:icon="@drawable/compose_icon"
android:shortcutShortLabel="@string/compose_shortcut_short_label1"
android:shortcutLongLabel="@string/compose_shortcut_long_label1"
android:shortcutDisabledMessage="@string/compose_disabled_message1">
<intent
android:action="android.intent.action.VIEW"
android:targetPackage="com.example.myapplication"
android:targetClass="com.example.myapplication.ComposeActivity" />
<!-- If your shortcut is associated with multiple intents, include them
here. The last intent in the list determines what the user sees when
they launch this shortcut. -->
<categories android:name="android.shortcut.conversation" />
</shortcut>
<!-- Specify more shortcuts here. -->
</shortcuts>注意:如果某个快捷方式配置了多个Intent,则点击快捷方式时会跳到最后一个Intent对应的界面,然后按回退栈的方式,如果点击返回键,则返回倒数第二个Intent对应的界面,跟startActivities(Intent[] intents)效果类似。
-
效果图,有点像iOS的3D Touch(来自官方文档)
使用动态快捷方式
应用场景
- 给某人打电话
- 导航到某个位置
- 查看游戏的当前分数
创建方法
-
Publish: 使用
setDynamicShortcuts()
来重定义快捷方式列表,或者使用addDynamicShortcuts()
来扩展已经存在的快捷方式列表。 -
Update: 使用
updateShortcuts()
方法更新快捷方式。 -
Remove: 使用
removeDynamicShortcuts()
来删除一组快捷方式,或者使用removeAllDynamicShortcuts()
来删除所有的快捷方式。
创建动态快捷方式的代码示例:
ShortcutManager shortcutManager = getSystemService(ShortcutManager.class);
ShortcutInfo shortcut = new ShortcutInfo.Builder(this, "id1")
.setShortLabel("Web site")
.setLongLabel("Open the web site")
.setIcon(Icon.createWithResource(context, R.drawable.icon_website))
.setIntent(new Intent(Intent.ACTION_VIEW,
Uri.parse("https://www.mysite.example.com/")))
.build();
shortcutManager.setDynamicShortcuts(Arrays.asList(shortcut));
使用固定快捷方式
应用场景
在8.0或更高的系统上可以使用固定快捷方式,此类快捷方式在支持它的Launcher上表现为独立的图标,如图(来自官网)所示:
当尝试创建此种快捷方式时,会弹出申请对话框让用户确定,如果用户没有同意,则Launcher会取消创建快捷方式的请求。
创建步骤
首先使用
isRequestPinShortcutSupported()
方法来检查设备默认的Launcher应用是否支持固定快捷方式。-
创建
ShortcutInfo
对象,根据快捷方式是否存在有两种不同的处理方式:- 如果快捷方式已经存在,则创建的
ShortcutInfo
对象仅包含快捷方式ID,系统会将其他信息自动关联到此快捷方式。 - 如果快捷方式不存在,则创建的
ShortcutInfo
对象包含快捷方式ID、Intent、label等信息。
- 如果快捷方式已经存在,则创建的
-
调用
requestPinShortcut()
方法尝试在设备Launcher上创建快捷方式,同时可以传入一个PendingIntent,当创建快捷方式成功时会通知应用。注意:如果用户不允许创建快捷方式,则应用不会收到回调。当快捷方式创建好之后,可以使用
updateShortcuts()
方法更新其内容。
示例代码:
ShortcutManager mShortcutManager =
context.getSystemService(ShortcutManager.class);
if (mShortcutManager.isRequestPinShortcutSupported()) {
// Assumes there's already a shortcut with the ID "my-shortcut".
// The shortcut must be enabled.
ShortcutInfo pinShortcutInfo =
new ShortcutInfo.Builder(context, "my-shortcut").build();
// Create the PendingIntent object only if your app needs to be notified
// that the user allowed the shortcut to be pinned. Note that, if the
// pinning operation fails, your app isn't notified. We assume here that the
// app has implemented a method called createShortcutResultIntent() that
// returns a broadcast intent.
Intent pinnedShortcutCallbackIntent =
mShortcutManager.createShortcutResultIntent(pinShortcutInfo);
// Configure the intent so that your app's broadcast receiver gets
// the callback successfully.
PendingIntent successCallback = PendingIntent.getBroadcast(context, 0,
pinnedShortcutCallbackIntent, 0);
mShortcutManager.requestPinShortcut(pinShortcutInfo,
successCallback.getIntentSender());
}
兼容老版本
为了支持Android 7.1(API Level=25)及之前的版本,可以使用Android兼容库,参考ShortcutManagerCompat。