Skip to content

Commit 313667f

Browse files
authored
Develop - Custom app icons (#858)
2 parents c3fa417 + 48e9a1c commit 313667f

38 files changed

Lines changed: 1214 additions & 102 deletions

app/src/main/AndroidManifest.xml

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,118 @@
139139
android:resource="@xml/shortcuts" />
140140
</activity>
141141

142+
<activity-alias
143+
android:name=".MainActivityLegacy"
144+
android:enabled="false"
145+
android:exported="true"
146+
android:icon="@mipmap/ic_launcher_legacy"
147+
android:roundIcon="@mipmap/ic_launcher_legacy_round"
148+
android:label="Essentials"
149+
android:targetActivity=".MainActivity">
150+
<intent-filter>
151+
<action android:name="android.intent.action.MAIN" />
152+
<category android:name="android.intent.category.LAUNCHER" />
153+
</intent-filter>
154+
<intent-filter>
155+
<action android:name="android.intent.action.SEND" />
156+
<category android:name="android.intent.category.DEFAULT" />
157+
<data android:mimeType="text/plain" />
158+
</intent-filter>
159+
<intent-filter>
160+
<action android:name="android.intent.action.VIEW" />
161+
<category android:name="android.intent.category.DEFAULT" />
162+
<category android:name="android.intent.category.BROWSABLE" />
163+
<data android:scheme="geo" />
164+
</intent-filter>
165+
<meta-data
166+
android:name="android.app.shortcuts"
167+
android:resource="@xml/shortcuts" />
168+
</activity-alias>
169+
170+
<activity-alias
171+
android:name=".MainActivityBlack"
172+
android:enabled="false"
173+
android:exported="true"
174+
android:icon="@mipmap/ic_launcher_black"
175+
android:roundIcon="@mipmap/ic_launcher_black_round"
176+
android:label="Essentials"
177+
android:targetActivity=".MainActivity">
178+
<intent-filter>
179+
<action android:name="android.intent.action.MAIN" />
180+
<category android:name="android.intent.category.LAUNCHER" />
181+
</intent-filter>
182+
<intent-filter>
183+
<action android:name="android.intent.action.SEND" />
184+
<category android:name="android.intent.category.DEFAULT" />
185+
<data android:mimeType="text/plain" />
186+
</intent-filter>
187+
<intent-filter>
188+
<action android:name="android.intent.action.VIEW" />
189+
<category android:name="android.intent.category.DEFAULT" />
190+
<category android:name="android.intent.category.BROWSABLE" />
191+
<data android:scheme="geo" />
192+
</intent-filter>
193+
<meta-data
194+
android:name="android.app.shortcuts"
195+
android:resource="@xml/shortcuts" />
196+
</activity-alias>
197+
198+
<activity-alias
199+
android:name=".MainActivityGta"
200+
android:enabled="false"
201+
android:exported="true"
202+
android:icon="@mipmap/ic_launcher_gta"
203+
android:roundIcon="@mipmap/ic_launcher_gta_round"
204+
android:label="Essentials"
205+
android:targetActivity=".MainActivity">
206+
<intent-filter>
207+
<action android:name="android.intent.action.MAIN" />
208+
<category android:name="android.intent.category.LAUNCHER" />
209+
</intent-filter>
210+
<intent-filter>
211+
<action android:name="android.intent.action.SEND" />
212+
<category android:name="android.intent.category.DEFAULT" />
213+
<data android:mimeType="text/plain" />
214+
</intent-filter>
215+
<intent-filter>
216+
<action android:name="android.intent.action.VIEW" />
217+
<category android:name="android.intent.category.DEFAULT" />
218+
<category android:name="android.intent.category.BROWSABLE" />
219+
<data android:scheme="geo" />
220+
</intent-filter>
221+
<meta-data
222+
android:name="android.app.shortcuts"
223+
android:resource="@xml/shortcuts" />
224+
</activity-alias>
225+
226+
<activity-alias
227+
android:name=".MainActivityGoogle"
228+
android:enabled="false"
229+
android:exported="true"
230+
android:icon="@mipmap/ic_launcher_google"
231+
android:roundIcon="@mipmap/ic_launcher_google_round"
232+
android:label="Essentials"
233+
android:targetActivity=".MainActivity">
234+
<intent-filter>
235+
<action android:name="android.intent.action.MAIN" />
236+
<category android:name="android.intent.category.LAUNCHER" />
237+
</intent-filter>
238+
<intent-filter>
239+
<action android:name="android.intent.action.SEND" />
240+
<category android:name="android.intent.category.DEFAULT" />
241+
<data android:mimeType="text/plain" />
242+
</intent-filter>
243+
<intent-filter>
244+
<action android:name="android.intent.action.VIEW" />
245+
<category android:name="android.intent.category.DEFAULT" />
246+
<category android:name="android.intent.category.BROWSABLE" />
247+
<data android:scheme="geo" />
248+
</intent-filter>
249+
<meta-data
250+
android:name="android.app.shortcuts"
251+
android:resource="@xml/shortcuts" />
252+
</activity-alias>
253+
142254
<activity
143255
android:name=".PixelSearchActivity"
144256
android:excludeFromRecents="true"
60.5 KB
Loading

app/src/main/java/com/sameerasw/essentials/data/repository/SettingsRepository.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import com.google.gson.reflect.TypeToken
1616
import com.sameerasw.essentials.domain.HapticFeedbackType
1717
import com.sameerasw.essentials.domain.diy.Action
1818
import com.sameerasw.essentials.domain.diy.ActionGsonAdapter
19+
import com.sameerasw.essentials.domain.model.AppIcon
1920
import com.sameerasw.essentials.domain.model.AppSelection
2021
import com.sameerasw.essentials.domain.model.AppTag
2122
import com.sameerasw.essentials.domain.model.DnsPreset
@@ -238,6 +239,7 @@ class SettingsRepository(
238239
const val KEY_DEVELOPER_MODE_ENABLED = "developer_mode_enabled"
239240
const val KEY_HAPTIC_FEEDBACK_TYPE = "haptic_feedback_type"
240241
const val KEY_DEFAULT_TAB = "default_tab"
242+
const val KEY_APP_ICON = "app_icon_style"
241243
const val KEY_USE_ROOT = "use_root"
242244
const val KEY_PITCH_BLACK_THEME_ENABLED = "pitch_black_theme_enabled"
243245
const val KEY_ENABLE_UNSUPPORTED_FEATURES = "enable_unsupported_features"
@@ -810,6 +812,15 @@ class SettingsRepository(
810812
putString(KEY_DEFAULT_TAB, tab.name)
811813
}
812814

815+
fun getAppIcon(): AppIcon {
816+
val key = prefs.getString(KEY_APP_ICON, AppIcon.DEFAULT.key)
817+
return AppIcon.fromKey(key)
818+
}
819+
820+
fun setAppIcon(appIcon: AppIcon) {
821+
putString(KEY_APP_ICON, appIcon.key)
822+
}
823+
813824
/**
814825
* Executes the get calendar sync selected calendars operation.
815826
* @return The resulting Set<String> data.
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright (c) 2026 sameerasw.com
3+
* License: MIT License
4+
*
5+
* Feature Module: Domain Model
6+
* File: AppIcon.kt
7+
* Description: Model enum representing customizable app launcher icons.
8+
*/
9+
10+
package com.sameerasw.essentials.domain.model
11+
12+
import androidx.annotation.DrawableRes
13+
import androidx.annotation.StringRes
14+
import com.sameerasw.essentials.R
15+
16+
enum class AppIcon(
17+
val key: String,
18+
val aliasName: String,
19+
@StringRes val titleRes: Int,
20+
@DrawableRes val foregroundRes: Int,
21+
) {
22+
DEFAULT(
23+
key = "default",
24+
aliasName = "com.sameerasw.essentials.MainActivity",
25+
titleRes = R.string.app_icon_default,
26+
foregroundRes = R.drawable.ic_launcher_foreground,
27+
),
28+
LEGACY(
29+
key = "legacy",
30+
aliasName = "com.sameerasw.essentials.MainActivityLegacy",
31+
titleRes = R.string.app_icon_legacy,
32+
foregroundRes = R.drawable.ic_launcher_foreground_legacy,
33+
),
34+
BLACK(
35+
key = "black",
36+
aliasName = "com.sameerasw.essentials.MainActivityBlack",
37+
titleRes = R.string.app_icon_black,
38+
foregroundRes = R.drawable.ic_launcher_foreground_black,
39+
),
40+
GTA(
41+
key = "gta",
42+
aliasName = "com.sameerasw.essentials.MainActivityGta",
43+
titleRes = R.string.app_icon_gta,
44+
foregroundRes = R.drawable.ic_launcher_foreground_gta,
45+
),
46+
GOOGLE(
47+
key = "google",
48+
aliasName = "com.sameerasw.essentials.MainActivityGoogle",
49+
titleRes = R.string.app_icon_google,
50+
foregroundRes = R.drawable.ic_launcher_foreground_google,
51+
);
52+
53+
companion object {
54+
fun fromKey(key: String?): AppIcon {
55+
return entries.find { it.key == key } ?: DEFAULT
56+
}
57+
}
58+
}

app/src/main/java/com/sameerasw/essentials/ui/activities/SettingsActivity.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ import com.sameerasw.essentials.ui.core.cards.FeatureCard
9999
import com.sameerasw.essentials.ui.core.cards.IconToggleItem
100100
import com.sameerasw.essentials.ui.core.cards.PermissionCard
101101
import com.sameerasw.essentials.ui.core.containers.RoundedCardContainer
102+
import com.sameerasw.essentials.ui.core.pickers.AppIconPicker
102103
import com.sameerasw.essentials.ui.core.pickers.CrashReportingPicker
103104
import com.sameerasw.essentials.ui.core.pickers.DefaultTabPicker
104105
import com.sameerasw.essentials.ui.core.pickers.LanguagePicker
@@ -647,6 +648,12 @@ fun SettingsContent(
647648
options = availableTabs,
648649
)
649650

651+
val selectedAppIcon by viewModel.selectedAppIcon
652+
AppIconPicker(
653+
selectedIcon = selectedAppIcon,
654+
onIconSelected = { viewModel.setAppIcon(it, context) },
655+
)
656+
650657
IconToggleItem(
651658
iconRes = R.drawable.rounded_touch_app_24,
652659
title = stringResource(R.string.setting_swipe_tabs_title),

0 commit comments

Comments
 (0)