Android应用快捷方式

时间:2022-10-18 00:02:25

有的App会给用户提供快捷方式,8.0之前我们多是通过发送com.android.launcher.action.INSTALL_SHORTCUT 广播的方式来实现。但在8.0的系统行为变更中指出,该广播变为私有的隐式广播,因此原来创建快捷方式的方法在8.0的系统上将不再有效,官方推荐我们使用ShortcutManager来创建应用快捷方式。

快捷方式应用场景及类型

快捷方式应用场景

Android 7.1起,开发者可以创建一些跳转到特定页面的快捷方式,常见的应用场景如:

  1. 地图App中为用户导航到特定位置
  2. 社交App中向某个好友发送消息
  3. 多媒体App中播放电视剧的下一集
  4. 游戏App中加载上次保存的状态

快捷方式类型

Static shortcuts

静态快捷方式通过资源文件定义,并且打包到APK中,因此只能在更新App时才能修改此类快捷方式。

Dynamic shortcuts

动态快捷方式在App运行时使用ShortcutManager API定义,可以在运行时创建、修改和删除。

Pinned shortcuts

固定快捷方式也是在App运行时通过ShortcutManager API定义,App会弹出确认对话框来申请创建该快捷方式,如果用户允许,则此快捷方式将会显示在支持它的启动器(Launcher)上。

一个App最多可以创建5个静态、动态快捷方式,对于固定快捷方式的数量则没有限制,但一些Launcher应用可能不会全部显示出所创建的动态或静态快捷方式。

注意:虽然其他应用无法访问快捷方式的元数据,但Launcher应用可以,因此创建快捷方式时尽量不要涉及用户隐私。

使用静态快捷方式

应用场景

  1. 查看发送的消息
  2. 设置闹钟
  3. 显示用户当天的活动

创建步骤

  1. 在AndroidManifest.xml中,找到启动Activity,即设置了 android.intent.action.MAINandroid.intent.category.LAUNCHER这两个Intent Filter的Activity。

  2. 为这个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>
  3. 创建快捷方式的资源文件 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)效果类似。

  4. 效果图,有点像iOS的3D Touch(来自官方文档)

    Android应用快捷方式

使用动态快捷方式

应用场景

  1. 给某人打电话
  2. 导航到某个位置
  3. 查看游戏的当前分数

创建方法

  1. Publish: 使用 setDynamicShortcuts() 来重定义快捷方式列表,或者使用 addDynamicShortcuts() 来扩展已经存在的快捷方式列表。
  2. Update: 使用 updateShortcuts() 方法更新快捷方式。
  3. 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上表现为独立的图标,如图(来自官网)所示:

Android应用快捷方式

当尝试创建此种快捷方式时,会弹出申请对话框让用户确定,如果用户没有同意,则Launcher会取消创建快捷方式的请求。

创建步骤

  1. 首先使用 isRequestPinShortcutSupported() 方法来检查设备默认的Launcher应用是否支持固定快捷方式。

  2. 创建ShortcutInfo 对象,根据快捷方式是否存在有两种不同的处理方式:

    1. 如果快捷方式已经存在,则创建的ShortcutInfo 对象仅包含快捷方式ID,系统会将其他信息自动关联到此快捷方式。
    2. 如果快捷方式不存在,则创建的ShortcutInfo 对象包含快捷方式ID、Intent、label等信息。
  3. 调用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