ShortcutManager桌面app图标长按快捷入口

273 阅读3分钟

1.动态方式实现

1.kotlin版代码

1.1 直接实现

对应代码:

    fun shortcut(){
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N_MR1) {
            val scManager: ShortcutManager = getSystemService(ShortcutManager::class.java)
            //跳转Second
            val secondIntent = Intent("secondback",android.net.Uri.EMPTY,
                this,Test::class.java) //此处的Test即为回退页面,快捷方式跳转的页面按下返回键后显示的页面
            val infoPublishPai: ShortcutInfo =ShortcutInfo.Builder(this, "two")
                .setShortLabel("go second")
                .setRank(1)
                .setIcon(android.graphics.drawable.Icon.createWithResource(this,R.drawable.icon_shortcut_pai))
                .setIntents(arrayOf<Intent>(secondIntent,Intent(this,Second::class.java).setAction("second")))
                .build()
            val list: MutableList<ShortcutInfo> = java.util.ArrayList<ShortcutInfo>()
            list.add(infoPublishPai)

            if (scManager != null) {
                scManager.setDynamicShortcuts(list)
            }
        }
    }

2.2 设置解析实现

上面是直接设置时就指定跳转的页面,还有一种方式是设置后解析跳转,如下:

package com.wsx.shortcutsdemo

import android.content.Intent
import android.content.pm.ShortcutInfo
import android.content.pm.ShortcutManager
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
//        方式1 在AndroidManifest.xml中

//        方式2
//        shortcut()

//        方式3
        initShortcuts()
        jumpShortcuts()
    }

    fun shortcut(){
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N_MR1) {
            val scManager: ShortcutManager = getSystemService(ShortcutManager::class.java)
            //跳转Second
            val secondIntent = Intent("secondback",android.net.Uri.EMPTY,
                this,Test::class.java) //此处的Test即为回退页面,快捷方式跳转的页面按下返回键后显示的页面
            val infoPublishPai: ShortcutInfo =ShortcutInfo.Builder(this, "two")
                .setShortLabel("go second")
                .setRank(1)
                .setIcon(android.graphics.drawable.Icon.createWithResource(this,R.drawable.icon_shortcut_pai))
                .setIntents(arrayOf<Intent>(secondIntent,Intent(this,Second::class.java).setAction("second")))
                .build()
            val list: MutableList<ShortcutInfo> = java.util.ArrayList<ShortcutInfo>()
            list.add(infoPublishPai)

            if (scManager != null) {
                scManager.setDynamicShortcuts(list)
            }
        }
    }
    /**
     * 7.1以上支持shortcuts
     */
    private fun initShortcuts() {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N_MR1) {
            val scManager: ShortcutManager = getSystemService(ShortcutManager::class.java)
            //跳转Test
            val testIntent = Intent(Intent.ACTION_MAIN,android.net.Uri.EMPTY,
                this,MainActivity::class.java)//此处需为入口页面,否则快捷方式目标页面跳转不了
            testIntent.putExtra("shortcuts", "test")//自定义的规则,解析跳转时用到
            val infoForumPublish: ShortcutInfo = ShortcutInfo.Builder(this, "testid")
                .setShortLabel("测试一下")
                .setRank(0)
                .setIcon(android.graphics.drawable.Icon.createWithResource(this, R.drawable.icon_shortcut_post))
                .setIntents(arrayOf<Intent>(testIntent))
                .build()
//            action ,id 可以随便填
            //跳转Second
            val secondIntent = Intent("secondaction",android.net.Uri.EMPTY,
                this,MainActivity::class.java)
            secondIntent.putExtra("shortcuts", "second")
            val infoPublishPai: ShortcutInfo =ShortcutInfo.Builder(this, "secondid")
                .setShortLabel("go second")
                .setRank(1)
                .setIcon(android.graphics.drawable.Icon.createWithResource(this,R.drawable.icon_shortcut_pai))
                .setIntents(arrayOf<Intent>(secondIntent))
                .build()
            val list: MutableList<ShortcutInfo> = java.util.ArrayList<ShortcutInfo>()
            list.add(infoForumPublish)
            list.add(infoPublishPai)
            if (scManager != null) {
                scManager.setDynamicShortcuts(list)
            }
        }
    }

//    override fun onNewIntent(intent: Intent?) {
//        super.onNewIntent(intent)
//        jumpShortcuts()
//    }

    private fun jumpShortcuts() {
        val shortcuts: String? =intent.getStringExtra("shortcuts")
        when(shortcuts){
            "test"->{
                startActivity(Intent(this,Test::class.java))
            }
            "second"->{
                startActivity(Intent(this,Second::class.java))
            }
        }
    }
}

2.java版代码

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initShortcuts();
        jumpShortcuts();
    }
    private void initShortcuts() {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N_MR1) {
            ShortcutManager scManager = getSystemService(ShortcutManager.class);
            Intent forumPublishIntent = new Intent("test", Uri.EMPTY, this, MainActivity.class);
            forumPublishIntent.putExtra("shortcuts", "test");
            ShortcutInfo infoForumPublish = new ShortcutInfo.Builder(this, "test")
                    .setShortLabel("测试一下")
                    .setIcon(Icon.createWithResource(this, R.drawable.icon_shortcut_post))
                    .setIntents(new Intent[]{
                            forumPublishIntent
                    })
                    .build();
            //跳转本地圈发布
            Intent paiPublishIntent = new Intent("second", Uri.EMPTY, this, MainActivity.class);
            paiPublishIntent.putExtra("shortcuts","second");
            ShortcutInfo infoPublishPai = new ShortcutInfo.Builder(this, "second")
                    .setShortLabel("go second")
                    .setIcon(Icon.createWithResource(this, R.drawable.icon_shortcut_pai))
                    .setIntents(new Intent[]{
                            paiPublishIntent
                    })
                    .build();
            List<ShortcutInfo> list = new ArrayList<>();

            list.add(infoForumPublish);
            list.add(infoPublishPai);

            if (scManager != null) {
                scManager.setDynamicShortcuts(list);
            }
        }
    }

    private void jumpShortcuts() {
        String shortcuts = getIntent().getStringExtra("shortcuts");
        switch (shortcuts) {
            case "test":
                startActivity(new Intent(this,Test.class));
                break;
            case "second":
                startActivity(new Intent(this,Second.class));
                break;
        }
    }
}

3.ShortcutManager API释义

setRank设置快捷方式的顺序

新建:方法setDynamicShortcuts() 可以添加或替换所有的shortcut;方法addDynamicShortcuts() 来添加新的shortcut到列表中,超过最大个数会报异常

更新:方法updateShortcuts(List shortcutInfoList) 更新已有的动态快捷方式;

删除:方法removeDynamicShortcuts(List shortcutIds) 根据动态快捷方式的ID,删除已有的动态快捷方式;方法removeAllDynamicShortcuts() 删除掉app中所有的动态快捷方式;

List getDynamicShortcuts() : 得到所有的动态shortcuts;


2.静态方式实现

1.在app的AndroidManifest.xml文件中,找到入口Activity添加….指向定义Shortcuts的资源文件。

即红色标记对应的activity ,添加绿色部分代码

<meta-data android:name="android.app.shortcuts"
                android:resource="@xml/shortcuts"/>

2.创建Shortcuts的资源文件,res/xml/shortcuts.xml文件

<?xml version="1.0" encoding="utf-8"?>
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
<!--    shortcut越靠下显示越靠前-->
    <shortcut
        android:enabled="true"
        android:icon="@drawable/icon_shortcut_post"
        android:shortcutId="test"
        android:shortcutShortLabel="@string/test">
        <!--shortcutShortLabel 快捷方式的名称 此处不能直接使用文字-->
        <intent
            android:action="android.intent.action.MAIN"
            android:targetPackage="com.wsx.shortcutsdemo"
            android:targetClass="com.wsx.shortcutsdemo.MainActivity"/>
        <intent
            android:action="android.intent.action.MAIN"
            android:targetPackage="com.wsx.shortcutsdemo"
            android:targetClass="com.wsx.shortcutsdemo.Second"/>
<!--        点击快捷入口会显示Test,返回会显示Second,再返回会显示MainActivity
            即最后一个intent就是快捷方式显示的页面,前面的都是回退栈-->
        <intent
            android:action="android.intent.action.MAIN"
            android:targetPackage="com.wsx.shortcutsdemo"
            android:targetClass="com.wsx.shortcutsdemo.Test"/>
    </shortcut>
    <shortcut
        android:enabled="true"
        android:icon="@drawable/icon_shortcut_pai"
        android:shortcutId="second"
        android:shortcutShortLabel="@string/go_Second">
        <intent
            android:action="android.intent.action.MAIN"
            android:targetPackage="com.wsx.shortcutsdemo"
            android:targetClass="com.wsx.shortcutsdemo.Second"/>
    </shortcut>
</shortcuts>

运行即可,至此,静态方式实现就结束了。

3.属性释义

shortcutId:shortcut唯一标识符,相同的shortcutId会被覆盖。(必设属性)

enable:shortcut是否启用,true启用,false是禁用(若设置为false,不如删除掉该快捷方式)(可选属性)

icon:显示在快捷方式左边的图标。(可选属性)

shortcutShortLabel : shortcut的简要说明,这项是必须的。(必设属性)

shortcutLongLabel:当launcher的空间足够时将会显示shortcut的长文本描述,不宜过长,如果过长或未设置时会显示shortcutShortLabel (可选属性)

intent : 这里定义快捷方式被点击之后将会打开的intent (必设属性)

shortcutDisabledMessage : 当你禁用了shortcut之后,它将不会显示在用户长按应用图标后打开的快捷方式里,但是用户可以把一个快捷方式拖拽到launcher的某个页面成为Pinned Shortcut,被禁用之后这个快捷方式就会显示为灰色,点击这个Pinned Shortcut则会显示一个内容为shortcutDisabledMessage的Toast。(可选属性)