「前端」Android桌面圖標快捷方式

架構思考 發佈 2022-12-09T18:34:23.372657+00:00

一、背景長按桌面圖標實現快捷方式最早是iOS提供的功能,而Android最早在Android 7.1版本也提供了對這方面的支持,於是在短時間內,像微信,支付寶,頭條等流量級應用都提供了這方面的支持,如下圖。

一、背景

長按桌面圖標實現快捷方式最早是iOS提供的功能,而Android最早在Android 7.1版本也提供了對這方面的支持,於是在短時間內,像微信,支付寶,頭條等流量級應用都提供了這方面的支持,如下圖。

現在,長按桌面圖標快捷方式已經是很成熟的功能,實現上也比較簡單,主要用到的Api就是ShortcutManager。而在具體實現方案上,Android 又給出了兩種實現方式,一種是靜態,一種是動態。

二、靜態方式

靜態方式需要使用xml資源,以shortcuts標籤的形式引入。對於靜態方式,我們首先需要在res目錄的xml目錄下創建一個xml資源文件,如下所示。

<?xml version="1.0" encoding="utf-8"?>
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">

    <shortcut
        android:enabled="true"
        android:icon="@mipmap/ic_shortcut_scan"
        android:shortcutId="scan"
        android:shortcutShortLabel="掃一掃">

        <Intent
            android:action="android.intent.action.VIEW"
            android:targetClass="com.xzh.app.ScanActivity"
            android:targetPackage="com.xzh.app" />
        <categories android:name="android.shortcut.conversation" />
        <capability-binding android:key="actions.intent.SCAN" />
    </Shortcut>

    ... //省略其他代碼
</shortcuts>

其中,使用靜態方式常見的配置屬性如下:

  • enabled:表示這個shortcut是否可用;
  • icon:為快捷圖標;
  • shortcutId:快捷方式唯一的id;
  • shortcutShortLabel:短名稱;
  • shortcutLongLabel:配置的長名稱, launcher會優先選擇長名稱顯示,顯示不下會選擇短名稱;
  • categories:為應用程式的快捷方式執行的操作類型提供分組
  • capability-binding:聲明與此快捷方式關聯的功能。

除此之外,在shortcut標籤下也有幾個屬性需要注意:

  • intent:點擊shortcut時的目標頁;
  • targetPackage:指定一個目標應用的包名;
  • targetClass:要跳轉的目標類, 需要注意的是,android:action一定要配置,否則可能出現崩潰;
  • categories:目前官方只給提供了android.shortcut.conversation;

完成上述操作後,接下來就是在清單文件AndroidManifest.xml里進行配置。具體來說,就是在AndroidManifest.xml的入口Activity中引入shortcuts資源。

<!--引入shortcuts資源-->
<meta-data
    android:name="android.app.shortcuts"
    android:resource="@xml/shortcuts" />

完成上述操作後,我們就可以允許工程代碼了,效果如下。

三、動態方式

靜態快捷方式適合畢竟固定的場景,如果快捷方式需要動態配置,那麼就需要用到ShortcutManagerCompat或ShortcutManager來實現。

3.1 ShortcutManagerCompat

下面是使用ShortcutManagerCompat實現動態快捷方式的示例代碼。

private fun initShortCut() {
    //動態方式添加
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
        val shortScan = ShortcutInfoCompat.Builder(this, "scan")
            .setShortLabel(getString(R.string.short_cut_scan))
            .setIcon(IconCompat.createWithResource(this, R.mipmap.ic_shortcut_scan))
            .setIntent(Intent(Intent.ACTION_MAIN, null, this, ScanActivity::class.java))
            .build()
        ShortcutManagerCompat.addDynamicShortcuts(this, mutableListOf(shortScan))
    }
}

如果需要更新快捷方式,可以使用updateShortcuts方法,參考代碼如下。

private fun updateShortCut() {
    val shortScan = ShortcutInfoCompat.Builder(this, "scan") 
        .setShortLabel(getString(R.string.short_cut_scan)) 
        .setIcon(IconCompat.createWithResource(this, R.mipmap.ic_shortcut_scan)) 
        .setIntent(Intent(Intent.ACTION_MAIN, null, this, MainActivity::class.java))
        .build()
    ShortcutManagerCompat.updateShortcuts(this, mutableListOf(shortScan))
}

如果要刪除快捷方式,需要用到ShortcutManagerCompat的removeDynamicShortcuts刪除方法,並且需要使用創建時的唯一id,參考代碼如下。

//動態移除
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
    ShortcutManagerCompat.removeDynamicShortcuts(
        this@MainActivity,
        Collections.singletonList("scan")//唯一標識id
    )
}

3.2 ShortcutManager

除了ShortcutManagerCompat方式外,我們還可以使用ShortcutManager來創建快捷方式,如下所示。

private fun initShortCut() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
        val info = ShortcutInfo.Builder(this, "scan") 
            .setShortLabel(getString(R.string.short_cut_scan)) 
            .setIcon(Icon.createWithResource(this, R.mipmap.ic_shortcut_scan)) 
            .setIntent(intent) 
            .build()
        getSystemService(ShortcutManager::class.java)
            .dynamicShortcuts = mutableListOf(info)
    }
}

如果需要更新快捷方式,可以使用updateShortcuts方法,如下所示。

private fun updateShortCut() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
        val info = ShortcutInfo.Builder(this, "scan") 
            .setShortLabel(getString(R.string.short_cut_scan)) 
            .setIcon(Icon.createWithResource(this, R.mipmap.ic_shortcut_scan)) 
            .setIntent(intent) 
            .build()
        getSystemService(ShortcutManager::class.java).updateShortcuts(listOf(info))
    }
}

如果要刪除快捷方式,可以使用removeDynamicShortcuts方法,如下所示。

private fun delShortCut() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
        getSystemService(ShortcutManager::class.java)
            .removeDynamicShortcuts(listOf("scan")) 
    }
}

下面是ShortcutManager的常見方法:

  • setDynamicShortcuts():可以添加或替換所有的shortcut;
  • addDynamicShortcuts():來添加新的shortcut到列表中,超過最大個數會報異常
  • updateShortcuts(List shortcutInfoList):更新已有的動態快捷方式;
  • removeDynamicShortcuts(List shortcutIds):根據動態快捷方式的ID,刪除已有的動態快捷方式;
  • removeAllDynamicShortcuts():刪除掉app中所有的動態快捷方式;
  • getDynamicShortcuts():得到所有的動態shortcuts;

到此,快捷方式的靜態和動態添加方式就介紹完成了。

建議您收藏或轉發,以備不時之需。

文章來源:xiangzhihong_https://segmentfault.com/a/1190000043005248

關鍵字: