Shortcut

Introduction: 桌面快捷方式 Sample
More: Author   ReportBugs   
Tags:

  桌面快捷快捷方式,可在受支持的启动器中显示,帮助用户快速访问应用的某些功能。例如点击桌面“扫一扫”快捷方式,便启动 App 并且跳转到扫一扫界面。例如添加小程序到桌面,用户点击桌面快捷方式便可启动 App 快速进入小程序。

  在 Android 8.0(API 级别 26)及更高版本中,才支持创建桌面快捷方式。与静态和动态快捷方式不同,桌面快捷方式在受支持的启动器中显示为单独的图标

权限

创建桌面快捷方式权限不需要运行时请求,在 AndroidManifest.xml 声明即可。

    <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
    <uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />

可是,华为、小米、OPPO、Vivo 等厂商的权限管理都将创建桌面快捷方式权限设计成运行时权限,默认权限是禁止。这样我们要解决两个问题:

  1. 如何检测当前应用是否获取了创建桌面快捷方式权限
    华为、小米、OPPO、Vivo 检测方法不相同,具体分析过程参考《是否允许创建快捷方式的权限检测》,根据这篇文章本人已经整理好相关可运行代码 github
厂商 检测方法 机型有问题请 issue
华为 反射 com.huawei.hsm.permission.PermissionManager#canSendBroadcast Android 7-11
小米 反射 AppOpsManager#checkOpNoThrow Android 7-11
OPPO ContentProvider 查询 URI:content://settings/secure/launcher_shortcut_permission_settings Android 7-11
Vivo ContentProvider 查询 URI:content://com.bbk.launcher2.settings/favorites Android 7-11
  1. 是否可以按照运行时权限进行请求让用户进行授权同意
    不可以,需要引导用户跳转应用设置界面进行权限开启,可以跳转应用设置界面,亦可以跳转单独的创建桌面快捷方式权限设置界面
应用设置界面 创建桌面快捷方式权限界面

参数

  • 创建 ShortcutInfoCompat 对象,必须包含 ID,Intent,ShortLable 三个参数。ID 是唯一性,Intent 是点击桌面快捷方式图标后的跳转意图,ShortLable 是所创建的快捷方式显示的名称。

      /**
       * Builder class for {@link ShortcutInfoCompat} objects.
       */
      public static class Builder {
    
          private final ShortcutInfoCompat mInfo;
    
          public Builder(@NonNull Context context, @NonNull String id) {
              mInfo = new ShortcutInfoCompat();
              mInfo.mContext = context;
              mInfo.mId = id;
          }
          ...
          ...
          /**
           * Creates a {@link ShortcutInfoCompat} instance.
           */
          @NonNull
          public ShortcutInfoCompat build() {
              // Verify the arguments
              if (TextUtils.isEmpty(mInfo.mLabel)) {
                  throw new IllegalArgumentException("Shortcut must have a non-empty label");
              }
              if (mInfo.mIntents == null || mInfo.mIntents.length == 0) {
                  throw new IllegalArgumentException("Shortcut must have an intent");
              }
              return mInfo;
          }
      }
    
  • Icon 不是必须的,如果没有主动设置则显示默认图标。这里特别提出 Icon,是由于 Android 8.0(API 级别 26)引入了自适应启动器图标,在不同设备型号上显示为不同的形状。如果设置的 Icon 是圆形、圆角都可能被系统调整后包了一层白边。如果设置 Icon 是正方形则可能某些机型直接显示为正方形。

厂商 图标表现形式 预期表现形式
华为
小米

这样我们要解决一个问题:

  1. 如何让创建的桌面快捷方式图标与 App 图标保持一致
    将设置图标缩放为 App 图标的大小,然后合并绘制两个图标,取两者重合保留设置图标内容

唯一性

  根据ShortcutInfoCompat#Builder(@NonNull Context context, @NonNull String id)设置的 ID 可以标识每一个快捷方式。可是,华为 8.0 ~ 8.1 出现了一个 bug,名称一致也认为是相同的快捷方式,在 9.0 之后就已修复。
这样我们要解决一个问题:

  1. 如何解决华为 8.0 - 8.1 这两个版本因为名称相同导致无法创建快捷方式的异常
    遍历已有快捷方式,是否存在相同名称的快捷方式,存在则对准备创建的快捷方式改名,目前在后面加一个“.”(当然可以 UUID 确保完全不一样),等待创建成功的回调后,再默默根据 ID 对快捷方式进行更新名称操作

点击快捷方式打开 App

  点击快捷方式,打开的意图是所设置的 Intent,Sample 给的方法是跳转一个透明界面,然后进行逻辑处理。从抽屉式中的通知、桌面快捷方式、微件等端外进入 App 都可以跳转透明的界面再分发做处理。

Apps
About Me
GitHub: Trinea
Facebook: Dev Tools