diff --git a/app/src/main/java/de/jrpie/android/launcher/Application.kt b/app/src/main/java/de/jrpie/android/launcher/Application.kt index e3e5f7c..6e924c2 100644 --- a/app/src/main/java/de/jrpie/android/launcher/Application.kt +++ b/app/src/main/java/de/jrpie/android/launcher/Application.kt @@ -1,5 +1,9 @@ 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.pm.LauncherApps import android.content.pm.ShortcutInfo @@ -7,6 +11,7 @@ import android.os.AsyncTask import android.os.Build import android.os.Build.VERSION_CODES import android.os.UserHandle +import androidx.core.content.ContextCompat import androidx.lifecycle.MutableLiveData import androidx.preference.PreferenceManager import de.jrpie.android.launcher.actions.TorchManager @@ -19,6 +24,14 @@ import de.jrpie.android.launcher.preferences.resetPreferences class Application : android.app.Application() { val apps = MutableLiveData>() + 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 private val launcherAppsCallback = object : LauncherApps.Callback() { override fun onPackageRemoved(p0: String?, p1: UserHandle?) { @@ -107,6 +120,21 @@ class Application : android.app.Application() { val launcherApps = getSystemService(LAUNCHER_APPS_SERVICE) as LauncherApps 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() } diff --git a/app/src/main/java/de/jrpie/android/launcher/Functions.kt b/app/src/main/java/de/jrpie/android/launcher/Functions.kt index e8d3851..48b5028 100644 --- a/app/src/main/java/de/jrpie/android/launcher/Functions.kt +++ b/app/src/main/java/de/jrpie/android/launcher/Functions.kt @@ -18,6 +18,7 @@ import de.jrpie.android.launcher.actions.Action import de.jrpie.android.launcher.actions.Gesture import de.jrpie.android.launcher.apps.AppInfo import de.jrpie.android.launcher.apps.DetailedAppInfo +import de.jrpie.android.launcher.preferences.LauncherPreferences import de.jrpie.android.launcher.ui.tutorial.TutorialActivity @@ -30,31 +31,36 @@ const val REQUEST_SET_DEFAULT_HOME = 42 const val LOG_TAG = "Launcher" -fun setDefaultHomeScreen(context: Context, checkDefault: Boolean = false) { - - if (checkDefault - && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q - && context is Activity - ) { +fun isDefaultHomeScreen(context: Context): Boolean { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { val roleManager = context.getSystemService(RoleManager::class.java) - if (!roleManager.isRoleHeld(RoleManager.ROLE_HOME)) { - context.startActivityForResult( - roleManager.createRequestRoleIntent(RoleManager.ROLE_HOME), - REQUEST_SET_DEFAULT_HOME - ) - } - return - } - - if (checkDefault) { + return roleManager.isRoleHeld(RoleManager.ROLE_HOME) + } else { val testIntent = Intent(Intent.ACTION_MAIN) testIntent.addCategory(Intent.CATEGORY_HOME) val defaultHome = testIntent.resolveActivity(context.packageManager)?.packageName - if (defaultHome == context.packageName) { - // Launcher is already the default home app - return - } + return defaultHome == context.packageName } +} + +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) context.startActivity(intent) } @@ -94,6 +100,21 @@ fun getApps(packageManager: PackageManager, context: Context): MutableList= 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 { loadList.add(DetailedAppInfo(it)) } diff --git a/app/src/main/java/de/jrpie/android/launcher/actions/LauncherAction.kt b/app/src/main/java/de/jrpie/android/launcher/actions/LauncherAction.kt index 3c641ff..2eddf16 100644 --- a/app/src/main/java/de/jrpie/android/launcher/actions/LauncherAction.kt +++ b/app/src/main/java/de/jrpie/android/launcher/actions/LauncherAction.kt @@ -1,17 +1,22 @@ package de.jrpie.android.launcher.actions +import android.content.ActivityNotFoundException import android.content.Context import android.content.Intent +import android.content.pm.LauncherApps import android.graphics.Rect import android.graphics.drawable.Drawable import android.media.AudioManager import android.os.Build import android.os.SystemClock +import android.os.UserManager +import android.provider.Settings import android.view.KeyEvent import android.widget.Toast import de.jrpie.android.launcher.Application import de.jrpie.android.launcher.R 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.ui.list.ListActivity import de.jrpie.android.launcher.ui.settings.SettingsActivity @@ -33,7 +38,8 @@ enum class LauncherAction( val id: String, val label: Int, val icon: Int, - val launch: (Context) -> Unit + val launch: (Context) -> Unit, + val available: (Context) -> Boolean = { true } ) : Action { SETTINGS( "settings", @@ -53,6 +59,13 @@ enum class LauncherAction( R.drawable.baseline_favorite_24, { 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", 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) { /* https://stackoverflow.com/a/31898506 */ try { @@ -260,6 +313,7 @@ private class LauncherActionSerializer : KSerializer { ) { element("value", String.serializer().descriptor) } + override fun deserialize(decoder: Decoder): LauncherAction { val s = decoder.decodeStructure(descriptor) { decodeElementIndex(descriptor) diff --git a/app/src/main/java/de/jrpie/android/launcher/preferences/LauncherPreferences$Config.java b/app/src/main/java/de/jrpie/android/launcher/preferences/LauncherPreferences$Config.java index 640e6ce..98496ce 100644 --- a/app/src/main/java/de/jrpie/android/launcher/preferences/LauncherPreferences$Config.java +++ b/app/src/main/java/de/jrpie/android/launcher/preferences/LauncherPreferences$Config.java @@ -5,8 +5,8 @@ import java.util.Set; import de.jrpie.android.launcher.R; 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.SetAppInfoPreferenceSerializer; import de.jrpie.android.launcher.preferences.theme.Background; import de.jrpie.android.launcher.preferences.theme.ColorTheme; 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 = "custom_names", type = HashMap.class, serializer = MapAppInfoStringPreferenceSerializer.class), @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 = { @Preference(name = "layout", type = ListLayout.class, defaultValue = "DEFAULT") diff --git a/app/src/main/java/de/jrpie/android/launcher/preferences/theme/ColorTheme.kt b/app/src/main/java/de/jrpie/android/launcher/preferences/theme/ColorTheme.kt index 8cef124..816d94f 100644 --- a/app/src/main/java/de/jrpie/android/launcher/preferences/theme/ColorTheme.kt +++ b/app/src/main/java/de/jrpie/android/launcher/preferences/theme/ColorTheme.kt @@ -2,8 +2,8 @@ package de.jrpie.android.launcher.preferences.theme import android.content.Context import android.content.res.Resources -import de.jrpie.android.launcher.R import com.google.android.material.color.DynamicColors +import de.jrpie.android.launcher.R @Suppress("unused") enum class ColorTheme( diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/HomeActivity.kt b/app/src/main/java/de/jrpie/android/launcher/ui/HomeActivity.kt index 5633113..1d5381d 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/HomeActivity.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/HomeActivity.kt @@ -3,7 +3,6 @@ package de.jrpie.android.launcher.ui import android.annotation.SuppressLint import android.content.SharedPreferences import android.content.res.Resources -import android.os.AsyncTask import android.os.Build import android.os.Bundle 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.LauncherAction 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.migratePreferencesToNewVersion -import de.jrpie.android.launcher.preferences.resetPreferences import de.jrpie.android.launcher.ui.tutorial.TutorialActivity -import java.text.SimpleDateFormat -import java.util.Date import java.util.Locale import java.util.Timer import kotlin.concurrent.fixedRateTimer @@ -69,8 +63,6 @@ class HomeActivity : UIObject, AppCompatActivity(), private lateinit var mDetector: GestureDetectorCompat - // timers - private var clockTimer = Timer() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -104,30 +96,24 @@ class HomeActivity : UIObject, AppCompatActivity(), } - private fun updateClock() { - clockTimer.cancel() + private fun initClock() { val locale = Locale.getDefault() val dateVisible = LauncherPreferences.clock().dateVisible() val timeVisible = LauncherPreferences.clock().timeVisible() var dateFMT = "yyyy-MM-dd" var timeFMT = "HH:mm" - val period = 100L if (LauncherPreferences.clock().showSeconds()) { 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()) { dateFMT = android.text.format.DateFormat.getBestDateTimePattern(locale, dateFMT) timeFMT = android.text.format.DateFormat.getBestDateTimePattern(locale, timeFMT) } - var upperFormat = SimpleDateFormat(dateFMT, locale) - var lowerFormat = SimpleDateFormat(timeFMT, locale) + var upperFormat = dateFMT + var lowerFormat = timeFMT var upperVisible = dateVisible var lowerVisible = timeVisible @@ -142,21 +128,10 @@ class HomeActivity : UIObject, AppCompatActivity(), binding.homeUpperView.setTextColor(LauncherPreferences.clock().color()) binding.homeLowerView.setTextColor(LauncherPreferences.clock().color()) - - clockTimer = fixedRateTimer("clockTimer", true, 0L, period) { - this@HomeActivity.runOnUiThread { - if (lowerVisible) { - 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 - } - } - } + binding.homeLowerView.format24Hour = lowerFormat + binding.homeUpperView.format24Hour = upperFormat + binding.homeLowerView.format12Hour = lowerFormat + binding.homeUpperView.format12Hour = upperFormat } override fun getTheme(): Resources.Theme { @@ -176,12 +151,7 @@ class HomeActivity : UIObject, AppCompatActivity(), edgeWidth = LauncherPreferences.enabled_gestures().edgeSwipeEdgeWidth() / 100f - updateClock() - } - - override fun onPause() { - super.onPause() - clockTimer.cancel() + initClock() } override fun onDestroy() { diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/list/other/OtherRecyclerAdapter.kt b/app/src/main/java/de/jrpie/android/launcher/ui/list/other/OtherRecyclerAdapter.kt index ddfcfd1..97d1c84 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/list/other/OtherRecyclerAdapter.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/list/other/OtherRecyclerAdapter.kt @@ -23,7 +23,8 @@ import de.jrpie.android.launcher.ui.list.forGesture class OtherRecyclerAdapter(val activity: Activity) : RecyclerView.Adapter() { - private val othersList: Array = LauncherAction.values() + private val othersList: Array = + LauncherAction.entries.filter { it.isAvailable(activity) }.toTypedArray() inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener { diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/settings/launcher/SettingsFragmentLauncher.kt b/app/src/main/java/de/jrpie/android/launcher/ui/settings/launcher/SettingsFragmentLauncher.kt index 0b054ce..a8efb43 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/settings/launcher/SettingsFragmentLauncher.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/settings/launcher/SettingsFragmentLauncher.kt @@ -40,6 +40,11 @@ class SettingsFragmentLauncher : PreferenceFragmentCompat() { ) val lightTheme = LauncherPreferences.theme().colorTheme() == ColorTheme.LIGHT background?.isVisible = !lightTheme + + val hidePausedApps = findPreference( + LauncherPreferences.apps().keys().hidePausedApps() + ) + hidePausedApps?.isVisible = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N } override fun onStart() { diff --git a/app/src/main/res/drawable/baseline_security_24.xml b/app/src/main/res/drawable/baseline_security_24.xml new file mode 100644 index 0000000..3c260ff --- /dev/null +++ b/app/src/main/res/drawable/baseline_security_24.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/app/src/main/res/layout/home.xml b/app/src/main/res/layout/home.xml index 5f34412..f59b211 100644 --- a/app/src/main/res/layout/home.xml +++ b/app/src/main/res/layout/home.xml @@ -10,7 +10,7 @@ android:fitsSystemWindows="true" tools:context=".ui.HomeActivity"> - - Prenez quelques instants pour apprendre à utiliser ce \'launcher\' ! Concept Launcher vous offre un environnement minimaliste, efficace et sans distraction.\n\nIl ne vous coûte rien, ne contient aucune publicité, ne recueille pas de données personnelles. - L\'application est open-source (sous licence MIT) et disponible sur GitHub !\n\nN\'hésitez pas à y faire un tour ! + L\'application est open-source (sous licence MIT) et disponible sur GitHub !\n\nN\'hésitez pas à y faire un tour ! Utilisation Sur votre écran d\'accueil vous ne trouverez rien d\'autre que la date et l\'heure : rien qui pourrait vous distraire. Vous pouvez ouvrir des applications en effectuant des mouvelents latéraux sur l\'écran ou en appuyant sur les touches de volume. Vous pourrez en définir le comportement dans le panneau suivant. @@ -115,12 +115,7 @@ Voici quelques paramètres par défaut. Vous pouvez les changer dès à présent : Vous pourrez bien sûr tout reconfigurer plus tard. C\'est parti ! - Vous êtes prêt à démarrer ! -\n -\nJ\'espère que cette application vous sera précieuse ! -\n -\n- Finn M Glas -\n(le développeur originel) et Josia (le développeur de la branche μLauncher) + Vous êtes prêt à démarrer ! \n \nJ\'espère que cette application vous sera précieuse ! \n \n- Finn M Glas \n(le développeur originel) et Josia (le développeur de la branche μLauncher) Démarrer Réglages Plus d\'options @@ -154,8 +149,7 @@ Applications Favorites Appli cachée. Vous pouvez l\'afficher à nouveau depuis les réglages. Défaire - Erreur : impossible d\'afficher la barre de statut. -\nCette action utilise des fonctionalités qui ne sont pas officiellement dans l\'API Android. Malheuresement ça ne semble pas fonctionner sur votre appareil. + Erreur : impossible d\'afficher la barre de statut. \nCette action utilise des fonctionalités qui ne sont pas officiellement dans l\'API Android. Malheuresement ça ne semble pas fonctionner sur votre appareil. Réglages rapides Basculer l\'état de la lampe Dynamique diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 9505db7..1f05552 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -118,8 +118,8 @@ Tutorial Tire alguns segundos para aprender a usar este Launcher! Conceito - O Launcher foi projetado para ser minimalista, eficiente e livre de distrações.\n\nEle é livre de pagamentos, anúncios e serviços de rastreamento. - O aplicativo é de código aberto (licença MIT) e está disponível no GitHub!\n\nNão deixe de conferir o repositório! + O Launcher foi criado para ser minimalista, eficiente e livre de distrações. Ele é livre de pagamentos, anúncios e serviços de rastreamento. + O app é de código aberto (licença MIT) e está disponível no GitHub! Não deixe de conferir o repositório! Uso Sua tela inicial contém a data e hora local. Sem distração. Você pode iniciar seus aplicativos com um toque único ou pressionando um botão. Escolha algumas ações no próximo slide. @@ -127,13 +127,12 @@ Selecionamos alguns aplicativos padrão para você. Se quiser, você pode alterá-los agora: Você também pode alterar suas escolhas mais tarde. Vamos lá! - Você está pronto para começar!\n\nEspero que isso seja de grande valor para você!\n\n- Finn (que criou o Launcher)\n\te Josia (que fez algumas melhorias e mantém o fork μLauncher) + Tá todo pronto para começar! Espero que isso seja de grande valor para você! - Finn (que criou o Launcher) \te Josia (que fez algumas melhorias e tb mantém o fork do μLauncher) Começar Configurações Mais opções Remover dos favoritos - Erro: Não foi possível expandir a barra de status. -\nEssa ação usa uma funcionalidade que não faz parte da API do Android publicada. Infelizmente, ela não vai funcionar no seu dispositivo. + Erro: Não foi possível expandir a barra de status. Essa ação usa uma funcionalidade que não faz parte da API do Android publicado. Infelizmente, isto não vai funcionar no seu dispositivo. Fundo (lista de apps e configurações) Fonte Ícones de apps monocromáticos @@ -257,4 +256,6 @@ Pesquise na internet Ao buscar na lista de apps toque no Enter para iniciar uma pesquisa na internet. Busca (sem inicialização automática) + Licenças de código aberto + Licenças de código aberto \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 1ca8ba6..2add7e6 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -64,9 +64,7 @@ 选择应用 花几秒时间学下咋用这个启动器吧! 概念 - 该应用是开源的(MIT许可),并在 GitHub 上可用! -\n -\n一定要来看看代码仓库! + 该应用是开源的(MIT许可),并在 GitHub 上可用! \n \n一定要来看看代码仓库! 使用方法 您的主屏幕仅包含本地日期和时间,没有其它纷纷扰扰。 设置 @@ -87,17 +85,10 @@ 音乐:下一首 啥也不干 教程 - μLauncher 的设计是最小、高效且无干扰。 -\n -\n它不付费、无广告、不追踪。 + μLauncher 的设计是最小、高效且无干扰。 \n \n它不付费、无广告、不追踪。 您只需滑动屏幕或按下按钮即可启动应用程序。在下一步向导中选择一些应用程序。 将 μLauncher 设为默认桌面 - 您已经准备好开始了! -\n -\n我希望这对你有很大的价值! -\n -\n- Finn (Launcher 的作者) -\n以及 Josia(做了一些改进并维护了 μLauncher 分支) + 您已经准备好开始了! \n \n我希望这对你有很大的价值! \n \n- Finn (Launcher 的作者) \n以及 Josia(做了一些改进并维护了 μLauncher 分支) 双滑动作 使用本地日期格式 显示时间 @@ -110,8 +101,7 @@ 旋转屏幕 应用 展开通知面板 - 错误:无法打开通知栏。 -\n这个动作使用的功能并非现有的 Android API的一部分。不幸的是,它似乎不适用于您的设备。 + 错误:无法打开通知栏。 \n这个动作使用的功能并非现有的 Android API的一部分。不幸的是,它似乎不适用于您的设备。 开关手电筒 未检测到带闪光灯的摄像头。 错误:无法访问闪光灯。 diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml index 0a30fac..b2e69a1 100644 --- a/app/src/main/res/values/donottranslate.xml +++ b/app/src/main/res/values/donottranslate.xml @@ -13,6 +13,7 @@ apps.hidden apps.custom_names apps.hide_bound_apps + apps.hide_paused_apps list.layout general.select_launcher diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5bb2c61..4cdebb1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -145,6 +145,7 @@ Apps Hidden apps Don\'t show apps that are bound to a gesture in the app list + Hide paused apps Layout of app list Default @@ -207,6 +208,7 @@ µLauncher Settings All Applications Favorite Applications + Toggle Private Space Lock Music: Louder Music: Quieter Music: Next @@ -245,6 +247,7 @@ More options 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. This functionality requires Android 6.0 or later. + This functionality requires Android 15.0 or later. App hidden. You can make it visible again in settings. Undo Quick Settings @@ -255,6 +258,10 @@ Error: Can\'t access torch. Error: Failed to lock screen. (If you just upgraded the app, try to disable and re-enable the accessibility service in phone settings) μLauncher\'s accessibility service is not enabled. Please enable it in settings + Private space locked + Private space unlocked + Private space is not available + µLauncher needs to be the default home screen to access private space. Error: Locking the screen using accessibility is not supported on this device. Please use device admin instead. µLauncher - lock screen diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index d1dcbe6..57e50df 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -145,6 +145,11 @@ android:title="@string/settings_apps_hide_bound_apps" android:defaultValue="false" /> + +