Compare commits

...

3 commits

Author SHA1 Message Date
Too Late (bot)
162d31cc4d
Merge c5c81e1dc1 into 6d385e4e87 2025-01-22 16:09:24 +01:00
6d385e4e87
use TextClock instead of custom solution 2025-01-22 02:17:46 +01:00
785e024ddb
basic support for private space (#98)
* add an action to toggle private space lock
* hide apps from private space if private space is locked
2025-01-22 01:44:51 +01:00
13 changed files with 170 additions and 65 deletions

View file

@ -1,5 +1,9 @@
package de.jrpie.android.launcher package de.jrpie.android.launcher
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.SharedPreferences import android.content.SharedPreferences
import android.content.pm.LauncherApps import android.content.pm.LauncherApps
import android.content.pm.ShortcutInfo import android.content.pm.ShortcutInfo
@ -7,6 +11,7 @@ import android.os.AsyncTask
import android.os.Build import android.os.Build
import android.os.Build.VERSION_CODES import android.os.Build.VERSION_CODES
import android.os.UserHandle import android.os.UserHandle
import androidx.core.content.ContextCompat
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import de.jrpie.android.launcher.actions.TorchManager import de.jrpie.android.launcher.actions.TorchManager
@ -19,6 +24,14 @@ import de.jrpie.android.launcher.preferences.resetPreferences
class Application : android.app.Application() { class Application : android.app.Application() {
val apps = MutableLiveData<List<DetailedAppInfo>>() val apps = MutableLiveData<List<DetailedAppInfo>>()
private val profileAvailabilityBroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
// TODO: only update specific apps
// use Intent.EXTRA_USER
loadApps()
}
}
// TODO: only update specific apps // TODO: only update specific apps
private val launcherAppsCallback = object : LauncherApps.Callback() { private val launcherAppsCallback = object : LauncherApps.Callback() {
override fun onPackageRemoved(p0: String?, p1: UserHandle?) { override fun onPackageRemoved(p0: String?, p1: UserHandle?) {
@ -107,6 +120,21 @@ class Application : android.app.Application() {
val launcherApps = getSystemService(LAUNCHER_APPS_SERVICE) as LauncherApps val launcherApps = getSystemService(LAUNCHER_APPS_SERVICE) as LauncherApps
launcherApps.registerCallback(launcherAppsCallback) launcherApps.registerCallback(launcherAppsCallback)
if (Build.VERSION.SDK_INT >= VERSION_CODES.N) {
val filter = IntentFilter().also {
if (Build.VERSION.SDK_INT >= VERSION_CODES.VANILLA_ICE_CREAM) {
it.addAction(Intent.ACTION_PROFILE_AVAILABLE)
it.addAction(Intent.ACTION_PROFILE_UNAVAILABLE)
} else {
it.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE)
it.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE)
}
}
ContextCompat.registerReceiver(this, profileAvailabilityBroadcastReceiver, filter,
ContextCompat.RECEIVER_EXPORTED
)
}
loadApps() loadApps()
} }

View file

@ -18,6 +18,7 @@ import de.jrpie.android.launcher.actions.Action
import de.jrpie.android.launcher.actions.Gesture import de.jrpie.android.launcher.actions.Gesture
import de.jrpie.android.launcher.apps.AppInfo import de.jrpie.android.launcher.apps.AppInfo
import de.jrpie.android.launcher.apps.DetailedAppInfo import de.jrpie.android.launcher.apps.DetailedAppInfo
import de.jrpie.android.launcher.preferences.LauncherPreferences
import de.jrpie.android.launcher.ui.tutorial.TutorialActivity import de.jrpie.android.launcher.ui.tutorial.TutorialActivity
@ -30,31 +31,36 @@ const val REQUEST_SET_DEFAULT_HOME = 42
const val LOG_TAG = "Launcher" const val LOG_TAG = "Launcher"
fun setDefaultHomeScreen(context: Context, checkDefault: Boolean = false) { fun isDefaultHomeScreen(context: Context): Boolean {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
if (checkDefault
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
&& context is Activity
) {
val roleManager = context.getSystemService(RoleManager::class.java) val roleManager = context.getSystemService(RoleManager::class.java)
if (!roleManager.isRoleHeld(RoleManager.ROLE_HOME)) { return roleManager.isRoleHeld(RoleManager.ROLE_HOME)
context.startActivityForResult( } else {
roleManager.createRequestRoleIntent(RoleManager.ROLE_HOME),
REQUEST_SET_DEFAULT_HOME
)
}
return
}
if (checkDefault) {
val testIntent = Intent(Intent.ACTION_MAIN) val testIntent = Intent(Intent.ACTION_MAIN)
testIntent.addCategory(Intent.CATEGORY_HOME) testIntent.addCategory(Intent.CATEGORY_HOME)
val defaultHome = testIntent.resolveActivity(context.packageManager)?.packageName val defaultHome = testIntent.resolveActivity(context.packageManager)?.packageName
if (defaultHome == context.packageName) { return defaultHome == context.packageName
// Launcher is already the default home app
return
}
} }
}
fun setDefaultHomeScreen(context: Context, checkDefault: Boolean = false) {
if (checkDefault && isDefaultHomeScreen(context)) {
// Launcher is already the default home app
return
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
&& context is Activity
&& checkDefault // using role manager only works when µLauncher is not already the default.
) {
val roleManager = context.getSystemService(RoleManager::class.java)
context.startActivityForResult(
roleManager.createRequestRoleIntent(RoleManager.ROLE_HOME),
REQUEST_SET_DEFAULT_HOME
)
return
}
val intent = Intent(Settings.ACTION_HOME_SETTINGS) val intent = Intent(Settings.ACTION_HOME_SETTINGS)
context.startActivity(intent) context.startActivity(intent)
} }
@ -94,6 +100,21 @@ fun getApps(packageManager: PackageManager, context: Context): MutableList<Detai
// TODO: shortcuts - launcherApps.getShortcuts() // TODO: shortcuts - launcherApps.getShortcuts()
val users = userManager.userProfiles val users = userManager.userProfiles
for (user in users) { for (user in users) {
// don't load apps from a user profile that has quiet mode enabled
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
if (userManager.isQuietModeEnabled(user)) {
// hide paused apps
if (LauncherPreferences.apps().hidePausedApps()) {
continue
}
// hide apps from private space
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM &&
launcherApps.getLauncherUserInfo(user)?.userType == UserManager.USER_TYPE_PROFILE_PRIVATE
) {
continue
}
}
}
launcherApps.getActivityList(null, user).forEach { launcherApps.getActivityList(null, user).forEach {
loadList.add(DetailedAppInfo(it)) loadList.add(DetailedAppInfo(it))
} }

View file

@ -1,17 +1,22 @@
package de.jrpie.android.launcher.actions package de.jrpie.android.launcher.actions
import android.content.ActivityNotFoundException
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.LauncherApps
import android.graphics.Rect import android.graphics.Rect
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.media.AudioManager import android.media.AudioManager
import android.os.Build import android.os.Build
import android.os.SystemClock import android.os.SystemClock
import android.os.UserManager
import android.provider.Settings
import android.view.KeyEvent import android.view.KeyEvent
import android.widget.Toast import android.widget.Toast
import de.jrpie.android.launcher.Application import de.jrpie.android.launcher.Application
import de.jrpie.android.launcher.R import de.jrpie.android.launcher.R
import de.jrpie.android.launcher.apps.AppFilter import de.jrpie.android.launcher.apps.AppFilter
import de.jrpie.android.launcher.isDefaultHomeScreen
import de.jrpie.android.launcher.preferences.LauncherPreferences import de.jrpie.android.launcher.preferences.LauncherPreferences
import de.jrpie.android.launcher.ui.list.ListActivity import de.jrpie.android.launcher.ui.list.ListActivity
import de.jrpie.android.launcher.ui.settings.SettingsActivity import de.jrpie.android.launcher.ui.settings.SettingsActivity
@ -33,7 +38,8 @@ enum class LauncherAction(
val id: String, val id: String,
val label: Int, val label: Int,
val icon: Int, val icon: Int,
val launch: (Context) -> Unit val launch: (Context) -> Unit,
val available: (Context) -> Boolean = { true }
) : Action { ) : Action {
SETTINGS( SETTINGS(
"settings", "settings",
@ -53,6 +59,13 @@ enum class LauncherAction(
R.drawable.baseline_favorite_24, R.drawable.baseline_favorite_24,
{ context -> openAppsList(context, true) } { context -> openAppsList(context, true) }
), ),
TOGGLE_PRIVATE_SPACE_LOCK(
"toggle_private_space_lock",
R.string.list_other_toggle_private_space_lock,
R.drawable.baseline_security_24,
::togglePrivateSpaceLock,
available = { Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM }
),
VOLUME_UP( VOLUME_UP(
"volume_up", "volume_up",
R.string.list_other_volume_up, R.string.list_other_volume_up,
@ -207,6 +220,46 @@ private fun expandNotificationsPanel(context: Context) {
} }
} }
private fun togglePrivateSpaceLock(context: Context) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.VANILLA_ICE_CREAM) {
Toast.makeText(
context,
context.getString(R.string.alert_requires_android_v),
Toast.LENGTH_LONG
).show()
return
}
val userManager = context.getSystemService(Context.USER_SERVICE) as UserManager
val launcherApps = context.getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps
val privateSpaceUser = userManager.userProfiles.firstOrNull { u ->
launcherApps.getLauncherUserInfo(u)?.userType == UserManager.USER_TYPE_PROFILE_PRIVATE
}
if (privateSpaceUser == null) {
Toast.makeText(context, context.getString(R.string.toast_private_space_not_available), Toast.LENGTH_LONG).show()
if (!isDefaultHomeScreen(context)) {
Toast.makeText(context, context.getString(R.string.toast_private_space_default_home_screen), Toast.LENGTH_LONG).show()
return
}
try {
context.startActivity(Intent(Settings.ACTION_PRIVACY_SETTINGS))
} catch (_: ActivityNotFoundException) {}
return
}
if (userManager.isQuietModeEnabled(privateSpaceUser)) {
userManager.requestQuietModeEnabled(false, privateSpaceUser)
Toast.makeText(
context,
context.getString(R.string.toast_private_space_unlocked),
Toast.LENGTH_LONG
).show()
return
}
userManager.requestQuietModeEnabled(true, privateSpaceUser)
Toast.makeText(context, context.getString(R.string.toast_private_space_locked), Toast.LENGTH_LONG).show()
}
private fun expandSettingsPanel(context: Context) { private fun expandSettingsPanel(context: Context) {
/* https://stackoverflow.com/a/31898506 */ /* https://stackoverflow.com/a/31898506 */
try { try {
@ -260,6 +313,7 @@ private class LauncherActionSerializer : KSerializer<LauncherAction> {
) { ) {
element("value", String.serializer().descriptor) element("value", String.serializer().descriptor)
} }
override fun deserialize(decoder: Decoder): LauncherAction { override fun deserialize(decoder: Decoder): LauncherAction {
val s = decoder.decodeStructure(descriptor) { val s = decoder.decodeStructure(descriptor) {
decodeElementIndex(descriptor) decodeElementIndex(descriptor)

View file

@ -5,8 +5,8 @@ import java.util.Set;
import de.jrpie.android.launcher.R; import de.jrpie.android.launcher.R;
import de.jrpie.android.launcher.actions.lock.LockMethod; import de.jrpie.android.launcher.actions.lock.LockMethod;
import de.jrpie.android.launcher.preferences.serialization.SetAppInfoPreferenceSerializer;
import de.jrpie.android.launcher.preferences.serialization.MapAppInfoStringPreferenceSerializer; import de.jrpie.android.launcher.preferences.serialization.MapAppInfoStringPreferenceSerializer;
import de.jrpie.android.launcher.preferences.serialization.SetAppInfoPreferenceSerializer;
import de.jrpie.android.launcher.preferences.theme.Background; import de.jrpie.android.launcher.preferences.theme.Background;
import de.jrpie.android.launcher.preferences.theme.ColorTheme; import de.jrpie.android.launcher.preferences.theme.ColorTheme;
import de.jrpie.android.launcher.preferences.theme.Font; import de.jrpie.android.launcher.preferences.theme.Font;
@ -29,6 +29,7 @@ import eu.jonahbauer.android.preference.annotations.Preferences;
@Preference(name = "hidden", type = Set.class, serializer = SetAppInfoPreferenceSerializer.class), @Preference(name = "hidden", type = Set.class, serializer = SetAppInfoPreferenceSerializer.class),
@Preference(name = "custom_names", type = HashMap.class, serializer = MapAppInfoStringPreferenceSerializer.class), @Preference(name = "custom_names", type = HashMap.class, serializer = MapAppInfoStringPreferenceSerializer.class),
@Preference(name = "hide_bound_apps", type = boolean.class, defaultValue = "false"), @Preference(name = "hide_bound_apps", type = boolean.class, defaultValue = "false"),
@Preference(name = "hide_paused_apps", type = boolean.class, defaultValue = "false"),
}), }),
@PreferenceGroup(name = "list", prefix = "settings_list_", suffix = "_key", value = { @PreferenceGroup(name = "list", prefix = "settings_list_", suffix = "_key", value = {
@Preference(name = "layout", type = ListLayout.class, defaultValue = "DEFAULT") @Preference(name = "layout", type = ListLayout.class, defaultValue = "DEFAULT")

View file

@ -2,8 +2,8 @@ package de.jrpie.android.launcher.preferences.theme
import android.content.Context import android.content.Context
import android.content.res.Resources import android.content.res.Resources
import de.jrpie.android.launcher.R
import com.google.android.material.color.DynamicColors import com.google.android.material.color.DynamicColors
import de.jrpie.android.launcher.R
@Suppress("unused") @Suppress("unused")
enum class ColorTheme( enum class ColorTheme(

View file

@ -3,7 +3,6 @@ package de.jrpie.android.launcher.ui
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.SharedPreferences import android.content.SharedPreferences
import android.content.res.Resources import android.content.res.Resources
import android.os.AsyncTask
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.util.DisplayMetrics import android.util.DisplayMetrics
@ -20,13 +19,8 @@ import de.jrpie.android.launcher.actions.Action
import de.jrpie.android.launcher.actions.Gesture import de.jrpie.android.launcher.actions.Gesture
import de.jrpie.android.launcher.actions.LauncherAction import de.jrpie.android.launcher.actions.LauncherAction
import de.jrpie.android.launcher.databinding.HomeBinding import de.jrpie.android.launcher.databinding.HomeBinding
import de.jrpie.android.launcher.openTutorial
import de.jrpie.android.launcher.preferences.LauncherPreferences import de.jrpie.android.launcher.preferences.LauncherPreferences
import de.jrpie.android.launcher.preferences.migratePreferencesToNewVersion
import de.jrpie.android.launcher.preferences.resetPreferences
import de.jrpie.android.launcher.ui.tutorial.TutorialActivity import de.jrpie.android.launcher.ui.tutorial.TutorialActivity
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale import java.util.Locale
import java.util.Timer import java.util.Timer
import kotlin.concurrent.fixedRateTimer import kotlin.concurrent.fixedRateTimer
@ -69,8 +63,6 @@ class HomeActivity : UIObject, AppCompatActivity(),
private lateinit var mDetector: GestureDetectorCompat private lateinit var mDetector: GestureDetectorCompat
// timers
private var clockTimer = Timer()
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super<AppCompatActivity>.onCreate(savedInstanceState) super<AppCompatActivity>.onCreate(savedInstanceState)
@ -104,30 +96,24 @@ class HomeActivity : UIObject, AppCompatActivity(),
} }
private fun updateClock() { private fun initClock() {
clockTimer.cancel()
val locale = Locale.getDefault() val locale = Locale.getDefault()
val dateVisible = LauncherPreferences.clock().dateVisible() val dateVisible = LauncherPreferences.clock().dateVisible()
val timeVisible = LauncherPreferences.clock().timeVisible() val timeVisible = LauncherPreferences.clock().timeVisible()
var dateFMT = "yyyy-MM-dd" var dateFMT = "yyyy-MM-dd"
var timeFMT = "HH:mm" var timeFMT = "HH:mm"
val period = 100L
if (LauncherPreferences.clock().showSeconds()) { if (LauncherPreferences.clock().showSeconds()) {
timeFMT += ":ss" timeFMT += ":ss"
} }
/*
I thought about adding an option to show microseconds as well ( timeFMT += ".SSS" ).
However setting period ot 1L (or even 10L) causes high CPU load,
so that doesn't seem to be a good idea.
*/
if (LauncherPreferences.clock().localized()) { if (LauncherPreferences.clock().localized()) {
dateFMT = android.text.format.DateFormat.getBestDateTimePattern(locale, dateFMT) dateFMT = android.text.format.DateFormat.getBestDateTimePattern(locale, dateFMT)
timeFMT = android.text.format.DateFormat.getBestDateTimePattern(locale, timeFMT) timeFMT = android.text.format.DateFormat.getBestDateTimePattern(locale, timeFMT)
} }
var upperFormat = SimpleDateFormat(dateFMT, locale) var upperFormat = dateFMT
var lowerFormat = SimpleDateFormat(timeFMT, locale) var lowerFormat = timeFMT
var upperVisible = dateVisible var upperVisible = dateVisible
var lowerVisible = timeVisible var lowerVisible = timeVisible
@ -142,21 +128,10 @@ class HomeActivity : UIObject, AppCompatActivity(),
binding.homeUpperView.setTextColor(LauncherPreferences.clock().color()) binding.homeUpperView.setTextColor(LauncherPreferences.clock().color())
binding.homeLowerView.setTextColor(LauncherPreferences.clock().color()) binding.homeLowerView.setTextColor(LauncherPreferences.clock().color())
binding.homeLowerView.format24Hour = lowerFormat
clockTimer = fixedRateTimer("clockTimer", true, 0L, period) { binding.homeUpperView.format24Hour = upperFormat
this@HomeActivity.runOnUiThread { binding.homeLowerView.format12Hour = lowerFormat
if (lowerVisible) { binding.homeUpperView.format12Hour = upperFormat
val t = lowerFormat.format(Date())
if (binding.homeLowerView.text != t)
binding.homeLowerView.text = t
}
if (upperVisible) {
val d = upperFormat.format(Date())
if (binding.homeUpperView.text != d)
binding.homeUpperView.text = d
}
}
}
} }
override fun getTheme(): Resources.Theme { override fun getTheme(): Resources.Theme {
@ -176,12 +151,7 @@ class HomeActivity : UIObject, AppCompatActivity(),
edgeWidth = LauncherPreferences.enabled_gestures().edgeSwipeEdgeWidth() / 100f edgeWidth = LauncherPreferences.enabled_gestures().edgeSwipeEdgeWidth() / 100f
updateClock() initClock()
}
override fun onPause() {
super.onPause()
clockTimer.cancel()
} }
override fun onDestroy() { override fun onDestroy() {

View file

@ -23,7 +23,8 @@ import de.jrpie.android.launcher.ui.list.forGesture
class OtherRecyclerAdapter(val activity: Activity) : class OtherRecyclerAdapter(val activity: Activity) :
RecyclerView.Adapter<OtherRecyclerAdapter.ViewHolder>() { RecyclerView.Adapter<OtherRecyclerAdapter.ViewHolder>() {
private val othersList: Array<LauncherAction> = LauncherAction.values() private val othersList: Array<LauncherAction> =
LauncherAction.entries.filter { it.isAvailable(activity) }.toTypedArray()
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
View.OnClickListener { View.OnClickListener {

View file

@ -40,6 +40,11 @@ class SettingsFragmentLauncher : PreferenceFragmentCompat() {
) )
val lightTheme = LauncherPreferences.theme().colorTheme() == ColorTheme.LIGHT val lightTheme = LauncherPreferences.theme().colorTheme() == ColorTheme.LIGHT
background?.isVisible = !lightTheme background?.isVisible = !lightTheme
val hidePausedApps = findPreference<androidx.preference.Preference>(
LauncherPreferences.apps().keys().hidePausedApps()
)
hidePausedApps?.isVisible = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
} }
override fun onStart() { override fun onStart() {

View file

@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp">
<path
android:fillColor="?android:textColor"
android:pathData="M12,1L3,5v6c0,5.55 3.84,10.74 9,12 5.16,-1.26 9,-6.45 9,-12L21,5l-9,-4zM12,11.99h7c-0.53,4.12 -3.28,7.79 -7,8.94L12,12L5,12L5,6.3l7,-3.11v8.8z" />
</vector>

View file

@ -10,7 +10,7 @@
android:fitsSystemWindows="true" android:fitsSystemWindows="true"
tools:context=".ui.HomeActivity"> tools:context=".ui.HomeActivity">
<TextView <TextClock
android:id="@+id/home_upper_view" android:id="@+id/home_upper_view"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -23,7 +23,7 @@
app:layout_constraintVertical_bias="0.45" app:layout_constraintVertical_bias="0.45"
tools:text="2024-12-24" /> tools:text="2024-12-24" />
<TextView <TextClock
android:id="@+id/home_lower_view" android:id="@+id/home_lower_view"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View file

@ -13,6 +13,7 @@
<string name="settings_apps_hidden_key" translatable="false">apps.hidden</string> <string name="settings_apps_hidden_key" translatable="false">apps.hidden</string>
<string name="settings_apps_custom_names_key" translatable="false">apps.custom_names</string> <string name="settings_apps_custom_names_key" translatable="false">apps.custom_names</string>
<string name="settings_apps_hide_bound_apps_key" translatable="false">apps.hide_bound_apps</string> <string name="settings_apps_hide_bound_apps_key" translatable="false">apps.hide_bound_apps</string>
<string name="settings_apps_hide_paused_apps_key" translatable="false">apps.hide_paused_apps</string>
<string name="settings_list_layout_key" translatable="false">list.layout</string> <string name="settings_list_layout_key" translatable="false">list.layout</string>
<string name="settings_general_choose_home_screen_key" translatable="false">general.select_launcher</string> <string name="settings_general_choose_home_screen_key" translatable="false">general.select_launcher</string>

View file

@ -145,6 +145,7 @@
<string name="settings_launcher_section_apps">Apps</string> <string name="settings_launcher_section_apps">Apps</string>
<string name="settings_apps_hidden">Hidden apps</string> <string name="settings_apps_hidden">Hidden apps</string>
<string name="settings_apps_hide_bound_apps">Don\'t show apps that are bound to a gesture in the app list</string> <string name="settings_apps_hide_bound_apps">Don\'t show apps that are bound to a gesture in the app list</string>
<string name="settings_apps_hide_paused_apps">Hide paused apps</string>
<string name="settings_list_layout">Layout of app list</string> <string name="settings_list_layout">Layout of app list</string>
<string name="settings_list_layout_item_default">Default</string> <string name="settings_list_layout_item_default">Default</string>
@ -207,6 +208,7 @@
<string name="list_other_settings">µLauncher Settings</string> <string name="list_other_settings">µLauncher Settings</string>
<string name="list_other_list">All Applications</string> <string name="list_other_list">All Applications</string>
<string name="list_other_list_favorites">Favorite Applications</string> <string name="list_other_list_favorites">Favorite Applications</string>
<string name="list_other_toggle_private_space_lock">Toggle Private Space Lock</string>
<string name="list_other_volume_up">Music: Louder</string> <string name="list_other_volume_up">Music: Louder</string>
<string name="list_other_volume_down">Music: Quieter</string> <string name="list_other_volume_down">Music: Quieter</string>
<string name="list_other_track_next">Music: Next</string> <string name="list_other_track_next">Music: Next</string>
@ -245,6 +247,7 @@
<string name="ic_menu_alt">More options</string> <string name="ic_menu_alt">More options</string>
<string name="alert_cant_expand_status_bar_panel">Error: Can\'t expand status bar. This action is using functionality that is not part of the published Android API. Unfortunately, it does not seem to work on your device.</string> <string name="alert_cant_expand_status_bar_panel">Error: Can\'t expand status bar. This action is using functionality that is not part of the published Android API. Unfortunately, it does not seem to work on your device.</string>
<string name="alert_requires_android_m">This functionality requires Android 6.0 or later.</string> <string name="alert_requires_android_m">This functionality requires Android 6.0 or later.</string>
<string name="alert_requires_android_v">This functionality requires Android 15.0 or later.</string>
<string name="snackbar_app_hidden">App hidden. You can make it visible again in settings.</string> <string name="snackbar_app_hidden">App hidden. You can make it visible again in settings.</string>
<string name="undo">Undo</string> <string name="undo">Undo</string>
<string name="list_other_expand_settings_panel">Quick Settings</string> <string name="list_other_expand_settings_panel">Quick Settings</string>
@ -255,6 +258,10 @@
<string name="alert_torch_access_exception">Error: Can\'t access torch.</string> <string name="alert_torch_access_exception">Error: Can\'t access torch.</string>
<string name="alert_lock_screen_failed">Error: Failed to lock screen. (If you just upgraded the app, try to disable and re-enable the accessibility service in phone settings)</string> <string name="alert_lock_screen_failed">Error: Failed to lock screen. (If you just upgraded the app, try to disable and re-enable the accessibility service in phone settings)</string>
<string name="toast_accessibility_service_not_enabled">μLauncher\'s accessibility service is not enabled. Please enable it in settings</string> <string name="toast_accessibility_service_not_enabled">μLauncher\'s accessibility service is not enabled. Please enable it in settings</string>
<string name="toast_private_space_locked">Private space locked</string>
<string name="toast_private_space_unlocked">Private space unlocked</string>
<string name="toast_private_space_not_available">Private space is not available</string>
<string name="toast_private_space_default_home_screen">µLauncher needs to be the default home screen to access private space.</string>
<string name="toast_lock_screen_not_supported">Error: Locking the screen using accessibility is not supported on this device. Please use device admin instead.</string> <string name="toast_lock_screen_not_supported">Error: Locking the screen using accessibility is not supported on this device. Please use device admin instead.</string>
<string name="accessibility_service_name">µLauncher - lock screen</string> <string name="accessibility_service_name">µLauncher - lock screen</string>
<string name="accessibility_service_description"> <string name="accessibility_service_description">

View file

@ -145,6 +145,11 @@
android:title="@string/settings_apps_hide_bound_apps" android:title="@string/settings_apps_hide_bound_apps"
android:defaultValue="false" /> android:defaultValue="false" />
<SwitchPreference
android:key="@string/settings_apps_hide_paused_apps_key"
android:title="@string/settings_apps_hide_paused_apps"
android:defaultValue="false" />
<DropDownPreference <DropDownPreference
android:key="@string/settings_list_layout_key" android:key="@string/settings_list_layout_key"
android:title="@string/settings_list_layout" android:title="@string/settings_list_layout"