快捷方式在各类App中现已十分常见,快捷方式能够让用户直达想要运用的功用,例如快速翻开扫一扫、快速翻开健康码等。对此,Android提供了Shortcuts API,本文介绍怎么运用Shortcuts API来完成快捷方式。

Shortcuts API 简介

在Android中,快捷方式通常显现在App的发动器或支撑的助理中(例如Google 助理)。每个快捷方式对应一个或许多个Intent,当用户选中某个快捷方式时,体系会发动对应的Intent

需求留意:

  • 只有包含<action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" />Activity(即发动页)能够具有快捷方式。

  • 不同设备支撑的快捷方式数量或许不同,通常每个发动器最多显现4个快捷方式,能够经过ShortcutManagerCompat.getMaxShortcutCountPerActivity(context)来获取设备支撑的快捷方式数量。

Android 支撑下列三种快捷方式:

  • 静态快捷方式:经过xml装备生成。

  • 动态快捷方式:在运行时经过代码装备生成、更新和移除。

  • 桌面快捷方式:在运行时经过代码装备生成、更新,需求用户同意后才能增加。

下面别离介绍这三种类型的快捷方式怎么完成。

静态快捷方式

快捷方式装备

在res/xml目录下创立shortcuts.xml,如下图:

Android 快捷方式

留意,此方式仅在Android N_MR1(25)以上可用。

文件内容如下:

<?xml version ="1.0" encoding="utf-8"?>
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
    <shortcut
        android:enabled="true"
        android:icon="@drawable/icon_biometrics"
        android:shortcutDisabledMessage="@string/shortcuts_disable_message"
        android:shortcutId="biometrics"
        android:shortcutLongLabel="@string/biometrics_shortcuts_long_label"
        android:shortcutShortLabel="@string/biometrics_shortcuts_short_label">
        <!--快捷方式跳转的页面,有必要装备-->
        <intent
            android:action="android.intent.action.VIEW"
            android:targetClass="com.chenyihong.exampledemo.androidapi.biometrics.BiometricActivity"
            android:targetPackage="com.chenyihong.exampledemo" />
    </shortcut>
</shortcuts>

装备文件中,每个shortcut标签有必要装备的值为android:shortcutIdandroid:shortcutShortLabel,其余为可选装备。

特点名 特点值
android:shortcutId id, 不能设置为字符串资源,有必要装备
android:shortcutShortLabel 简述,主张限制在10个字符以内,字符串资源,有必要装备
android:shortcutLongLabel 详细描述,显现空间足够大时会显现此值,主张限制在25个字符内,字符串资源,非有必要
android:icon 图标,图片的路径或图片资源文件,非有必要
android:enabled 是否可用,布尔值,非有必要
android:shortcutDisabledMessage 用户点击不行用的快捷方式时的提示语,仅在enable为false时生效,字符串资源,非有必要

在Manifest中增加快捷方式装备

AndroidManifest中发动页标签下增加meta-data,如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.chenyihong.exampledemo">
    <application
        ....
        >
        <activity
            android:name=".home.HomeActivity"
            android:exported="true"
            android:screenOrientation="portrait">
            <meta-data
                android:name="android.app.shortcuts"
                android:resource="@xml/shortcuts" />
            <intent-filter>
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.LAUNCHER" />
                <action android:name="android.intent.action.MAIN" />
            </intent-filter>
        </activity>
    </application>
</manifest>

作用如图:

Android 快捷方式

动态快捷方式

能够在运行时经过代码增加或移除动态快捷方式,代码如下:

class ShortcutsActivity : AppCompatActivity() {
    private val locationShortcutId = "location"
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding: LayoutShortcutsActivityBinding = DataBindingUtil.setContentView(this, R.layout.layout_shortcuts_activity)
        binding.includeTitle.tvTitle.text = "Shortcuts Api"
        binding.btnCreateShortcut.setOnClickListener {
            // 创立动态快捷方式
            createDynamicShortcuts()
        }
        binding.btnRemoveShortcut.setOnClickListener {
            // 依据ID移除指定的动态快捷方式
            ShortcutManagerCompat.removeDynamicShortcuts(this, arrayListOf(locationShortcutId))
            // 移除一切的动态快捷方式
            // ShortcutManagerCompat.removeAllDynamicShortcuts(this)
        }
    }
    private fun createDynamicShortcuts() {
        val dynamicShortcuts = ShortcutManagerCompat.getDynamicShortcuts(this)
        val locationShortcut = ShortcutInfoCompat.Builder(this, locationShortcutId)
            .setShortLabel(getString(R.string.location_shortcuts_short_label))
            .setLongLabel(getString(R.string.location_shortcuts_long_label))
            .setDisabledMessage(getString(R.string.shortcuts_disable_message))
            .setIcon(IconCompat.createWithResource(this, R.drawable.icon_location))
            .setIntent(Intent(Intent.ACTION_VIEW).apply {
                component = ComponentName(packageName, GpsSignalActivity::class.java.name)
            })
            .build()
        if (dynamicShortcuts.isEmpty() || !dynamicShortcuts.contains(locationShortcut)) {
            ShortcutManagerCompat.pushDynamicShortcut(this, locationShortcut)
        }
    }
}

作用如图:

桌面快捷方式

运行时创立

桌面快捷方式也十分常见,例如支付宝能够将扫一扫、乘车码等固定到桌面。能够经过如下代码增加桌面快捷方式:

class ShortcutsActivity : AppCompatActivity() {
    private val locationShortcutId = "location"
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ...
        binding.btnCreatePinShortcut.setOnClickListener {
            // 创立桌面快捷方式
            createPinShortcuts()
        }
    }
    private fun createPinShortcuts() {
        // 先判断是否支撑增加桌面快捷方式
        if (ShortcutManagerCompat.isRequestPinShortcutSupported(this)) {
            val pinShortcutInfo = ShortcutInfoCompat.Builder(this, locationShortcutId)
                .setShortLabel(getString(R.string.location_shortcuts_short_label))
                .setLongLabel(getString(R.string.location_shortcuts_long_label))
                .setDisabledMessage(getString(R.string.shortcuts_disable_message))
                .setIcon(IconCompat.createWithResource(this, R.drawable.icon_location))
                .setIntent(Intent(Intent.ACTION_VIEW).apply {
                    component = ComponentName(packageName, GpsSignalActivity::class.java.name)
                })
                .build()
            val pinnedShortcutCallbackIntent = ShortcutManagerCompat.createShortcutResultIntent(this, pinShortcutInfo)
            val successCallback = PendingIntent.getBroadcast(this, 0, pinnedShortcutCallbackIntent, if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) PendingIntent.FLAG_MUTABLE else 0)
            ShortcutManagerCompat.requestPinShortcut(this, pinShortcutInfo, successCallback.intentSender)
        }
    }
}

作用如图:

支撑用户自动创立

能够经过装备创立快捷方式专用的Activity来支撑用户自动创立桌面快捷方式,代码如下:

class CreateCameraShortcutActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding: LayoutCreateShortcutsActivityBinding = DataBindingUtil.setContentView(this, R.layout.layout_create_shortcuts_activity)
        binding.tvTips.text = "Do you want to add the Camera Launcher icon to your home screen?"
        binding.btnAddShortcut.setOnClickListener {
            createPinShortcuts()
        }
        binding.btnReject.setOnClickListener {
            finish()
        }
    }
    private fun createPinShortcuts() {
        if (ShortcutManagerCompat.isRequestPinShortcutSupported(this)) {
            val pinShortcutInfo = ShortcutInfoCompat.Builder(this, "camera")
                .setShortLabel(getString(R.string.camera_shortcuts_short_label))
                .setLongLabel(getString(R.string.camera_shortcuts_long_label))
                .setDisabledMessage(getString(R.string.shortcuts_disable_message))
                .setIcon(IconCompat.createWithResource(this, R.drawable.icon_camera))
                .setIntent(Intent(Intent.ACTION_VIEW).apply {
                    component = ComponentName(packageName, CameraActivity::class.java.name)
                })
                .build()
            val pinnedShortcutCallbackIntent = ShortcutManagerCompat.createShortcutResultIntent(this, pinShortcutInfo)
            setResult(RESULT_OK, pinnedShortcutCallbackIntent)
            finish()
        }
    }
}
// 在 manifest中装备activity
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.chenyihong.exampledemo">
    <application
        ...
        >
        <activity
            android:name=".androidapi.shortcuts.CreateCameraShortcutActivity"
            android:exported="true"
            android:icon="@drawable/icon_camera"
            android:label="@string/label_camera"
            android:theme="@style/DialogActivity">
            <intent-filter>
                <action android:name="android.intent.action.CREATE_SHORTCUT" />
            </intent-filter>
        </activity>
    </application>
</manifest>

作用如图:

翻开多个Activity

每个快捷方式都能够装备多个Intent,当用户选中此快捷方式时,会链式的翻开一切Intent对应的页面,代码如下:

// 静态快捷方式
<?xml version ="1.0" encoding="utf-8"?>
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
    <shortcut
        android:enabled="true"
        android:icon="@drawable/icon_search_48"
        android:shortcutDisabledMessage="@string/shortcuts_disable_message"
        android:shortcutId="search"
        android:shortcutLongLabel="@string/search_shortcuts_long_label"
        android:shortcutShortLabel="@string/search_shortcuts_short_label">
        <intent
            android:action="android.intent.action.VIEW"
            android:targetClass="com.chenyihong.exampledemo.home.HomeActivity"
            android:targetPackage="com.chenyihong.exampledemo" />
        <intent
            android:action="android.intent.action.VIEW"
            android:targetClass="com.chenyihong.exampledemo.androidapi.search.SearchActivity"
            android:targetPackage="com.chenyihong.exampledemo" />
    </shortcut>
</shortcuts>
// 动态快捷方式(桌面快捷方式与此类似)
class ShortcutsActivity : AppCompatActivity() {
    private val locationShortcutId = "location"
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ...
        binding.btnCreateMultipleIntentsShortcut.setOnClickListener {
            createMultipleIntentsDynamicShortcuts()
        }
    }
    private fun createMultipleIntentsDynamicShortcuts() {
        val dynamicShortcuts = ShortcutManagerCompat.getDynamicShortcuts(this)
        val locationShortcut = ShortcutInfoCompat.Builder(this, locationShortcutId)
            .setShortLabel(getString(R.string.location_shortcuts_short_label))
            .setLongLabel(getString(R.string.location_shortcuts_long_label))
            .setDisabledMessage(getString(R.string.shortcuts_disable_message))
            .setIcon(IconCompat.createWithResource(this, R.drawable.icon_location))
            .setIntents(arrayOf(
                Intent(Intent.ACTION_VIEW).apply {
                    component = ComponentName(packageName, HomeActivity::class.java.name)
                },
                Intent(Intent.ACTION_VIEW).apply {
                    component = ComponentName(packageName, GpsSignalActivity::class.java.name)
                }))
            .build()
        if (dynamicShortcuts.isEmpty() || !dynamicShortcuts.contains(locationShortcut)) {
            ShortcutManagerCompat.pushDynamicShortcut(this, locationShortcut)
        }
    }
}

作用如图:

更新快捷方式

启用和禁用

在需求的时分,例如当定位不行用时禁止定位快捷方式,定位康复可用时重新启用快捷方式,代码如下:

class ShortcutsActivity : AppCompatActivity() {
    private val locationShortcutId = "location"
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ...
        binding.btnEnableShortcut.setOnClickListener {
            // 启用快捷方式
            ShortcutManagerCompat.enableShortcuts(this, arrayListOf(ShortcutInfoCompat.Builder(this, locationShortcutId)
                .setShortLabel(getString(R.string.location_shortcuts_short_label))
                .setLongLabel(getString(R.string.location_shortcuts_long_label))
                .setDisabledMessage(getString(R.string.shortcuts_disable_message))
                .setIcon(IconCompat.createWithResource(this, R.drawable.icon_location))
                .setIntent(Intent(Intent.ACTION_VIEW).apply {
                    component = ComponentName(packageName, GpsSignalActivity::class.java.name)
                })
                .build()
            ))
        }
        binding.btnDisableShortcut.setOnClickListener {
            // 禁用快捷方式,需求传入禁用原因,当用户点击时会显现
            ShortcutManagerCompat.disableShortcuts(this, arrayListOf(locationShortcutId), "Location function is currently unavailable")
        }
    }
}

作用如图:

留意,依据作用图能够看到,禁用后动态快捷方式会被移除,再次启用后不会自动增加,需求手动增加。

更新快捷方式的款式

在需求的时分,例如用户切换言语时能够更新快捷方式的款式,显现匹配当前言语的文案,代码如下:

class ShortcutsActivity : AppCompatActivity() {
    private val locationShortcutId = "location"
    private var english = true
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ...
        binding.btnUpdateShortcut.setOnClickListener {
            updateDynamicShortcuts()
        }
    }
    private fun updateDynamicShortcuts() {
        english = !english
        ShortcutManagerCompat.updateShortcuts(this, arrayListOf(
            ShortcutInfoCompat.Builder(this, locationShortcutId)
                .setShortLabel(if (english) getString(R.string.location_shortcuts_short_label) else "运用定位")
                .setLongLabel(if (english) getString(R.string.location_shortcuts_long_label) else "经过定位获取方位信息")
                .setDisabledMessage(if (english) getString(R.string.shortcuts_disable_message) else "此快捷方式不行用")
                .setIcon(IconCompat.createWithResource(this, R.drawable.icon_location))
                .setIntent(Intent(Intent.ACTION_VIEW).apply {
                    component = ComponentName(packageName, GpsSignalActivity::class.java.name)
                })
                .build()
        ))
    }
}

作用如图:

留意,经过代码只能更新动态快捷方式和桌面快捷方式,假如更新了静态快捷方式会崩溃。

示例

整合之后做了个示例Demo,代码如下:

// 快捷方式装备文件
<?xml version ="1.0" encoding="utf-8"?>
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
    <shortcut
        android:enabled="true"
        android:icon="@drawable/icon_biometrics"
        android:shortcutDisabledMessage="@string/shortcuts_disable_message"
        android:shortcutId="biometrics"
        android:shortcutLongLabel="@string/biometrics_shortcuts_long_label"
        android:shortcutShortLabel="@string/biometrics_shortcuts_short_label">
        <!--快捷方式跳转的页面,有必要装备-->
        <intent
            android:action="android.intent.action.VIEW"
            android:targetClass="com.chenyihong.exampledemo.androidapi.biometrics.BiometricActivity"
            android:targetPackage="com.chenyihong.exampledemo" />
    </shortcut>
    <shortcut
        android:enabled="true"
        android:icon="@drawable/icon_search_48"
        android:shortcutDisabledMessage="@string/shortcuts_disable_message"
        android:shortcutId="search"
        android:shortcutLongLabel="@string/search_shortcuts_long_label"
        android:shortcutShortLabel="@string/search_shortcuts_short_label">
        <intent
            android:action="android.intent.action.VIEW"
            android:targetClass="com.chenyihong.exampledemo.home.HomeActivity"
            android:targetPackage="com.chenyihong.exampledemo" />
        <intent
            android:action="android.intent.action.VIEW"
            android:targetClass="com.chenyihong.exampledemo.androidapi.search.SearchActivity"
            android:targetPackage="com.chenyihong.exampledemo" />
    </shortcut>
</shortcuts>
// 弹窗款式的Activity Style
<resources xmlns:tools="http://schemas.android.com/tools">
    <style name="DialogActivity" parent="Theme.MaterialComponents.DayNight.NoActionBar">
        <!-- 背景色通明度 -->
        <item name="android:windowBackground">@android:color/transparent</item>
        <!-- 无标题 -->
        <item name="android:windowNoTitle">true</item>
        <!-- 半通明,设置为false无通明作用 -->
        <item name="android:windowIsTranslucent">true</item>
        <!-- 模糊 -->
        <item name="android:backgroundDimEnabled">true</item>
        <!-- 窗口款式Dialog -->
        <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
    </style>
</resources>
// Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.chenyihong.exampledemo">
    <application
        ...
        >
        <activity
            android:name=".home.HomeActivity"
            android:exported="true"
            android:screenOrientation="portrait">
            <meta-data
                android:name="android.app.shortcuts"
                android:resource="@xml/shortcuts" />
            <intent-filter>
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.LAUNCHER" />
                <action android:name="android.intent.action.MAIN" />
            </intent-filter>
        </activity>
        <activity
            android:name=".androidapi.shortcuts.ShortcutsActivity"
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".androidapi.shortcuts.CreateCameraShortcutActivity"
            android:exported="true"
            android:icon="@drawable/icon_camera"
            android:label="@string/label_camera"
            android:theme="@style/DialogActivity">
            <intent-filter>
                <action android:name="android.intent.action.CREATE_SHORTCUT" />
            </intent-filter>
        </activity>
        <activity
            android:name=".androidapi.shortcuts.CreateLocationShortcutActivity"
            android:exported="true"
            android:icon="@drawable/icon_location"
            android:label="@string/label_location"
            android:theme="@style/DialogActivity">
            <intent-filter>
                <action android:name="android.intent.action.CREATE_SHORTCUT" />
            </intent-filter>
        </activity>
    </application>
</manifest>
// 示例Activity
class ShortcutsActivity : AppCompatActivity() {
    private val locationShortcutId = "location"
    private var english = true
    @SuppressLint("SetTextI18n")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding: LayoutShortcutsActivityBinding = DataBindingUtil.setContentView(this, R.layout.layout_shortcuts_activity)
        binding.includeTitle.tvTitle.text = "Shortcuts Api"
        binding.btnCreateShortcut.setOnClickListener {
            // 创立动态快捷方式
            createDynamicShortcuts()
        }
        binding.btnRemoveShortcut.setOnClickListener {
            // 依据ID移除指定的动态快捷方式
            ShortcutManagerCompat.removeDynamicShortcuts(this, arrayListOf(locationShortcutId))
            // 依据ID移除指定的动态快捷方式
            // ShortcutManagerCompat.removeAllDynamicShortcuts(this)
        }
        binding.btnCreatePinShortcut.setOnClickListener {
            // 创立桌面快捷方式
            createPinShortcuts()
        }
        binding.btnCreateMultipleIntentsShortcut.setOnClickListener {
            createMultipleIntentsDynamicShortcuts()
        }
        binding.btnEnableShortcut.setOnClickListener {
            // 启用快捷方式
            ShortcutManagerCompat.enableShortcuts(this, arrayListOf(ShortcutInfoCompat.Builder(this, locationShortcutId)
                .setShortLabel(getString(R.string.location_shortcuts_short_label))
                .setLongLabel(getString(R.string.location_shortcuts_long_label))
                .setDisabledMessage(getString(R.string.shortcuts_disable_message))
                .setIcon(IconCompat.createWithResource(this, R.drawable.icon_location))
                .setIntent(Intent(Intent.ACTION_VIEW).apply {
                    component = ComponentName(packageName, GpsSignalActivity::class.java.name)
                })
                .build()
            ))
        }
        binding.btnDisableShortcut.setOnClickListener {
            // 禁用快捷方式,需求传入禁用原因,当用户点击时会显现
            ShortcutManagerCompat.disableShortcuts(this, arrayListOf(locationShortcutId), "Location function is currently unavailable")
        }
        binding.btnUpdateShortcut.setOnClickListener {
            // 更新快捷方式
            updateDynamicShortcuts()
        }
    }
    private fun createDynamicShortcuts() {
        val dynamicShortcuts = ShortcutManagerCompat.getDynamicShortcuts(this)
        val locationShortcut = ShortcutInfoCompat.Builder(this, locationShortcutId)
            .setShortLabel(getString(R.string.location_shortcuts_short_label))
            .setLongLabel(getString(R.string.location_shortcuts_long_label))
            .setDisabledMessage(getString(R.string.shortcuts_disable_message))
            .setIcon(IconCompat.createWithResource(this, R.drawable.icon_location))
            .setIntent(Intent(Intent.ACTION_VIEW).apply {
                component = ComponentName(packageName, GpsSignalActivity::class.java.name)
            })
            .build()
        if (dynamicShortcuts.isEmpty() || !dynamicShortcuts.contains(locationShortcut)) {
            ShortcutManagerCompat.pushDynamicShortcut(this, locationShortcut)
        }
    }
    private fun createMultipleIntentsDynamicShortcuts() {
        val dynamicShortcuts = ShortcutManagerCompat.getDynamicShortcuts(this)
        val locationShortcut = ShortcutInfoCompat.Builder(this, locationShortcutId)
            .setShortLabel(getString(R.string.location_shortcuts_short_label))
            .setLongLabel(getString(R.string.location_shortcuts_long_label))
            .setDisabledMessage(getString(R.string.shortcuts_disable_message))
            .setIcon(IconCompat.createWithResource(this, R.drawable.icon_location))
            .setIntents(arrayOf(
                Intent(Intent.ACTION_VIEW).apply {
                    component = ComponentName(packageName, HomeActivity::class.java.name)
                },
                Intent(Intent.ACTION_VIEW).apply {
                    component = ComponentName(packageName, GpsSignalActivity::class.java.name)
                }))
            .build()
        if (dynamicShortcuts.isEmpty() || !dynamicShortcuts.contains(locationShortcut)) {
            ShortcutManagerCompat.pushDynamicShortcut(this, locationShortcut)
        }
    }
    private fun updateDynamicShortcuts() {
        english = !english
        ShortcutManagerCompat.updateShortcuts(this, arrayListOf(
            ShortcutInfoCompat.Builder(this, locationShortcutId)
                .setShortLabel(if (english) getString(R.string.location_shortcuts_short_label) else "运用定位")
                .setLongLabel(if (english) getString(R.string.location_shortcuts_long_label) else "经过定位获取方位信息")
                .setDisabledMessage(if (english) getString(R.string.shortcuts_disable_message) else "此快捷方式不行用")
                .setIcon(IconCompat.createWithResource(this, R.drawable.icon_location))
                .setIntent(Intent(Intent.ACTION_VIEW).apply {
                    component = ComponentName(packageName, GpsSignalActivity::class.java.name)
                })
                .build()
        ))
    }
    private fun createPinShortcuts() {
        // 先判断是否支撑增加桌面快捷方式
        if (ShortcutManagerCompat.isRequestPinShortcutSupported(this)) {
            val pinShortcutInfo = ShortcutInfoCompat.Builder(this, locationShortcutId)
                .setShortLabel(getString(R.string.location_shortcuts_short_label))
                .setLongLabel(getString(R.string.location_shortcuts_long_label))
                .setDisabledMessage(getString(R.string.shortcuts_disable_message))
                .setIcon(IconCompat.createWithResource(this, R.drawable.icon_location))
                .setIntent(Intent(Intent.ACTION_VIEW).apply {
                    component = ComponentName(packageName, GpsSignalActivity::class.java.name)
                })
                .build()
            val pinnedShortcutCallbackIntent = ShortcutManagerCompat.createShortcutResultIntent(this, pinShortcutInfo)
            val successCallback = PendingIntent.getBroadcast(this, 0, pinnedShortcutCallbackIntent, if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) PendingIntent.FLAG_MUTABLE else 0)
            ShortcutManagerCompat.requestPinShortcut(this, pinShortcutInfo, successCallback.intentSender)
        }
    }
}
// 支撑用户创立桌面快捷方式
class CreateCameraShortcutActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding: LayoutCreateShortcutsActivityBinding = DataBindingUtil.setContentView(this, R.layout.layout_create_shortcuts_activity)
        binding.tvTips.text = "Do you want to add the Camera Launcher icon to your home screen?"
        binding.btnAddShortcut.setOnClickListener {
            createPinShortcuts()
        }
        binding.btnReject.setOnClickListener {
            finish()
        }
    }
    private fun createPinShortcuts() {
        if (ShortcutManagerCompat.isRequestPinShortcutSupported(this)) {
            val pinShortcutInfo = ShortcutInfoCompat.Builder(this, "camera")
                .setShortLabel(getString(R.string.camera_shortcuts_short_label))
                .setLongLabel(getString(R.string.camera_shortcuts_long_label))
                .setDisabledMessage(getString(R.string.shortcuts_disable_message))
                .setIcon(IconCompat.createWithResource(this, R.drawable.icon_camera))
                .setIntent(Intent(Intent.ACTION_VIEW).apply {
                    component = ComponentName(packageName, CameraActivity::class.java.name)
                })
                .build()
            val pinnedShortcutCallbackIntent = ShortcutManagerCompat.createShortcutResultIntent(this, pinShortcutInfo)
            setResult(RESULT_OK, pinnedShortcutCallbackIntent)
            finish()
        }
    }
}
// 支撑用户创立桌面快捷方式
class CreateLocationShortcutActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding: LayoutCreateShortcutsActivityBinding = DataBindingUtil.setContentView(this, R.layout.layout_create_shortcuts_activity)
        binding.tvTips.text = "Do you want to add the Location Launcher icon to your home screen?"
        binding.btnAddShortcut.setOnClickListener {
            createPinShortcuts()
        }
        binding.btnReject.setOnClickListener {
            finish()
        }
    }
    private fun createPinShortcuts() {
        if (ShortcutManagerCompat.isRequestPinShortcutSupported(this)) {
            val pinShortcutInfo = ShortcutInfoCompat.Builder(this, "location")
                .setShortLabel(getString(R.string.location_shortcuts_short_label))
                .setLongLabel(getString(R.string.location_shortcuts_long_label))
                .setDisabledMessage(getString(R.string.shortcuts_disable_message))
                .setIcon(IconCompat.createWithResource(this, R.drawable.icon_location))
                .setIntent(Intent(Intent.ACTION_VIEW).apply {
                    component = ComponentName(packageName, GpsSignalActivity::class.java.name)
                })
                .build()
            val pinnedShortcutCallbackIntent = ShortcutManagerCompat.createShortcutResultIntent(this, pinShortcutInfo)
            setResult(RESULT_OK, pinnedShortcutCallbackIntent)
            finish()
        }
    }
}

ExampleDemo github

ExampleDemo gitee