Android 桌面快捷方式實(shí)現(xiàn)實(shí)例詳解
Shortcuts API 簡(jiǎn)介
快捷方式在各類App中已經(jīng)十分常見(jiàn),快捷方式可以讓用戶直達(dá)想要使用的功能,例如快速打開(kāi)掃一掃、快速打開(kāi)健康碼等。對(duì)此,Android提供了Shortcuts API,本文介紹如何使用Shortcuts API來(lái)實(shí)現(xiàn)快捷方式。
在Android中,快捷方式通常顯示在App的啟動(dòng)器或支持的助理中(例如Google 助理)。每個(gè)快捷方式對(duì)應(yīng)一個(gè)或者多個(gè)Intent,當(dāng)用戶選中某個(gè)快捷方式時(shí),系統(tǒng)會(huì)啟動(dòng)對(duì)應(yīng)的Intent。
需要注意:
- 只有包含
<action android:name="android.intent.action.MAIN" />和<category android:name="android.intent.category.LAUNCHER" />的Activity(即啟動(dòng)頁(yè))可以擁有快捷方式。 - 不同設(shè)備支持的快捷方式數(shù)量可能不同,通常每個(gè)啟動(dòng)器最多顯示4個(gè)快捷方式,可以通過(guò)
ShortcutManagerCompat.getMaxShortcutCountPerActivity(context)來(lái)獲取設(shè)備支持的快捷方式數(shù)量。
Android 支持下列三種快捷方式:
- 靜態(tài)快捷方式:通過(guò)xml配置生成。
- 動(dòng)態(tài)快捷方式:在運(yùn)行時(shí)通過(guò)代碼配置生成、更新和移除。
- 桌面快捷方式:在運(yùn)行時(shí)通過(guò)代碼配置生成、更新,需要用戶同意后才能添加。
下面分別介紹這三種類型的快捷方式如何實(shí)現(xiàn)。
靜態(tài)快捷方式
快捷方式配置
在res/xml目錄下創(chuàng)建shortcuts.xml,如下圖:

注意,此方式僅在Android N_MR1(25)以上可用。
文件內(nèi)容如下:
<?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">
<!--快捷方式跳轉(zhuǎn)的頁(yè)面,必須配置-->
<intent
android:action="android.intent.action.VIEW"
android:targetClass="com.chenyihong.exampledemo.androidapi.biometrics.BiometricActivity"
android:targetPackage="com.chenyihong.exampledemo" />
</shortcut>
</shortcuts>
配置文件中,每個(gè)shortcut標(biāo)簽必須配置的值為android:shortcutId和android:shortcutShortLabel,其余為可選配置。
| 屬性名 | 屬性值 |
|---|---|
| android:shortcutId | id, 不能設(shè)置為字符串資源,必須配置 |
| android:shortcutShortLabel | 簡(jiǎn)述,建議限制在10個(gè)字符以內(nèi),字符串資源,必須配置 |
| android:shortcutLongLabel | 詳細(xì)描述,顯示空間足夠大時(shí)會(huì)顯示此值,建議限制在25個(gè)字符內(nèi),字符串資源,非必須 |
| android:icon | 圖標(biāo),圖片的路徑或圖片資源文件,非必須 |
| android:enabled | 是否可用,布爾值,非必須 |
| android:shortcutDisabledMessage | 用戶點(diǎn)擊不可用的快捷方式時(shí)的提示語(yǔ),僅在enable為false時(shí)生效,字符串資源,非必須 |
在Manifest中添加快捷方式配置
在AndroidManifest中啟動(dòng)頁(yè)標(biāo)簽下添加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>
效果如圖:

動(dòng)態(tài)快捷方式
可以在運(yùn)行時(shí)通過(guò)代碼添加或移除動(dòng)態(tài)快捷方式,代碼如下:
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 {
// 創(chuàng)建動(dòng)態(tài)快捷方式
createDynamicShortcuts()
}
binding.btnRemoveShortcut.setOnClickListener {
// 根據(jù)ID移除指定的動(dòng)態(tài)快捷方式
ShortcutManagerCompat.removeDynamicShortcuts(this, arrayListOf(locationShortcutId))
// 移除所有的動(dòng)態(tài)快捷方式
// 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)
}
}
}
效果如圖:

桌面快捷方式
運(yùn)行時(shí)創(chuàng)建
桌面快捷方式也十分常見(jiàn),例如支付寶可以將掃一掃、乘車碼等固定到桌面??梢酝ㄟ^(guò)如下代碼添加桌面快捷方式:
class ShortcutsActivity : AppCompatActivity() {
private val locationShortcutId = "location"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
binding.btnCreatePinShortcut.setOnClickListener {
// 創(chuàng)建桌面快捷方式
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)
}
}
}
效果如圖:

支持用戶主動(dòng)創(chuàng)建
可以通過(guò)配置創(chuàng)建快捷方式專用的Activity來(lái)支持用戶主動(dòng)創(chuàng)建桌面快捷方式,代碼如下:
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>
效果如圖:

打開(kāi)多個(gè)Activity
每個(gè)快捷方式都可以配置多個(gè)Intent,當(dāng)用戶選中此快捷方式時(shí),會(huì)鏈?zhǔn)降拇蜷_(kāi)所有Intent對(duì)應(yīng)的頁(yè)面,代碼如下:
// 靜態(tài)快捷方式
<?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>
// 動(dòng)態(tài)快捷方式(桌面快捷方式與此類似)
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)
}
}
}
效果如圖:

更新快捷方式
啟用和禁用
在需要的時(shí)候,例如當(dāng)定位不可用時(shí)禁止定位快捷方式,定位恢復(fù)可用時(shí)重新啟用快捷方式,代碼如下:
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 {
// 禁用快捷方式,需要傳入禁用原因,當(dāng)用戶點(diǎn)擊時(shí)會(huì)顯示
ShortcutManagerCompat.disableShortcuts(this, arrayListOf(locationShortcutId), "Location function is currently unavailable")
}
}
}
效果如圖:

注意,根據(jù)效果圖可以看到,禁用后動(dòng)態(tài)快捷方式會(huì)被移除,再次啟用后不會(huì)自動(dòng)添加,需要手動(dòng)添加。
更新快捷方式的樣式
在需要的時(shí)候,例如用戶切換語(yǔ)言時(shí)可以更新快捷方式的樣式,顯示匹配當(dāng)前語(yǔ)言的文案,代碼如下:
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 "通過(guò)定位獲取位置信息")
.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()
))
}
}
效果如圖:

注意,通過(guò)代碼只能更新動(dòng)態(tài)快捷方式和桌面快捷方式,如果更新了靜態(tài)快捷方式會(huì)崩潰。
示例
整合之后做了個(gè)示例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">
<!--快捷方式跳轉(zhuǎn)的頁(yè)面,必須配置-->
<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>
<!-- 無(wú)標(biāo)題 -->
<item name="android:windowNoTitle">true</item>
<!-- 半透明,設(shè)置為false無(wú)透明效果 -->
<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 {
// 創(chuàng)建動(dòng)態(tài)快捷方式
createDynamicShortcuts()
}
binding.btnRemoveShortcut.setOnClickListener {
// 根據(jù)ID移除指定的動(dòng)態(tài)快捷方式
ShortcutManagerCompat.removeDynamicShortcuts(this, arrayListOf(locationShortcutId))
// 根據(jù)ID移除指定的動(dòng)態(tài)快捷方式
// ShortcutManagerCompat.removeAllDynamicShortcuts(this)
}
binding.btnCreatePinShortcut.setOnClickListener {
// 創(chuàng)建桌面快捷方式
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 {
// 禁用快捷方式,需要傳入禁用原因,當(dāng)用戶點(diǎn)擊時(shí)會(huì)顯示
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 "通過(guò)定位獲取位置信息")
.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)
}
}
}
// 支持用戶創(chuàng)建桌面快捷方式
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()
}
}
}
// 支持用戶創(chuàng)建桌面快捷方式
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()
}
}
}
以上就是Android 快捷方式實(shí)現(xiàn)實(shí)例詳解的詳細(xì)內(nèi)容,更多關(guān)于Android 桌面快捷方式的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Flutter中嵌入Android 原生TextView實(shí)例教程
這篇文章主要給大家介紹了關(guān)于Flutter中嵌入Android 原生TextView的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09
Android編程之內(nèi)存溢出解決方案(OOM)實(shí)例總結(jié)
這篇文章主要介紹了Android編程之內(nèi)存溢出解決方案(OOM),結(jié)合實(shí)例實(shí)例總結(jié)分析了Android編程過(guò)程中常見(jiàn)的內(nèi)存溢出情況與對(duì)應(yīng)的解決方法,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11
Android開(kāi)發(fā)教程之ContentProvider數(shù)據(jù)存儲(chǔ)
這篇文章主要介紹了Android開(kāi)發(fā)教程之ContentProvider數(shù)據(jù)存儲(chǔ)的相關(guān)資料,需要的朋友可以參考下2016-12-12
Android-自定義控件之ListView下拉刷新的實(shí)現(xiàn)
本篇文章主要介紹了Android-自定義控件之ListView下拉刷新示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-02-02
Android實(shí)現(xiàn)簡(jiǎn)易登陸注冊(cè)邏輯的實(shí)例代碼
在android的應(yīng)用中越來(lái)越多的包含了網(wǎng)絡(luò)互動(dòng)功能,這就帶來(lái)了注冊(cè),登陸賬號(hào)功能,這篇文章主要給大家介紹了關(guān)于Android實(shí)現(xiàn)簡(jiǎn)易登陸注冊(cè)邏輯的相關(guān)資料,需要的朋友可以參考下2021-06-06
Android應(yīng)用更新之自動(dòng)檢測(cè)版本及自動(dòng)升級(jí)
這篇文章主要為大家詳細(xì)介紹了Android應(yīng)用更新之自動(dòng)檢測(cè)版本及自動(dòng)升級(jí),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-09-09
Android實(shí)現(xiàn)京東App分類頁(yè)面效果
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)京東App分類頁(yè)面效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-02-02
Android使用ViewPager實(shí)現(xiàn)類似laucher左右拖動(dòng)效果
這篇文章主要為大家詳細(xì)介紹了Android使用ViewPager實(shí)現(xiàn)類似laucher左右拖動(dòng)效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05

