Android应用快捷方式 - Shortcuts

1,646 阅读4分钟

前言

最近产品小姐姐提出和苹果一样"3D Touch"类似的功能,刚好谷歌提供了"Shortcuts"相关快捷方式Api,本文就参照某地图软件快捷方式效果实现

参考效果

某地图快捷方式效果展示

提取功能点

  1. 长按显示快捷方式列表

  2. 显示广告页

  3. 跳转目标页面

  4. 目标页面返回首页

具体实现

创建快捷方式

官方提供了静态和动态创建两种方式,这里主要介绍动态创建,它更加灵活.

代码很简单,看注释即可

  val shortcutItemList = mutableListOf<ShortcutInfoCompat>()

        //用于演示只创建一个 "从这里出发" 的快捷方式

        //1.构建任务栈列表
        val intentList  = arrayOf() 

        //2.创建快捷方式条目
        val shortcutItem = ShortcutInfoCompat
                //设置唯一Id
                .Builder(context, "shortcut_id")
                //条目显示的文本,设置成一样即可
                .setShortLabel("从这里出发")
                .setLongLabel("从这里出发")
                //设置图标
                .setIcon(IconCompat.createWithResource(context, R.mipmap.ic_launcher_round))
                //设置任务栈
                .setIntents(intentList)
                .build()
        shortcutItemList.add(shortcutItem)
        //3.将自定义快捷方式列表导入管理器
        ShortcutManagerCompat.setDynamicShortcuts(context, shortcutItemList)

设置Intent

这里的Intent 指的是点击快捷方式后,需要的跳转的界面,一般 setIntent() 即可,但是从前面的效果可以看出,跳转到目标界面后,此时我们点击返回需要返回到首页,这时候我们就可以使用setIntents()

官网说明

使用ShortcutInfoCompat.Builder创建快捷方式时,您可以使用 setIntents() 代替 setIntent()。通过调用 setIntents(),您可以在用户选择某个快捷方式时在应用内启动多个 Activity,同时将列表中除最后一个 Activity 之外的所有 Activity 放到返回堆栈上...

目标界面分析

我们需要实现的核心功能

  • 长按快捷方式(广告页 -> 导航页 )
  • 点击返回(导航页 -> 首页)

这里我将首页作为第一个界面,广告页作为"目标页面",当广告页启动后,立即跳转导航页,并finish广告页, 这时任务栈就只有首页和导航页,点击返回后,就返回到了首页了.也就达到了目标效果

完整intentList

    //1.构建任务栈列表
        val intentList = arrayOf(
                //TODO 定义目前界面返回后显示的界面,一般是首页
                Intent(context, MainActivity::class.java).apply {
                    action = Intent.ACTION_MAIN
                    flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
                },

                //这里用SplashActivity充当处理Shortcuts逻辑的页面
                Intent(context, SplashActivity::class.java).apply {
                    //TODO 目标快捷方式必须设置action,否者报错,任意action即可
                    action = Intent.ACTION_VIEW
                    //TODO 官网推荐,配合taskAffinity 使用
                    flags = Intent.FLAG_ACTIVITY_NEW_TASK
                    //TODO 这是意图参数
                    putExtra("action_id", "guide")
                }
        )
        

Manifest

 <activity
            android:name=".SplashActivity"
            android:excludeFromRecents="true"
            android:noHistory="true"
            android:taskAffinity="">
        
        </activity>

注意点

  • 创建Intent 必须设置action,否者报错

  • 目标界面最好配置 taskAffinity(官方推荐)

  • 使用taskAffinity最好指定excludeFromRecents,noHistory,否者任务栈会有记录

官网
从一个 Activity 启动另一个 Activity
静态快捷方式不能有自定义 intent 标记。 静态快捷方式的第一个 intent 始终设置有 Intent.FLAG_ACTIVITY_NEW_TASKIntent.FLAG_ACTIVITY_CLEAR_TASK。这意味着,如果应用已在运行,则在静态快捷方式启动时,应用中的所有现有 Activity 都会被销毁。如果不希望出现这种行为,您可以使用 Trampoline Activity,或者使用一个先在 Activity.onCreate(Bundle) 中启动其他 Activity、而后调用Activity.finish()的不可见 Activity:

  1. 在 AndroidManifest.xml 文件中,Trampoline Activity 应包含属性分配 android:taskAffinity=""。
  2. 在快捷方式资源文件中,静态快捷方式内的 intent 应引用 Trampoline Activity。

实现跳转逻辑

我们在构建Intent 时可以传入自定义参数,可用控制跳转逻辑,Demo这部分代码很简单,直接上代码

class SplashActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_splash)
        //TODO 区分是默认启动还是普通启动
        val action = intent.getStringExtra("action_id")
        handlerAction(action)
    }

    fun handlerAction(action: String?) {
        when (action) {
            "guide" -> startToGuide()
            else -> startToMain()
        }
    }

    fun startToMain() {
        thread {
            sleep(2000)
            val intent = Intent(this, MainActivity::class.java)
            startActivity(intent)
            finish()
        }
    }

    fun startToGuide() {
        thread {
            sleep(500)
            val intent = Intent(this, GuideActivity::class.java)
            startActivity(intent)
            finish()
        }
    }
}

效果展示

这里的三个界面都是某地图软件截图,关注跳转逻辑即可,通过Shortcuts我们可以很容易给App增加快捷方式的入口功能

虽然目前定制能力有限,但基本满足了开发需求,真是Biu倍爽

特别注意

  • 快捷方式显示效果不一致,不同厂商的ROM实现不一样

  • 定制能力有限,只能简单定制下图标

  • 最好不要修改字体(亮/暗模式切换后,会自动修改文字颜色,手动修改后失效)

  • 动态状态快捷方式,至少启动过一次App才能生效,后续启动不需要(第一次安装未启动时,长按)