Skip to content

Commit a7b83de

Browse files
committed
Improve dynamic shortcut implementation
1 parent 6523320 commit a7b83de

4 files changed

Lines changed: 58 additions & 45 deletions

File tree

app/src/main/java/com/wstxda/switchai/SwitchAI.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import com.wstxda.switchai.ui.ThemeManager
88
import com.wstxda.switchai.utils.Constants
99

1010
class SwitchAI : Application(), SharedPreferences.OnSharedPreferenceChangeListener {
11-
1211
private val prefs by lazy { PreferenceHelper(this) }
1312
private val shortcuts by lazy { ShortcutManager(this) }
1413

@@ -18,8 +17,7 @@ class SwitchAI : Application(), SharedPreferences.OnSharedPreferenceChangeListen
1817
prefs.getString(Constants.THEME_PREF_KEY, Constants.THEME_SYSTEM)
1918
?: Constants.THEME_SYSTEM
2019
)
21-
22-
shortcuts.updateShortcuts()
20+
shortcuts.updateDynamicShortcuts()
2321
prefs.registerListener(this)
2422
}
2523

@@ -29,6 +27,8 @@ class SwitchAI : Application(), SharedPreferences.OnSharedPreferenceChangeListen
2927
}
3028

3129
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
32-
if (key == Constants.DIGITAL_ASSISTANT_SELECT_PREF_KEY) shortcuts.updateShortcuts()
30+
if (key == Constants.DIGITAL_ASSISTANT_SELECT_PREF_KEY) {
31+
shortcuts.updateDynamicShortcuts()
32+
}
3333
}
3434
}

app/src/main/java/com/wstxda/switchai/activity/BaseActivity.kt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@ import androidx.activity.SystemBarStyle
1010
import androidx.activity.enableEdgeToEdge
1111
import androidx.appcompat.app.AppCompatActivity
1212
import androidx.appcompat.widget.Toolbar
13+
import androidx.core.content.pm.ShortcutManagerCompat
1314
import androidx.core.view.ViewCompat
1415
import androidx.core.view.WindowInsetsCompat
1516

1617
abstract class BaseActivity : AppCompatActivity() {
17-
1818
override fun onCreate(savedInstanceState: Bundle?) {
1919
super.onCreate(savedInstanceState)
2020
enableEdgeToEdgeNoContrast()
21+
handleShortcutUsage()
2122
}
2223

2324
protected fun setupToolbar(toolbar: Toolbar, showBackButton: Boolean = true) {
@@ -60,4 +61,12 @@ abstract class BaseActivity : AppCompatActivity() {
6061
return if (onMenuItemSelected(item)) true
6162
else super.onOptionsItemSelected(item)
6263
}
64+
65+
private fun handleShortcutUsage() {
66+
intent?.getStringExtra(ShortcutManagerCompat.EXTRA_SHORTCUT_ID)?.let { shortcutId ->
67+
if (shortcutId.isNotEmpty()) {
68+
ShortcutManagerCompat.reportShortcutUsed(this, shortcutId)
69+
}
70+
}
71+
}
6372
}

app/src/main/java/com/wstxda/switchai/ui/ShortcutManager.kt

Lines changed: 44 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ package com.wstxda.switchai.ui
22

33
import android.content.Context
44
import android.content.Intent
5-
import android.content.pm.ShortcutInfo
6-
import android.content.pm.ShortcutManager
75
import android.graphics.Canvas
86
import android.graphics.drawable.AdaptiveIconDrawable
9-
import android.graphics.drawable.Icon
107
import android.graphics.drawable.InsetDrawable
118
import androidx.core.content.ContextCompat
9+
import androidx.core.content.pm.ShortcutInfoCompat
10+
import androidx.core.content.pm.ShortcutManagerCompat
1211
import androidx.core.graphics.createBitmap
12+
import androidx.core.graphics.drawable.IconCompat
1313
import androidx.core.graphics.drawable.toDrawable
1414
import com.wstxda.switchai.R
1515
import com.wstxda.switchai.activity.AssistantSelectorActivity
@@ -18,68 +18,73 @@ import com.wstxda.switchai.services.AssistantService
1818
import com.wstxda.switchai.ui.utils.AssistantResourcesManager
1919
import com.wstxda.switchai.utils.Constants
2020

21-
internal class ShortcutManager(private val context: Context) {
22-
21+
class ShortcutManager(private val context: Context) {
2322
private val prefs by lazy { PreferenceHelper(context) }
2423
private val resources by lazy { AssistantResourcesManager(context) }
2524

26-
fun updateShortcuts() {
27-
val manager = context.getSystemService(ShortcutManager::class.java) ?: return
25+
fun updateDynamicShortcuts() {
26+
if (ShortcutManagerCompat.isRateLimitingActive(context)) {
27+
return
28+
}
29+
30+
val assistantShortcut = createShortcut(
31+
id = "assistant_shortcut",
32+
label = prefs.getString(Constants.DIGITAL_ASSISTANT_SELECT_PREF_KEY, null)
33+
?.let { resources.getAssistantName(it) },
34+
longLabel = null,
35+
iconRes = prefs.getString(Constants.DIGITAL_ASSISTANT_SELECT_PREF_KEY, null)
36+
?.let { resources.getAssistantIcon(it) },
37+
target = AssistantService::class.java
38+
)
2839

29-
val shortcuts = listOfNotNull(
30-
createShortcut(
31-
id = "assistant_shortcut",
32-
label = prefs.getString(Constants.DIGITAL_ASSISTANT_SELECT_PREF_KEY, null)
33-
?.let { resources.getAssistantName(it) },
34-
longLabel = null,
35-
iconRes = prefs.getString(Constants.DIGITAL_ASSISTANT_SELECT_PREF_KEY, null)
36-
?.let { resources.getAssistantIcon(it) },
37-
target = AssistantService::class.java
38-
), createShortcut(
39-
id = "assistant_selector_shortcut",
40-
label = context.getString(R.string.assistant_label_selector),
41-
longLabel = context.getString(R.string.assistant_label_long_selector),
42-
iconRes = R.drawable.ic_select,
43-
target = AssistantSelectorActivity::class.java
44-
)
40+
val selectorShortcut = createShortcut(
41+
id = "assistant_selector_shortcut",
42+
label = context.getString(R.string.assistant_label_selector),
43+
longLabel = context.getString(R.string.assistant_label_long_selector),
44+
iconRes = R.drawable.ic_select,
45+
target = AssistantSelectorActivity::class.java
4546
)
4647

47-
manager.dynamicShortcuts = shortcuts
48+
assistantShortcut?.let {
49+
ShortcutManagerCompat.pushDynamicShortcut(context, it)
50+
}
51+
selectorShortcut?.let {
52+
ShortcutManagerCompat.pushDynamicShortcut(context, it)
53+
}
4854
}
4955

5056
private fun createShortcut(
5157
id: String, label: String?, longLabel: String?, iconRes: Int?, target: Class<*>
52-
): ShortcutInfo? {
58+
): ShortcutInfoCompat? {
5359
if (label.isNullOrEmpty() || iconRes == null) return null
5460

55-
val intent = Intent(context, target).setAction(Intent.ACTION_VIEW)
56-
return ShortcutInfo.Builder(context, id).setShortLabel(label)
61+
val intent = Intent(context, target).apply {
62+
action = Intent.ACTION_VIEW
63+
putExtra(ShortcutManagerCompat.EXTRA_SHORTCUT_ID, id)
64+
}
65+
66+
return ShortcutInfoCompat.Builder(context, id).setShortLabel(label)
5767
.setLongLabel(longLabel ?: label).setIcon(createAdaptiveIcon(iconRes)).setIntent(intent)
5868
.build()
5969
}
6070

61-
private fun createAdaptiveIcon(iconRes: Int): Icon {
71+
private fun createAdaptiveIcon(iconRes: Int): IconCompat {
6272
val size = dp108
6373
val inset = (size * 0.50f).toInt()
64-
6574
val background =
6675
ContextCompat.getColor(context, R.color.ic_shortcut_background).toDrawable()
6776
val foreground = ContextCompat.getDrawable(context, iconRes) ?: ContextCompat.getDrawable(
6877
context, R.drawable.ic_assistant_default
6978
)!!
70-
7179
foreground.mutate().setTint(ContextCompat.getColor(context, R.color.ic_shortcut_foreground))
72-
73-
val adaptive = AdaptiveIconDrawable(background, InsetDrawable(foreground, inset))
74-
80+
val insetDrawable = InsetDrawable(foreground, inset)
81+
val adaptiveIcon = AdaptiveIconDrawable(background, insetDrawable)
7582
val bitmap = createBitmap(size, size).apply {
76-
Canvas(this).apply {
77-
adaptive.setBounds(0, 0, size, size)
78-
adaptive.draw(this)
79-
}
83+
val canvas = Canvas(this)
84+
adaptiveIcon.setBounds(0, 0, size, size)
85+
adaptiveIcon.draw(canvas)
8086
}
81-
82-
return Icon.createWithAdaptiveBitmap(bitmap)
87+
return IconCompat.createWithAdaptiveBitmap(bitmap)
8388
}
8489

8590
private val dp108: Int

app/src/main/res/xml/main_preferences.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
app:layout="@layout/preference_material_assistant_cardview"
2121
app:useSimpleSummaryProvider="true" />
2222

23-
2423
<PreferenceCategory
2524
android:layout="@layout/preference_material_category"
2625
android:title="@string/pref_category_selector"

0 commit comments

Comments
 (0)