From 9935386ad8b3aed00b031f27056fa49f17e29d4e Mon Sep 17 00:00:00 2001 From: Hendika N <hendika.new@gmail.com> Date: Sat, 22 Feb 2025 07:35:28 +0700 Subject: [PATCH 01/73] Add option to hide navigation bar on home screen --- .../LauncherPreferences$Config.java | 1 + .../jrpie/android/launcher/ui/HomeActivity.kt | 33 +++++++++++++++++++ app/src/main/res/values/donottranslate.xml | 1 + app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/preferences.xml | 4 +++ 5 files changed, 40 insertions(+) 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 c216911..aacff13 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 @@ -61,6 +61,7 @@ import eu.jonahbauer.android.preference.annotations.Preferences; @Preference(name = "screen_timeout_disabled", type = boolean.class, defaultValue = "false"), @Preference(name = "full_screen", type = boolean.class, defaultValue = "true"), @Preference(name = "rotate_screen", type = boolean.class, defaultValue = "true"), + @Preference(name = "hide_navigation_bar", type = boolean.class, defaultValue = "false"), }), @PreferenceGroup(name = "functionality", prefix = "settings_functionality_", suffix = "_key", value = { @Preference(name = "search_auto_launch", type = boolean.class, defaultValue = "true"), 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 973e0ca..1d807fd 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 @@ -9,6 +9,7 @@ import android.util.DisplayMetrics import android.view.KeyEvent import android.view.MotionEvent import android.view.View +import android.view.Window import android.window.OnBackInvokedDispatcher import androidx.appcompat.app.AppCompatActivity import androidx.core.view.isVisible @@ -99,6 +100,38 @@ class HomeActivity : UIObject, AppCompatActivity() { } + override fun onWindowFocusChanged(hasFocus: Boolean) { + super.onWindowFocusChanged(hasFocus) + + if (hasFocus && LauncherPreferences.display().hideNavigationBar()) { + hideNavigationBar() + } + } + + @Suppress("DEPRECATION") + private fun hideNavigationBar() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + val windowInsetsController = window.insetsController ?: return + windowInsetsController.hide(android.view.WindowInsets.Type.navigationBars()) + windowInsetsController.systemBarsBehavior = + android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE + } else { + val decorView = window.decorView + val uiOptions = + (View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or View.SYSTEM_UI_FLAG_IMMERSIVE or View.SYSTEM_UI_FLAG_LAYOUT_STABLE) + + // Try to hide the navigation bar but do not hide the status bar + decorView.systemUiVisibility = uiOptions + + // Add listener to hide the navigation bar + decorView.setOnSystemUiVisibilityChangeListener { visibility -> + if (visibility and View.SYSTEM_UI_FLAG_FULLSCREEN == 0) { + decorView.systemUiVisibility = uiOptions + } + } + } + } + private fun updateSettingsFallbackButtonVisibility() { // If µLauncher settings can not be reached from any action bound to an enabled gesture, // show the fallback button. diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml index 6ebdf63..ec87cf8 100644 --- a/app/src/main/res/values/donottranslate.xml +++ b/app/src/main/res/values/donottranslate.xml @@ -137,6 +137,7 @@ <string name="settings_display_screen_timeout_disabled_key" translatable="false">display.disable_timeout</string> <string name="settings_display_full_screen_key" translatable="false">display.use_full_screen</string> <string name="settings_display_rotate_screen_key" translatable="false">display.rotate_screen</string> + <string name="settings_display_hide_navigation_bar_key" translatable="false">display.hide_navigation</string> <string name="settings_enabled_gestures_double_swipe_key" translatable="false">enabled_gestures.double_actions</string> <string name="settings_enabled_gestures_edge_swipe_key" translatable="false">enabled_gestures.edge_actions</string> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 687aed1..870e202 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -155,6 +155,7 @@ <string name="settings_display_screen_timeout_disabled">Keep screen on</string> <string name="settings_display_full_screen">Use full screen</string> <string name="settings_display_rotate_screen">Rotate screen</string> + <string name="settings_display_hide_navigation_bar">Hide navigation bar</string> <string name="settings_launcher_section_functionality">Functionality</string> diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 406f81a..180a261 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -180,6 +180,10 @@ android:key="@string/settings_display_screen_timeout_disabled_key" android:defaultValue="false" android:title="@string/settings_display_screen_timeout_disabled"/> + <SwitchPreference + android:key="@string/settings_display_hide_navigation_bar_key" + android:defaultValue="false" + android:title="@string/settings_display_hide_navigation_bar"/> </PreferenceCategory> From 941b06b258056d7e33c37a2ce59b38ccd86c4d05 Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Sat, 22 Feb 2025 03:03:52 +0100 Subject: [PATCH 02/73] minor reformatting --- .../jrpie/android/launcher/ui/HomeActivity.kt | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) 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 1d807fd..1100e0c 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 @@ -10,6 +10,8 @@ import android.view.KeyEvent import android.view.MotionEvent import android.view.View import android.view.Window +import android.view.WindowInsets +import android.view.WindowInsetsController import android.window.OnBackInvokedDispatcher import androidx.appcompat.app.AppCompatActivity import androidx.core.view.isVisible @@ -111,14 +113,18 @@ class HomeActivity : UIObject, AppCompatActivity() { @Suppress("DEPRECATION") private fun hideNavigationBar() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - val windowInsetsController = window.insetsController ?: return - windowInsetsController.hide(android.view.WindowInsets.Type.navigationBars()) - windowInsetsController.systemBarsBehavior = - android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE + window.insetsController?.apply { + hide(WindowInsets.Type.navigationBars()) + systemBarsBehavior = + WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE + } } else { val decorView = window.decorView - val uiOptions = - (View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or View.SYSTEM_UI_FLAG_IMMERSIVE or View.SYSTEM_UI_FLAG_LAYOUT_STABLE) + val uiOptions = (View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY + or View.SYSTEM_UI_FLAG_IMMERSIVE + or View.SYSTEM_UI_FLAG_LAYOUT_STABLE) // Try to hide the navigation bar but do not hide the status bar decorView.systemUiVisibility = uiOptions @@ -219,6 +225,7 @@ class HomeActivity : UIObject, AppCompatActivity() { // Only used pre Android 13, cf. onBackInvokedDispatcher handleBack() } + KeyEvent.KEYCODE_VOLUME_UP -> { if (Action.forGesture(Gesture.VOLUME_UP) == LauncherAction.VOLUME_UP) { // Let the OS handle the key event. This works better with some custom ROMs From ae119ac4ce00b5b87c1feacf71e26e2b2f71645f Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Mon, 3 Mar 2025 21:23:16 +0100 Subject: [PATCH 03/73] remove unused code --- app/src/main/res/layout/list.xml | 9 +++------ app/src/main/res/layout/settings.xml | 6 ++---- app/src/main/res/values/attrs.xml | 8 -------- 3 files changed, 5 insertions(+), 18 deletions(-) delete mode 100644 app/src/main/res/values/attrs.xml diff --git a/app/src/main/res/layout/list.xml b/app/src/main/res/layout/list.xml index e68c895..43c1f4c 100644 --- a/app/src/main/res/layout/list.xml +++ b/app/src/main/res/layout/list.xml @@ -40,8 +40,7 @@ android:src="@drawable/baseline_settings_24" custom:layout_constraintBottom_toBottomOf="parent" custom:layout_constraintStart_toStartOf="parent" - custom:layout_constraintTop_toTopOf="parent" - custom:type="solid" /> + custom:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/list_heading" @@ -70,8 +69,7 @@ android:src="@drawable/baseline_close_24" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintTop_toTopOf="parent" - custom:type="solid" /> + app:layout_constraintTop_toTopOf="parent" /> <ImageView android:id="@+id/list_lock" android:visibility="gone" @@ -85,8 +83,7 @@ android:src="@drawable/baseline_lock_24" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@id/list_close" - app:layout_constraintTop_toTopOf="parent" - custom:type="solid" /> + app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> <com.google.android.material.tabs.TabLayout diff --git a/app/src/main/res/layout/settings.xml b/app/src/main/res/layout/settings.xml index 668358a..f07402c 100644 --- a/app/src/main/res/layout/settings.xml +++ b/app/src/main/res/layout/settings.xml @@ -47,8 +47,7 @@ android:src="@drawable/baseline_close_24" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintTop_toTopOf="parent" - custom:type="solid" /> + app:layout_constraintTop_toTopOf="parent" /> <ImageView android:id="@+id/settings_system" @@ -63,8 +62,7 @@ android:src="@drawable/baseline_settings_applications_24" custom:layout_constraintBottom_toBottomOf="parent" custom:layout_constraintStart_toStartOf="parent" - custom:layout_constraintTop_toTopOf="parent" - custom:type="solid" /> + custom:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> <com.google.android.material.tabs.TabLayout diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml deleted file mode 100644 index f921e27..0000000 --- a/app/src/main/res/values/attrs.xml +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<!-- This declares attributes for the FontAwesome TextView --> -<resources> - <declare-styleable name="FontAwesome"> - <attr name="type" format="string" /> - </declare-styleable> -</resources> \ No newline at end of file From 5ea03d39fa1081f8b52558a861d8a839878c30c6 Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Mon, 3 Mar 2025 21:26:39 +0100 Subject: [PATCH 04/73] fix blurred text in dialogs --- app/src/main/res/values/styles.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 02d809e..5ca2a9e 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -123,6 +123,9 @@ <style name="AlertDialogCustom" parent="Theme.AppCompat.Light.Dialog.Alert"> <item name="android:color">#000000</item> <item name="android:textColor">@color/text_color_toggle</item> + <item name="android:shadowRadius">0</item> + <item name="android:shadowDx">0</item> + <item name="android:shadowDy">0</item> </style> <style name="AlertDialogDanger" parent="AlertDialogCustom"> From 1f825d6f00b6b1b15d22891621fe63f663b169f9 Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Tue, 4 Mar 2025 16:49:29 +0100 Subject: [PATCH 05/73] implement #113: option to reverse app list --- .../launcher/preferences/LauncherPreferences$Config.java | 3 ++- .../android/launcher/ui/list/apps/ListFragmentApps.kt | 9 +++++++++ app/src/main/res/values/donottranslate.xml | 1 + app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/preferences.xml | 6 ++++++ 5 files changed, 19 insertions(+), 1 deletion(-) 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 c216911..19362c2 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 @@ -33,7 +33,8 @@ import eu.jonahbauer.android.preference.annotations.Preferences; @Preference(name = "hide_private_space_apps", type = boolean.class, defaultValue = "false"), }), @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"), + @Preference(name = "reverse_layout", type = boolean.class, defaultValue = "false") }), @PreferenceGroup(name = "gestures", prefix = "settings_gesture_", suffix = "_key", value = { }), diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/ListFragmentApps.kt b/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/ListFragmentApps.kt index 3a6e403..a02c50f 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/ListFragmentApps.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/ListFragmentApps.kt @@ -9,6 +9,8 @@ import android.view.View import android.view.ViewGroup import android.widget.Toast import androidx.fragment.app.Fragment +import androidx.recyclerview.widget.GridLayoutManager +import androidx.recyclerview.widget.LinearLayoutManager import de.jrpie.android.launcher.R import de.jrpie.android.launcher.apps.AppFilter import de.jrpie.android.launcher.databinding.ListAppsBinding @@ -79,11 +81,18 @@ class ListFragmentApps : Fragment(), UIObject { layout = LauncherPreferences.list().layout() ) + // set up the list / recycler binding.listAppsRview.apply { // improve performance (since content changes don't change the layout size) setHasFixedSize(true) layoutManager = LauncherPreferences.list().layout().layoutManager(context) + .also { + if (LauncherPreferences.list().reverseLayout()) { + (it as? LinearLayoutManager)?.reverseLayout = true + (it as? GridLayoutManager)?.reverseLayout = true + } + } adapter = appsRecyclerAdapter } diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml index 6ebdf63..9dd7402 100644 --- a/app/src/main/res/values/donottranslate.xml +++ b/app/src/main/res/values/donottranslate.xml @@ -16,6 +16,7 @@ <string name="settings_apps_hide_paused_apps_key" translatable="false">apps.hide_paused_apps</string> <string name="settings_apps_hide_private_space_apps_key" translatable="false">apps.hide_private_space_apps</string> <string name="settings_list_layout_key" translatable="false">list.layout</string> + <string name="settings_list_reverse_layout_key" translatable="false">list.reverse_layout</string> <string name="settings_general_choose_home_screen_key" translatable="false">general.select_launcher</string> <!-- values of de.jrpie.android.launcher.preferences.ListLayout --> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 95dc9d4..fc5f883 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -178,6 +178,7 @@ <string name="settings_apps_hide_paused_apps">Hide paused apps</string> <string name="settings_apps_hide_private_space_apps">Hide private space from app list</string> <string name="settings_list_layout">Layout of app list</string> + <string name="settings_list_reverse_layout">Reverse app list</string> <string name="settings_list_layout_item_default">Default</string> <string name="settings_list_layout_item_text">Text</string> diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 406f81a..a90debd 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -164,6 +164,12 @@ android:summary="%s" android:defaultValue="DEFAULT"/> + <SwitchPreference + android:key="@string/settings_list_reverse_layout_key" + android:title="@string/settings_list_reverse_layout" + android:defaultValue="false"/> + + </PreferenceCategory> <PreferenceCategory android:title="@string/settings_launcher_section_display" From 9fe1a37ed658003867782e5cf570610f31dff6c8 Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Wed, 5 Mar 2025 00:31:43 +0100 Subject: [PATCH 06/73] implement #45: show pinned shortcuts in app list --- .../de/jrpie/android/launcher/Application.kt | 12 +-- .../de/jrpie/android/launcher/Functions.kt | 33 ++++++-- .../android/launcher/actions/AppAction.kt | 4 +- .../launcher/actions/ShortcutAction.kt | 2 +- .../android/launcher/apps/AbstractAppInfo.kt | 22 +++++ .../launcher/apps/AbstractDetailedAppInfo.kt | 42 ++++++++++ .../jrpie/android/launcher/apps/AppFilter.kt | 28 ++++--- .../de/jrpie/android/launcher/apps/AppInfo.kt | 18 +--- .../android/launcher/apps/DetailedAppInfo.kt | 63 ++++++++------ .../apps/DetailedPinnedShortcutInfo.kt | 66 +++++++++++++++ .../shortcuts => apps}/PinnedShortcutInfo.kt | 6 +- .../LauncherPreferences$Config.java | 12 +-- .../launcher/preferences/Preferences.kt | 12 +-- .../launcher/preferences/legacy/Version1.kt | 17 +++- .../launcher/preferences/legacy/Version2.kt | 2 +- .../launcher/preferences/legacy/Version3.kt | 83 +++++++++++++++++++ .../serialization/PreferenceSerializers.kt | 52 ++++++++---- .../launcher/ui/PinShortcutActivity.kt | 24 +++++- .../ui/list/apps/AppsRecyclerAdapter.kt | 37 +++++---- .../ui/list/apps/ContextMenuActions.kt | 52 +++++++----- .../main/res/layout/activity_pin_shortcut.xml | 16 +++- app/src/main/res/values/donottranslate.xml | 1 + app/src/main/res/values/strings.xml | 1 + 23 files changed, 467 insertions(+), 138 deletions(-) create mode 100644 app/src/main/java/de/jrpie/android/launcher/apps/AbstractAppInfo.kt create mode 100644 app/src/main/java/de/jrpie/android/launcher/apps/AbstractDetailedAppInfo.kt create mode 100644 app/src/main/java/de/jrpie/android/launcher/apps/DetailedPinnedShortcutInfo.kt rename app/src/main/java/de/jrpie/android/launcher/{actions/shortcuts => apps}/PinnedShortcutInfo.kt (93%) create mode 100644 app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version3.kt 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 810fceb..09229ab 100644 --- a/app/src/main/java/de/jrpie/android/launcher/Application.kt +++ b/app/src/main/java/de/jrpie/android/launcher/Application.kt @@ -15,15 +15,15 @@ import androidx.core.content.ContextCompat import androidx.lifecycle.MutableLiveData import androidx.preference.PreferenceManager import de.jrpie.android.launcher.actions.TorchManager -import de.jrpie.android.launcher.apps.AppInfo -import de.jrpie.android.launcher.apps.DetailedAppInfo +import de.jrpie.android.launcher.apps.AbstractAppInfo +import de.jrpie.android.launcher.apps.AbstractDetailedAppInfo import de.jrpie.android.launcher.apps.isPrivateSpaceLocked import de.jrpie.android.launcher.preferences.LauncherPreferences import de.jrpie.android.launcher.preferences.migratePreferencesToNewVersion import de.jrpie.android.launcher.preferences.resetPreferences class Application : android.app.Application() { - val apps = MutableLiveData<List<DetailedAppInfo>>() + val apps = MutableLiveData<List<AbstractDetailedAppInfo>>() val privateSpaceLocked = MutableLiveData<Boolean>() private val profileAvailabilityBroadcastReceiver = object : BroadcastReceiver() { @@ -82,10 +82,12 @@ class Application : android.app.Application() { } var torchManager: TorchManager? = null - private var customAppNames: HashMap<AppInfo, String>? = null + private var customAppNames: HashMap<AbstractAppInfo, String>? = null private val listener = SharedPreferences.OnSharedPreferenceChangeListener { _, pref -> if (pref == getString(R.string.settings_apps_custom_names_key)) { customAppNames = LauncherPreferences.apps().customNames() + } else if (pref == LauncherPreferences.apps().keys().pinnedShortcuts()) { + loadApps() } } @@ -143,7 +145,7 @@ class Application : android.app.Application() { loadApps() } - fun getCustomAppNames(): HashMap<AppInfo, String> { + fun getCustomAppNames(): HashMap<AbstractAppInfo, String> { return (customAppNames ?: LauncherPreferences.apps().customNames() ?: HashMap()) .also { customAppNames = it } } 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 8fc95a3..fc4d6f8 100644 --- a/app/src/main/java/de/jrpie/android/launcher/Functions.kt +++ b/app/src/main/java/de/jrpie/android/launcher/Functions.kt @@ -24,9 +24,12 @@ import androidx.annotation.RequiresApi import de.jrpie.android.launcher.actions.Action import de.jrpie.android.launcher.actions.Gesture import de.jrpie.android.launcher.actions.ShortcutAction -import de.jrpie.android.launcher.actions.shortcuts.PinnedShortcutInfo +import de.jrpie.android.launcher.apps.AbstractAppInfo.Companion.INVALID_USER +import de.jrpie.android.launcher.apps.AbstractDetailedAppInfo import de.jrpie.android.launcher.apps.AppInfo import de.jrpie.android.launcher.apps.DetailedAppInfo +import de.jrpie.android.launcher.apps.DetailedPinnedShortcutInfo +import de.jrpie.android.launcher.apps.PinnedShortcutInfo import de.jrpie.android.launcher.apps.getPrivateSpaceUser import de.jrpie.android.launcher.apps.isPrivateSpaceSupported import de.jrpie.android.launcher.preferences.LauncherPreferences @@ -99,9 +102,10 @@ fun removeUnusedShortcuts(context: Context) { } val userManager = context.getSystemService(Service.USER_SERVICE) as UserManager - val boundActions: Set<PinnedShortcutInfo> = + val boundActions: MutableSet<PinnedShortcutInfo> = Gesture.entries.mapNotNull { Action.forGesture(it) as? ShortcutAction }.map { it.shortcut } - .toSet() + .toMutableSet() + boundActions.addAll(LauncherPreferences.apps().pinnedShortcuts()) try { userManager.userProfiles.filter { !userManager.isQuietModeEnabled(it) }.forEach { profile -> getShortcuts(profile)?.groupBy { it.`package` }?.forEach { (p, shortcuts) -> @@ -135,9 +139,12 @@ fun openTutorial(context: Context) { /** * Load all apps. */ -fun getApps(packageManager: PackageManager, context: Context): MutableList<DetailedAppInfo> { - val start = System.currentTimeMillis() - val loadList = mutableListOf<DetailedAppInfo>() +fun getApps( + packageManager: PackageManager, + context: Context +): MutableList<AbstractDetailedAppInfo> { + var start = System.currentTimeMillis() + val loadList = mutableListOf<AbstractDetailedAppInfo>() val launcherApps = context.getSystemService(Service.LAUNCHER_APPS_SERVICE) as LauncherApps val userManager = context.getSystemService(Service.USER_SERVICE) as UserManager @@ -174,7 +181,7 @@ fun getApps(packageManager: PackageManager, context: Context): MutableList<Detai i.addCategory(Intent.CATEGORY_LAUNCHER) val allApps = packageManager.queryIntentActivities(i, 0) for (ri in allApps) { - val app = AppInfo(ri.activityInfo.packageName, null, AppInfo.INVALID_USER) + val app = AppInfo(ri.activityInfo.packageName, null, INVALID_USER) val detailedAppInfo = DetailedAppInfo( app, ri.loadLabel(packageManager), @@ -186,8 +193,18 @@ fun getApps(packageManager: PackageManager, context: Context): MutableList<Detai } loadList.sortBy { it.getCustomLabel(context).toString() } - val end = System.currentTimeMillis() + var end = System.currentTimeMillis() Log.i(LOG_TAG, "${loadList.size} apps loaded (${end - start}ms)") + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) { + start = System.currentTimeMillis() + LauncherPreferences.apps().pinnedShortcuts() + ?.mapNotNull { DetailedPinnedShortcutInfo.fromPinnedShortcutInfo(it, context) } + ?.let { + end = System.currentTimeMillis() + Log.i(LOG_TAG, "${it.size} shortcuts loaded (${end - start}ms)") + loadList.addAll(it) + } + } return loadList } diff --git a/app/src/main/java/de/jrpie/android/launcher/actions/AppAction.kt b/app/src/main/java/de/jrpie/android/launcher/actions/AppAction.kt index 90145aa..1446b13 100644 --- a/app/src/main/java/de/jrpie/android/launcher/actions/AppAction.kt +++ b/app/src/main/java/de/jrpie/android/launcher/actions/AppAction.kt @@ -11,7 +11,7 @@ import android.graphics.drawable.Drawable import android.util.Log import de.jrpie.android.launcher.R import de.jrpie.android.launcher.apps.AppInfo -import de.jrpie.android.launcher.apps.AppInfo.Companion.INVALID_USER +import de.jrpie.android.launcher.apps.AbstractAppInfo.Companion.INVALID_USER import de.jrpie.android.launcher.apps.DetailedAppInfo import de.jrpie.android.launcher.ui.list.apps.openSettings import kotlinx.serialization.SerialName @@ -67,7 +67,7 @@ class AppAction(val app: AppInfo) : Action { } override fun getIcon(context: Context): Drawable? { - return DetailedAppInfo.fromAppInfo(app, context)?.icon + return DetailedAppInfo.fromAppInfo(app, context)?.getIcon(context) } override fun isAvailable(context: Context): Boolean { diff --git a/app/src/main/java/de/jrpie/android/launcher/actions/ShortcutAction.kt b/app/src/main/java/de/jrpie/android/launcher/actions/ShortcutAction.kt index 8517b1a..a89f9e2 100644 --- a/app/src/main/java/de/jrpie/android/launcher/actions/ShortcutAction.kt +++ b/app/src/main/java/de/jrpie/android/launcher/actions/ShortcutAction.kt @@ -6,7 +6,7 @@ import android.content.pm.LauncherApps import android.graphics.Rect import android.graphics.drawable.Drawable import android.os.Build -import de.jrpie.android.launcher.actions.shortcuts.PinnedShortcutInfo +import de.jrpie.android.launcher.apps.PinnedShortcutInfo import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable diff --git a/app/src/main/java/de/jrpie/android/launcher/apps/AbstractAppInfo.kt b/app/src/main/java/de/jrpie/android/launcher/apps/AbstractAppInfo.kt new file mode 100644 index 0000000..dd60752 --- /dev/null +++ b/app/src/main/java/de/jrpie/android/launcher/apps/AbstractAppInfo.kt @@ -0,0 +1,22 @@ +package de.jrpie.android.launcher.apps + +import kotlinx.serialization.Serializable +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json + +/** + * This interface is implemented by [AppInfo] and [PinnedShortcutInfo]. + */ +@Serializable +sealed interface AbstractAppInfo { + fun serialize(): String { + return Json.encodeToString(this) + } + companion object { + const val INVALID_USER = -1 + + fun deserialize(serialized: String): AbstractAppInfo { + return Json.decodeFromString(serialized) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/de/jrpie/android/launcher/apps/AbstractDetailedAppInfo.kt b/app/src/main/java/de/jrpie/android/launcher/apps/AbstractDetailedAppInfo.kt new file mode 100644 index 0000000..9c7413d --- /dev/null +++ b/app/src/main/java/de/jrpie/android/launcher/apps/AbstractDetailedAppInfo.kt @@ -0,0 +1,42 @@ +package de.jrpie.android.launcher.apps + +import android.content.Context +import android.graphics.drawable.Drawable +import android.os.UserHandle +import android.util.Log +import de.jrpie.android.launcher.Application +import de.jrpie.android.launcher.actions.Action +import de.jrpie.android.launcher.preferences.LauncherPreferences + +/** + * This interface is implemented by [DetailedAppInfo] and [DetailedPinnedShortcutInfo] + */ +sealed interface AbstractDetailedAppInfo { + fun getRawInfo(): AbstractAppInfo + fun getLabel(): String + fun getIcon(context: Context): Drawable + fun getUser(context: Context): UserHandle + fun isPrivate(): Boolean + fun isRemovable(): Boolean + fun getAction(): Action + + + fun getCustomLabel(context: Context): String { + val map = (context.applicationContext as? Application)?.getCustomAppNames() + return map?.get(getRawInfo()) ?: getLabel() + } + + + fun setCustomLabel(label: CharSequence?) { + Log.i("Launcher", "Setting custom label for ${this.getRawInfo()} to ${label}.") + val map = LauncherPreferences.apps().customNames() ?: HashMap<AbstractAppInfo, String>() + + if (label.isNullOrEmpty()) { + map.remove(getRawInfo()) + } else { + map[getRawInfo()] = label.toString() + } + LauncherPreferences.apps().customNames(map) + } + +} \ No newline at end of file diff --git a/app/src/main/java/de/jrpie/android/launcher/apps/AppFilter.kt b/app/src/main/java/de/jrpie/android/launcher/apps/AppFilter.kt index ecc7eaa..ca387c0 100644 --- a/app/src/main/java/de/jrpie/android/launcher/apps/AppFilter.kt +++ b/app/src/main/java/de/jrpie/android/launcher/apps/AppFilter.kt @@ -6,6 +6,7 @@ import android.os.Build import de.jrpie.android.launcher.actions.Action import de.jrpie.android.launcher.actions.AppAction import de.jrpie.android.launcher.actions.Gesture +import de.jrpie.android.launcher.actions.ShortcutAction import de.jrpie.android.launcher.preferences.LauncherPreferences import java.util.Locale import kotlin.text.Regex.Companion.escape @@ -18,13 +19,14 @@ class AppFilter( var privateSpaceVisibility: AppSetVisibility = AppSetVisibility.VISIBLE ) { - operator fun invoke(apps: List<DetailedAppInfo>): List<DetailedAppInfo> { + operator fun invoke(apps: List<AbstractDetailedAppInfo>): List<AbstractDetailedAppInfo> { var apps = - apps.sortedBy { app -> app.getCustomLabel(context).toString().lowercase(Locale.ROOT) } + apps.sortedBy { app -> app.getCustomLabel(context).lowercase(Locale.ROOT) } val hidden = LauncherPreferences.apps().hidden() ?: setOf() val favorites = LauncherPreferences.apps().favorites() ?: setOf() - val private = apps.filter { it.isPrivateSpaceApp }.map { it.app }.toSet() + val private = apps.filter { it.isPrivate() } + .map { it.getRawInfo() }.toSet() apps = apps.filter { info -> favoritesVisibility.predicate(favorites, info) @@ -35,9 +37,13 @@ class AppFilter( if (LauncherPreferences.apps().hideBoundApps()) { val boundApps = Gesture.entries .filter(Gesture::isEnabled) - .mapNotNull { g -> (Action.forGesture(g) as? AppAction)?.app } + .mapNotNull { g -> Action.forGesture(g) } + .mapNotNull { + (it as? AppAction)?.app + ?: (it as? ShortcutAction)?.shortcut + } .toSet() - apps = apps.filterNot { info -> boundApps.contains(info.app) } + apps = apps.filterNot { info -> boundApps.contains(info.getRawInfo()) } } // normalize text for search @@ -57,11 +63,11 @@ class AppFilter( if (query.isEmpty()) { return apps } else { - val r: MutableList<DetailedAppInfo> = ArrayList() - val appsSecondary: MutableList<DetailedAppInfo> = ArrayList() + val r: MutableList<AbstractDetailedAppInfo> = ArrayList() + val appsSecondary: MutableList<AbstractDetailedAppInfo> = ArrayList() val normalizedQuery: String = normalize(query) for (item in apps) { - val itemLabel: String = normalize(item.getCustomLabel(context).toString()) + val itemLabel: String = normalize(item.getCustomLabel(context)) if (itemLabel.startsWith(normalizedQuery)) { r.add(item) @@ -77,11 +83,11 @@ class AppFilter( companion object { enum class AppSetVisibility( - val predicate: (set: Set<AppInfo>, DetailedAppInfo) -> Boolean + val predicate: (set: Set<AbstractAppInfo>, AbstractDetailedAppInfo) -> Boolean ) { VISIBLE({ _, _ -> true }), - HIDDEN({ set, appInfo -> !set.contains(appInfo.app) }), - EXCLUSIVE({ set, appInfo -> set.contains(appInfo.app) }), + HIDDEN({ set, appInfo -> !set.contains(appInfo.getRawInfo()) }), + EXCLUSIVE({ set, appInfo -> set.contains(appInfo.getRawInfo()) }), ; } diff --git a/app/src/main/java/de/jrpie/android/launcher/apps/AppInfo.kt b/app/src/main/java/de/jrpie/android/launcher/apps/AppInfo.kt index 21614f8..944cfaa 100644 --- a/app/src/main/java/de/jrpie/android/launcher/apps/AppInfo.kt +++ b/app/src/main/java/de/jrpie/android/launcher/apps/AppInfo.kt @@ -4,21 +4,18 @@ import android.app.Service import android.content.Context import android.content.pm.LauncherActivityInfo import android.content.pm.LauncherApps +import de.jrpie.android.launcher.apps.AbstractAppInfo.Companion.INVALID_USER import de.jrpie.android.launcher.getUserFromId +import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.Json /** * Represents an app installed on the users device. * Contains the minimal amount of data required to identify the app. */ @Serializable -class AppInfo(val packageName: String, val activityName: String?, val user: Int = INVALID_USER) { - - fun serialize(): String { - return Json.encodeToString(this) - } +@SerialName("app") +class AppInfo(val packageName: String, val activityName: String?, val user: Int = INVALID_USER): AbstractAppInfo { override fun equals(other: Any?): Boolean { if(other is AppInfo) { @@ -47,11 +44,4 @@ class AppInfo(val packageName: String, val activityName: String?, val user: Int return "AppInfo {package=$packageName, activity=$activityName, user=$user}" } - companion object { - const val INVALID_USER = -1 - - fun deserialize(serialized: String): AppInfo { - return Json.decodeFromString(serialized) - } - } } \ No newline at end of file diff --git a/app/src/main/java/de/jrpie/android/launcher/apps/DetailedAppInfo.kt b/app/src/main/java/de/jrpie/android/launcher/apps/DetailedAppInfo.kt index d77bf93..76f7fbb 100644 --- a/app/src/main/java/de/jrpie/android/launcher/apps/DetailedAppInfo.kt +++ b/app/src/main/java/de/jrpie/android/launcher/apps/DetailedAppInfo.kt @@ -4,20 +4,21 @@ import android.content.Context import android.content.pm.ApplicationInfo import android.content.pm.LauncherActivityInfo import android.graphics.drawable.Drawable -import android.util.Log -import de.jrpie.android.launcher.Application -import de.jrpie.android.launcher.preferences.LauncherPreferences +import android.os.UserHandle +import de.jrpie.android.launcher.actions.Action +import de.jrpie.android.launcher.actions.AppAction +import de.jrpie.android.launcher.getUserFromId /** * Stores information used to create [de.jrpie.android.launcher.ui.list.apps.AppsRecyclerAdapter] rows. */ class DetailedAppInfo( - val app: AppInfo, - val label: CharSequence, - val icon: Drawable, - val isPrivateSpaceApp: Boolean, - val isSystemApp: Boolean = false, -) { + private val app: AppInfo, + private val label: CharSequence, + private val icon: Drawable, + private val privateSpace: Boolean, + private val removable: Boolean = true, +): AbstractDetailedAppInfo { constructor(activityInfo: LauncherActivityInfo, private: Boolean) : this( AppInfo( @@ -28,29 +29,41 @@ class DetailedAppInfo( activityInfo.label, activityInfo.getBadgedIcon(0), private, - activityInfo.applicationInfo.flags.and(ApplicationInfo.FLAG_SYSTEM) != 0 + // App can be uninstalled iff it is not a system app + activityInfo.applicationInfo.flags.and(ApplicationInfo.FLAG_SYSTEM) == 0 ) - fun getCustomLabel(context: Context): CharSequence { - val map = (context.applicationContext as? Application)?.getCustomAppNames() ?: return label - return map[app] ?: label + + override fun getLabel(): String { + return label.toString() } - fun setCustomLabel(label: CharSequence?) { - - Log.i("Launcher", "Setting custom label for ${this.app} to ${label}.") - val map = LauncherPreferences.apps().customNames() ?: HashMap<AppInfo, String>() - - if (label.isNullOrEmpty()) { - map.remove(app) - } else { - map[app] = label.toString() - } - - LauncherPreferences.apps().customNames(map) + override fun getIcon(context: Context): Drawable { + return icon } + override fun getRawInfo(): AppInfo { + return app + } + + override fun getUser(context: Context): UserHandle { + return getUserFromId(app.user, context) + } + + override fun isPrivate(): Boolean { + return privateSpace + } + + override fun isRemovable(): Boolean { + return removable + } + + override fun getAction(): Action { + return AppAction(app) + } + + companion object { fun fromAppInfo(appInfo: AppInfo, context: Context): DetailedAppInfo? { return appInfo.getLauncherActivityInfo(context)?.let { diff --git a/app/src/main/java/de/jrpie/android/launcher/apps/DetailedPinnedShortcutInfo.kt b/app/src/main/java/de/jrpie/android/launcher/apps/DetailedPinnedShortcutInfo.kt new file mode 100644 index 0000000..f66034d --- /dev/null +++ b/app/src/main/java/de/jrpie/android/launcher/apps/DetailedPinnedShortcutInfo.kt @@ -0,0 +1,66 @@ +package de.jrpie.android.launcher.apps + +import android.app.Service +import android.content.Context +import android.content.pm.LauncherApps +import android.content.pm.ShortcutInfo +import android.graphics.drawable.Drawable +import android.os.Build +import android.os.UserHandle +import androidx.annotation.RequiresApi +import de.jrpie.android.launcher.actions.Action +import de.jrpie.android.launcher.actions.ShortcutAction +import de.jrpie.android.launcher.getUserFromId + +@RequiresApi(Build.VERSION_CODES.N_MR1) +class DetailedPinnedShortcutInfo( + private val shortcutInfo: PinnedShortcutInfo, + private val label: String, + private val icon: Drawable, + private val privateSpace: Boolean +) : AbstractDetailedAppInfo { + + constructor(context: Context, shortcut: ShortcutInfo) : this( + PinnedShortcutInfo(shortcut), + shortcut.longLabel.toString(), + (context.getSystemService(Service.LAUNCHER_APPS_SERVICE) as LauncherApps) + .getShortcutBadgedIconDrawable(shortcut, 0), + shortcut.userHandle == getPrivateSpaceUser(context) + ) + + override fun getRawInfo(): AbstractAppInfo { + return shortcutInfo + } + + override fun getLabel(): String { + return label + } + + override fun getIcon(context: Context): Drawable { + return icon + } + + override fun getUser(context: Context): UserHandle { + return getUserFromId(shortcutInfo.user, context) + } + + override fun isPrivate(): Boolean { + return privateSpace + } + + override fun isRemovable(): Boolean { + return true + } + + override fun getAction(): Action { + return ShortcutAction(shortcutInfo) + } + + companion object { + fun fromPinnedShortcutInfo(shortcutInfo: PinnedShortcutInfo, context: Context): DetailedPinnedShortcutInfo? { + return shortcutInfo.getShortcutInfo(context)?.let { + DetailedPinnedShortcutInfo(context, it) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/de/jrpie/android/launcher/actions/shortcuts/PinnedShortcutInfo.kt b/app/src/main/java/de/jrpie/android/launcher/apps/PinnedShortcutInfo.kt similarity index 93% rename from app/src/main/java/de/jrpie/android/launcher/actions/shortcuts/PinnedShortcutInfo.kt rename to app/src/main/java/de/jrpie/android/launcher/apps/PinnedShortcutInfo.kt index 796c737..a2815e5 100644 --- a/app/src/main/java/de/jrpie/android/launcher/actions/shortcuts/PinnedShortcutInfo.kt +++ b/app/src/main/java/de/jrpie/android/launcher/apps/PinnedShortcutInfo.kt @@ -1,4 +1,4 @@ -package de.jrpie.android.launcher.actions.shortcuts +package de.jrpie.android.launcher.apps import android.app.Service import android.content.ComponentName @@ -9,17 +9,19 @@ import android.content.pm.ShortcutInfo import android.os.Build import androidx.annotation.RequiresApi import de.jrpie.android.launcher.getUserFromId +import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @RequiresApi(Build.VERSION_CODES.N_MR1) @Serializable +@SerialName("shortcut") class PinnedShortcutInfo( val id: String, val packageName: String, val activityName: String, val user: Int -) { +): AbstractAppInfo { constructor(info: ShortcutInfo) : this(info.id, info.`package`, info.activity?.className ?: "", info.userHandle.hashCode()) 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 19362c2..9be85ab 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,9 @@ 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.MapAppInfoStringPreferenceSerializer; -import de.jrpie.android.launcher.preferences.serialization.SetAppInfoPreferenceSerializer; +import de.jrpie.android.launcher.preferences.serialization.MapAbstractAppInfoStringPreferenceSerializer; +import de.jrpie.android.launcher.preferences.serialization.SetAbstractAppInfoPreferenceSerializer; +import de.jrpie.android.launcher.preferences.serialization.SetPinnedShortcutInfoPreferenceSerializer; import de.jrpie.android.launcher.preferences.theme.Background; import de.jrpie.android.launcher.preferences.theme.ColorTheme; import de.jrpie.android.launcher.preferences.theme.Font; @@ -25,9 +26,10 @@ import eu.jonahbauer.android.preference.annotations.Preferences; @Preference(name = "version_code", type = int.class, defaultValue = "-1"), }), @PreferenceGroup(name = "apps", prefix = "settings_apps_", suffix = "_key", value = { - @Preference(name = "favorites", 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 = "favorites", type = Set.class, serializer = SetAbstractAppInfoPreferenceSerializer.class), + @Preference(name = "hidden", type = Set.class, serializer = SetAbstractAppInfoPreferenceSerializer.class), + @Preference(name = "pinned_shortcuts", type = Set.class, serializer = SetPinnedShortcutInfoPreferenceSerializer.class), + @Preference(name = "custom_names", type = HashMap.class, serializer = MapAbstractAppInfoStringPreferenceSerializer.class), @Preference(name = "hide_bound_apps", type = boolean.class, defaultValue = "false"), @Preference(name = "hide_paused_apps", type = boolean.class, defaultValue = "false"), @Preference(name = "hide_private_space_apps", type = boolean.class, defaultValue = "false"), diff --git a/app/src/main/java/de/jrpie/android/launcher/preferences/Preferences.kt b/app/src/main/java/de/jrpie/android/launcher/preferences/Preferences.kt index 9460125..caa39b3 100644 --- a/app/src/main/java/de/jrpie/android/launcher/preferences/Preferences.kt +++ b/app/src/main/java/de/jrpie/android/launcher/preferences/Preferences.kt @@ -5,6 +5,8 @@ import android.util.Log import de.jrpie.android.launcher.BuildConfig import de.jrpie.android.launcher.actions.Action import de.jrpie.android.launcher.apps.AppInfo +import de.jrpie.android.launcher.apps.AbstractAppInfo +import de.jrpie.android.launcher.apps.AbstractAppInfo.Companion.INVALID_USER import de.jrpie.android.launcher.apps.DetailedAppInfo import de.jrpie.android.launcher.preferences.legacy.migratePreferencesFromVersion1 import de.jrpie.android.launcher.preferences.legacy.migratePreferencesFromVersion2 @@ -15,7 +17,7 @@ import de.jrpie.android.launcher.ui.HomeActivity * Increase when breaking changes are introduced and write an appropriate case in * `migratePreferencesToNewVersion` */ -const val PREFERENCE_VERSION = 3 +const val PREFERENCE_VERSION = 4 const val UNKNOWN_PREFERENCE_VERSION = -1 private const val TAG = "Launcher - Preferences" @@ -66,16 +68,16 @@ fun resetPreferences(context: Context) { LauncherPreferences.internal().versionCode(PREFERENCE_VERSION) - val hidden: MutableSet<AppInfo> = mutableSetOf() + val hidden: MutableSet<AbstractAppInfo> = mutableSetOf() val launcher = DetailedAppInfo.fromAppInfo( AppInfo( BuildConfig.APPLICATION_ID, HomeActivity::class.java.name, - AppInfo.INVALID_USER + INVALID_USER ), context ) - launcher?.app?.let { hidden.add(it) } - Log.i(TAG,"Hiding ${launcher?.app}") + launcher?.getRawInfo()?.let { hidden.add(it) } + Log.i(TAG,"Hiding ${launcher?.getRawInfo()}") LauncherPreferences.apps().hidden(hidden) Action.resetToDefaultActions(context) diff --git a/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version1.kt b/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version1.kt index a61980a..6408b70 100644 --- a/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version1.kt +++ b/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version1.kt @@ -5,15 +5,26 @@ import de.jrpie.android.launcher.actions.AppAction import de.jrpie.android.launcher.actions.Gesture import de.jrpie.android.launcher.actions.LauncherAction import de.jrpie.android.launcher.apps.AppInfo -import de.jrpie.android.launcher.apps.AppInfo.Companion.INVALID_USER +import de.jrpie.android.launcher.apps.AbstractAppInfo.Companion.INVALID_USER import de.jrpie.android.launcher.preferences.LauncherPreferences import de.jrpie.android.launcher.preferences.PREFERENCE_VERSION -import de.jrpie.android.launcher.preferences.serialization.MapAppInfoStringPreferenceSerializer +import kotlinx.serialization.Serializable import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json import org.json.JSONException import org.json.JSONObject + +@Serializable +private class LegacyMapEntry(val key: AppInfo, val value: String) + +private fun serializeMapAppInfo(value: Map<AppInfo, String>?): Set<String>? { + return value?.map { (key, value) -> + Json.encodeToString(LegacyMapEntry(key, value)) + }?.toSet() +} + + val oldLauncherActionIds: Map<String, LauncherAction> = mapOf( Pair("launcher:settings", LauncherAction.SETTINGS), @@ -77,7 +88,7 @@ private fun Action.Companion.legacyFromPreference(id: String): Action? { private fun migrateAppInfoStringMap(key: String) { val preferences = LauncherPreferences.getSharedPreferences() - MapAppInfoStringPreferenceSerializer().serialize( + serializeMapAppInfo( preferences.getStringSet(key, setOf())?.mapNotNull { entry -> try { val obj = JSONObject(entry) diff --git a/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version2.kt b/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version2.kt index bcac3ae..4e6eae1 100644 --- a/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version2.kt +++ b/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version2.kt @@ -12,9 +12,9 @@ import de.jrpie.android.launcher.preferences.PREFERENCE_VERSION * (see [PREFERENCE_VERSION]) */ fun migratePreferencesFromVersion2() { - assert(PREFERENCE_VERSION == 3) assert(LauncherPreferences.internal().versionCode() == 2) // previously there was no setting for this Action.setActionForGesture(Gesture.BACK, LauncherAction.CHOOSE) LauncherPreferences.internal().versionCode(3) + migratePreferencesFromVersion3() } \ No newline at end of file diff --git a/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version3.kt b/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version3.kt new file mode 100644 index 0000000..d3bf7af --- /dev/null +++ b/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version3.kt @@ -0,0 +1,83 @@ +package de.jrpie.android.launcher.preferences.legacy + +import android.content.SharedPreferences +import android.content.SharedPreferences.Editor +import de.jrpie.android.launcher.apps.AppInfo +import de.jrpie.android.launcher.apps.AbstractAppInfo +import de.jrpie.android.launcher.preferences.LauncherPreferences +import de.jrpie.android.launcher.preferences.PREFERENCE_VERSION +import de.jrpie.android.launcher.preferences.serialization.MapAbstractAppInfoStringPreferenceSerializer +import de.jrpie.android.launcher.preferences.serialization.SetAbstractAppInfoPreferenceSerializer +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.Json +import java.util.HashSet + +/** + * Migrate preferences from version 3 (used until version 0.0.23) to the current format + * (see [PREFERENCE_VERSION]) + */ + + +fun deserializeSet(value: Set<String>?): Set<AppInfo>? { + return value?.map { + Json.decodeFromString<AppInfo>(it) + }?.toHashSet() +} + +fun deserializeMap(value: Set<String>?): HashMap<AppInfo, String>? { + return value?.associateTo(HashMap()) { + val entry = Json.decodeFromString<MapEntry>(it) + Pair(entry.key, entry.value) + } +} + +@Serializable +private class MapEntry(val key: AppInfo, val value: String) + +private fun migrateSetAppInfo(key: String, preferences: SharedPreferences, editor: Editor) { + try { + val serializer = SetAbstractAppInfoPreferenceSerializer() + val set = HashSet<AbstractAppInfo>() + + deserializeSet(preferences.getStringSet(key, null))?.let { + set.addAll(it) + } + editor.putStringSet( + key, + serializer.serialize(set as java.util.Set<AbstractAppInfo>) as Set<String>? + ) + } catch (_: Exception) { + editor.putStringSet(key, null) + } + +} +private fun migrateMapAppInfoString(key: String, preferences: SharedPreferences, editor: Editor ) { + try { + val serializer = MapAbstractAppInfoStringPreferenceSerializer() + val map = HashMap<AbstractAppInfo, String>() + + deserializeMap(preferences.getStringSet(key, null))?.let { + map.putAll(it) + } + editor.putStringSet(key, serializer.serialize(map) as Set<String>?) + } catch (_: Exception) { + editor.putStringSet(key, null) + } +} + +fun migratePreferencesFromVersion3() { + assert(PREFERENCE_VERSION == 4) + assert(LauncherPreferences.internal().versionCode() == 3) + + val preferences = LauncherPreferences.getSharedPreferences() + val editor = preferences.edit() + migrateSetAppInfo(LauncherPreferences.apps().keys().favorites(), preferences, editor) + migrateSetAppInfo(LauncherPreferences.apps().keys().hidden(), preferences, editor) + migrateSetAppInfo(LauncherPreferences.apps().keys().customNames(), preferences, editor) + + editor.apply() + + + + LauncherPreferences.internal().versionCode(4) +} \ No newline at end of file diff --git a/app/src/main/java/de/jrpie/android/launcher/preferences/serialization/PreferenceSerializers.kt b/app/src/main/java/de/jrpie/android/launcher/preferences/serialization/PreferenceSerializers.kt index 041fe4d..3e19daf 100644 --- a/app/src/main/java/de/jrpie/android/launcher/preferences/serialization/PreferenceSerializers.kt +++ b/app/src/main/java/de/jrpie/android/launcher/preferences/serialization/PreferenceSerializers.kt @@ -2,7 +2,8 @@ package de.jrpie.android.launcher.preferences.serialization -import de.jrpie.android.launcher.apps.AppInfo +import de.jrpie.android.launcher.apps.AbstractAppInfo +import de.jrpie.android.launcher.apps.PinnedShortcutInfo import eu.jonahbauer.android.preference.annotations.serializer.PreferenceSerializationException import eu.jonahbauer.android.preference.annotations.serializer.PreferenceSerializer import kotlinx.serialization.Serializable @@ -10,40 +11,61 @@ import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json -// Serializers for [LauncherPreference$Config] + @Suppress("UNCHECKED_CAST") -class SetAppInfoPreferenceSerializer : - PreferenceSerializer<java.util.Set<AppInfo>?, java.util.Set<java.lang.String>?> { +class SetAbstractAppInfoPreferenceSerializer : + PreferenceSerializer<java.util.Set<AbstractAppInfo>?, java.util.Set<java.lang.String>?> { @Throws(PreferenceSerializationException::class) - override fun serialize(value: java.util.Set<AppInfo>?): java.util.Set<java.lang.String> { - return value?.map(AppInfo::serialize)?.toHashSet() as java.util.Set<java.lang.String> + override fun serialize(value: java.util.Set<AbstractAppInfo>?): java.util.Set<java.lang.String> { + return value?.map(AbstractAppInfo::serialize) + ?.toHashSet() as java.util.Set<java.lang.String> } @Throws(PreferenceSerializationException::class) - override fun deserialize(value: java.util.Set<java.lang.String>?): java.util.Set<AppInfo>? { - return value?.map (java.lang.String::toString)?.map(AppInfo::deserialize)?.toHashSet() as? java.util.Set<AppInfo> + override fun deserialize(value: java.util.Set<java.lang.String>?): java.util.Set<AbstractAppInfo>? { + return value?.map(java.lang.String::toString)?.map(AbstractAppInfo::deserialize) + ?.toHashSet() as? java.util.Set<AbstractAppInfo> } } @Suppress("UNCHECKED_CAST") -class MapAppInfoStringPreferenceSerializer : - PreferenceSerializer<java.util.HashMap<AppInfo, String>?, java.util.Set<java.lang.String>?> { - - @Serializable - private class MapEntry(val key: AppInfo, val value: String) +class SetPinnedShortcutInfoPreferenceSerializer : + PreferenceSerializer<java.util.Set<PinnedShortcutInfo>?, java.util.Set<java.lang.String>?> { + @Throws(PreferenceSerializationException::class) + override fun serialize(value: java.util.Set<PinnedShortcutInfo>?): java.util.Set<java.lang.String> { + return value?.map { Json.encodeToString<PinnedShortcutInfo>(it) } + ?.toHashSet() as java.util.Set<java.lang.String> + } @Throws(PreferenceSerializationException::class) - override fun serialize(value: java.util.HashMap<AppInfo, String>?): java.util.Set<java.lang.String>? { + override fun deserialize(value: java.util.Set<java.lang.String>?): java.util.Set<PinnedShortcutInfo>? { + return value?.map(java.lang.String::toString) + ?.map { Json.decodeFromString<PinnedShortcutInfo>(it) } + ?.toHashSet() as? java.util.Set<PinnedShortcutInfo> + } +} + + +@Suppress("UNCHECKED_CAST") +class MapAbstractAppInfoStringPreferenceSerializer : + PreferenceSerializer<java.util.HashMap<AbstractAppInfo, String>?, java.util.Set<java.lang.String>?> { + + @Serializable + private class MapEntry(val key: AbstractAppInfo, val value: String) + + @Throws(PreferenceSerializationException::class) + override fun serialize(value: java.util.HashMap<AbstractAppInfo, String>?): java.util.Set<java.lang.String>? { return value?.map { (key, value) -> Json.encodeToString(MapEntry(key, value)) }?.toHashSet() as? java.util.Set<java.lang.String> } @Throws(PreferenceSerializationException::class) - override fun deserialize(value: java.util.Set<java.lang.String>?): java.util.HashMap<AppInfo, String>? { + override fun deserialize(value: java.util.Set<java.lang.String>?): java.util.HashMap<AbstractAppInfo, String>? { return value?.associateTo(HashMap()) { val entry = Json.decodeFromString<MapEntry>(it.toString()) Pair(entry.key, entry.value) } } } + diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/PinShortcutActivity.kt b/app/src/main/java/de/jrpie/android/launcher/ui/PinShortcutActivity.kt index d19fe04..4d5d700 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/PinShortcutActivity.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/PinShortcutActivity.kt @@ -21,7 +21,7 @@ import de.jrpie.android.launcher.R import de.jrpie.android.launcher.actions.Action import de.jrpie.android.launcher.actions.Gesture import de.jrpie.android.launcher.actions.ShortcutAction -import de.jrpie.android.launcher.actions.shortcuts.PinnedShortcutInfo +import de.jrpie.android.launcher.apps.PinnedShortcutInfo import de.jrpie.android.launcher.databinding.ActivityPinShortcutBinding import de.jrpie.android.launcher.preferences.LauncherPreferences @@ -29,6 +29,7 @@ class PinShortcutActivity : AppCompatActivity(), UIObject { private lateinit var binding: ActivityPinShortcutBinding private var isBound = false + private var request: PinItemRequest? = null override fun onCreate(savedInstanceState: Bundle?) { super<AppCompatActivity>.onCreate(savedInstanceState) @@ -46,6 +47,7 @@ class PinShortcutActivity : AppCompatActivity(), UIObject { val launcherApps = getSystemService(Service.LAUNCHER_APPS_SERVICE) as LauncherApps val request = launcherApps.getPinItemRequest(intent) + this.request = request if (request == null || request.requestType != PinItemRequest.REQUEST_TYPE_SHORTCUT) { finish() return @@ -84,6 +86,7 @@ class PinShortcutActivity : AppCompatActivity(), UIObject { } binding.pinShortcutClose.setOnClickListener { finish() } + binding.pinShortcutButtonOk.setOnClickListener { finish() } } override fun onStart() { @@ -91,6 +94,24 @@ class PinShortcutActivity : AppCompatActivity(), UIObject { super<UIObject>.onStart() } + override fun onDestroy() { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { + super.onDestroy() + return + } + if(binding.pinShortcutSwitchVisible.isChecked) { + if(!isBound) { + request?.accept() + } + request?.shortcutInfo?.let { + val set = LauncherPreferences.apps().pinnedShortcuts() ?: mutableSetOf() + set.add(PinnedShortcutInfo(it)) + LauncherPreferences.apps().pinnedShortcuts(set) + } + } + super.onDestroy() + } + override fun getTheme(): Resources.Theme { return modifyTheme(super.getTheme()) } @@ -124,5 +145,6 @@ class PinShortcutActivity : AppCompatActivity(), UIObject { override fun getItemCount(): Int { return gestures.size } + } } \ No newline at end of file diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/AppsRecyclerAdapter.kt b/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/AppsRecyclerAdapter.kt index 2d8e1eb..0c0407e 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/AppsRecyclerAdapter.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/AppsRecyclerAdapter.kt @@ -16,11 +16,10 @@ import androidx.recyclerview.widget.RecyclerView import de.jrpie.android.launcher.Application import de.jrpie.android.launcher.R import de.jrpie.android.launcher.REQUEST_CHOOSE_APP -import de.jrpie.android.launcher.actions.AppAction +import de.jrpie.android.launcher.apps.AbstractDetailedAppInfo import de.jrpie.android.launcher.apps.AppFilter import de.jrpie.android.launcher.apps.AppInfo import de.jrpie.android.launcher.apps.DetailedAppInfo -import de.jrpie.android.launcher.getUserFromId import de.jrpie.android.launcher.preferences.LauncherPreferences import de.jrpie.android.launcher.preferences.ListLayout import de.jrpie.android.launcher.ui.list.ListActivity @@ -47,7 +46,7 @@ class AppsRecyclerAdapter( RecyclerView.Adapter<AppsRecyclerAdapter.ViewHolder>() { private val apps = (activity.applicationContext as Application).apps - private val appsListDisplayed: MutableList<DetailedAppInfo> = mutableListOf() + private val appsListDisplayed: MutableList<AbstractDetailedAppInfo> = mutableListOf() // temporarily disable auto launch var disableAutoLaunch: Boolean = false @@ -83,11 +82,11 @@ class AppsRecyclerAdapter( if (layout.useBadgedText) { appLabel = activity.packageManager.getUserBadgedLabel( appLabel, - getUserFromId(appsListDisplayed[i].app.user, activity) + appsListDisplayed[i].getUser(activity) ).toString() } - val appIcon = appsListDisplayed[i].icon + val appIcon = appsListDisplayed[i].getIcon(activity) viewHolder.textView.text = appLabel viewHolder.img.setImageDrawable(appIcon) @@ -118,22 +117,26 @@ class AppsRecyclerAdapter( @Suppress("SameReturnValue") private fun showOptionsPopup( viewHolder: ViewHolder, - appInfo: DetailedAppInfo + appInfo: AbstractDetailedAppInfo ): Boolean { //create the popup menu val popup = PopupMenu(activity, viewHolder.img) popup.inflate(R.menu.menu_app) - if (appInfo.isSystemApp) { + if (!appInfo.isRemovable()) { popup.menu.findItem(R.id.app_menu_delete).setVisible(false) } - if (LauncherPreferences.apps().hidden()?.contains(appInfo.app) == true) { + if (appInfo !is DetailedAppInfo) { + popup.menu.findItem(R.id.app_menu_info).setVisible(false) + } + + if (LauncherPreferences.apps().hidden()?.contains(appInfo.getRawInfo()) == true) { popup.menu.findItem(R.id.app_menu_hidden).setTitle(R.string.list_app_hidden_remove) } - if (LauncherPreferences.apps().favorites()?.contains(appInfo.app) == true) { + if (LauncherPreferences.apps().favorites()?.contains(appInfo.getRawInfo()) == true) { popup.menu.findItem(R.id.app_menu_favorite).setTitle(R.string.list_app_favorite_remove) } @@ -141,19 +144,19 @@ class AppsRecyclerAdapter( popup.setOnMenuItemClickListener { when (it.itemId) { R.id.app_menu_delete -> { - appInfo.app.uninstall(activity); true + appInfo.getRawInfo().uninstall(activity); true } R.id.app_menu_info -> { - appInfo.app.openSettings(activity); true + (appInfo.getRawInfo() as? AppInfo)?.openSettings(activity); true } R.id.app_menu_favorite -> { - appInfo.app.toggleFavorite(); true + appInfo.getRawInfo().toggleFavorite(); true } R.id.app_menu_hidden -> { - appInfo.app.toggleHidden(root); true + appInfo.getRawInfo().toggleHidden(root); true } R.id.app_menu_rename -> { @@ -188,12 +191,12 @@ class AppsRecyclerAdapter( val appInfo = appsListDisplayed[pos] when (intention) { ListActivity.ListActivityIntention.VIEW -> { - AppAction(appInfo.app).invoke(activity, rect) + appInfo.getAction().invoke(activity, rect) } ListActivity.ListActivityIntention.PICK -> { val returnIntent = Intent() - AppAction(appInfo.app).writeToIntent(returnIntent) + appInfo.getAction().writeToIntent(returnIntent) returnIntent.putExtra("forGesture", forGesture) activity.setResult(REQUEST_CHOOSE_APP, returnIntent) activity.finish() @@ -211,8 +214,8 @@ class AppsRecyclerAdapter( && !disableAutoLaunch && LauncherPreferences.functionality().searchAutoLaunch() ) { - val info = appsListDisplayed[0] - AppAction(info.app).invoke(activity) + val app = appsListDisplayed[0] + app.getAction().invoke(activity) val inputMethodManager = activity.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/ContextMenuActions.kt b/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/ContextMenuActions.kt index 9636dc2..c1f3406 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/ContextMenuActions.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/ContextMenuActions.kt @@ -1,5 +1,6 @@ package de.jrpie.android.launcher.ui.list.apps +import android.app.Activity import android.app.Service import android.content.Context import android.content.Intent @@ -15,7 +16,10 @@ import com.google.android.material.snackbar.Snackbar import de.jrpie.android.launcher.R import de.jrpie.android.launcher.REQUEST_UNINSTALL import de.jrpie.android.launcher.apps.AppInfo +import de.jrpie.android.launcher.apps.AbstractAppInfo +import de.jrpie.android.launcher.apps.AbstractDetailedAppInfo import de.jrpie.android.launcher.apps.DetailedAppInfo +import de.jrpie.android.launcher.apps.PinnedShortcutInfo import de.jrpie.android.launcher.getUserFromId import de.jrpie.android.launcher.preferences.LauncherPreferences @@ -32,27 +36,33 @@ fun AppInfo.openSettings( } } -fun AppInfo.uninstall(activity: android.app.Activity) { - val packageName = this.packageName - val userId = this.user +fun AbstractAppInfo.uninstall(activity: Activity) { + if (this is AppInfo) { + val packageName = this.packageName + val userId = this.user - Log.i(LOG_TAG, "uninstalling $this") + Log.i(LOG_TAG, "uninstalling $this") - val intent = Intent(Intent.ACTION_UNINSTALL_PACKAGE) - intent.data = Uri.parse("package:$packageName") - getUserFromId(userId, activity).let { user -> - intent.putExtra(Intent.EXTRA_USER, user) + val intent = Intent(Intent.ACTION_UNINSTALL_PACKAGE) + intent.data = Uri.parse("package:$packageName") + getUserFromId(userId, activity).let { user -> + intent.putExtra(Intent.EXTRA_USER, user) + } + + intent.putExtra(Intent.EXTRA_RETURN_RESULT, true) + activity.startActivityForResult( + intent, + REQUEST_UNINSTALL + ) + } else if(this is PinnedShortcutInfo) { + val pinned = LauncherPreferences.apps().pinnedShortcuts() ?: mutableSetOf() + pinned.remove(this) + LauncherPreferences.apps().pinnedShortcuts(pinned) } - - intent.putExtra(Intent.EXTRA_RETURN_RESULT, true) - activity.startActivityForResult( - intent, - REQUEST_UNINSTALL - ) } -fun AppInfo.toggleFavorite() { - val favorites: MutableSet<AppInfo> = +fun AbstractAppInfo.toggleFavorite() { + val favorites: MutableSet<AbstractAppInfo> = LauncherPreferences.apps().favorites() ?: mutableSetOf() if (favorites.contains(this)) { @@ -69,8 +79,8 @@ fun AppInfo.toggleFavorite() { /** * @param view: used to show a snackbar letting the user undo the action */ -fun AppInfo.toggleHidden(view: View) { - val hidden: MutableSet<AppInfo> = +fun AbstractAppInfo.toggleHidden(view: View) { + val hidden: MutableSet<AbstractAppInfo> = LauncherPreferences.apps().hidden() ?: mutableSetOf() if (hidden.contains(this)) { hidden.remove(this) @@ -87,9 +97,9 @@ fun AppInfo.toggleHidden(view: View) { LauncherPreferences.apps().hidden(hidden) } -fun DetailedAppInfo.showRenameDialog(context: Context) { +fun AbstractDetailedAppInfo.showRenameDialog(context: Context) { AlertDialog.Builder(context, R.style.AlertDialogCustom).apply { - setTitle(context.getString(R.string.dialog_rename_title, label)) + setTitle(context.getString(R.string.dialog_rename_title, getLabel())) setView(R.layout.dialog_rename_app) setNegativeButton(R.string.dialog_cancel) { d, _ -> d.cancel() } setPositiveButton(R.string.dialog_rename_ok) { d, _ -> @@ -102,7 +112,7 @@ fun DetailedAppInfo.showRenameDialog(context: Context) { }.create().also { it.show() }.apply { val input = findViewById<EditText>(R.id.dialog_rename_app_edit_text) input?.setText(getCustomLabel(context)) - input?.hint = label + input?.hint = getLabel() } } diff --git a/app/src/main/res/layout/activity_pin_shortcut.xml b/app/src/main/res/layout/activity_pin_shortcut.xml index c401b42..5e10118 100644 --- a/app/src/main/res/layout/activity_pin_shortcut.xml +++ b/app/src/main/res/layout/activity_pin_shortcut.xml @@ -80,7 +80,6 @@ android:minHeight="40dp" tools:drawableLeft="@drawable/baseline_settings_24" tools:text="Shortcut name" /> - <!-- <Space android:layout_width="match_parent" android:layout_height="10dp" /> @@ -90,8 +89,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="?android:textColor" + android:checked="true" android:text="@string/pin_shortcut_switch_visible" /> - --> <Space android:layout_width="match_parent" @@ -103,8 +102,21 @@ android:layout_height="wrap_content" android:text="@string/pin_shortcut_button_bind" /> + <Space + android:layout_width="match_parent" + android:layout_height="10dp" /> + </LinearLayout> </ScrollView> + + <Button + android:id="@+id/pin_shortcut_button_ok" + android:layout_margin="10dp" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/pin_shortcut_button_ok" + app:layout_constraintBottom_toBottomOf="parent" /> + </androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml index 9dd7402..a2e4ad6 100644 --- a/app/src/main/res/values/donottranslate.xml +++ b/app/src/main/res/values/donottranslate.xml @@ -11,6 +11,7 @@ <string name="settings_internal_version_code_key" translatable="false">internal.version_code</string> <string name="settings_apps_favorites_key" translatable="false">apps.favorites</string> <string name="settings_apps_hidden_key" translatable="false">apps.hidden</string> + <string name="settings_apps_pinned_shortcuts_key" translatable="false">apps.pinned_shortcuts</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_paused_apps_key" translatable="false">apps.hide_paused_apps</string> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fc5f883..8e13753 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -263,6 +263,7 @@ <!-- Pin shortcuts --> <string name="pin_shortcut_title">Add Shortcut</string> <string name="pin_shortcut_button_bind">Bind to gesture</string> + <string name="pin_shortcut_button_ok">Ok</string> <string name="pin_shortcut_switch_visible">Show in app list</string> <!-- From e39ff62613874bd3c8898e1a21373b404bdad233 Mon Sep 17 00:00:00 2001 From: Vossa Excelencia <nationalistic.tention@hele.win> Date: Tue, 4 Mar 2025 20:33:33 +0000 Subject: [PATCH 07/73] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (253 of 253 strings) Translation: jrpie-Launcher/Launcher Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/pt_BR/ --- app/src/main/res/values-pt-rBR/strings.xml | 30 +++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 0dd41ed..a922186 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -281,4 +281,32 @@ <string name="list_other_list_private_space">Espaço privado</string> <string name="tooltip_lock_private_space">Trancar espaço privado</string> <string name="tooltip_unlock_private_space">Liberar espaço privado</string> -</resources> \ No newline at end of file + <string name="settings_gesture_swipe_larger_reverse"><![CDATA[> (Reverse)]]></string> + <string name="settings_gesture_description_swipe_larger_reverse">Canto inferior esquerdo -> centro direito -> canto superior esquerdo</string> + <string name="settings_gesture_description_swipe_smaller">Canto superior direito -> centro direito -> canto inferior direito</string> + <string name="settings_gesture_swipe_smaller_reverse"><![CDATA[< (Reverse)]]></string> + <string name="settings_gesture_description_swipe_v">Canto superior esquerdo -> centro médio -> canto superior direito</string> + <string name="settings_gesture_description_swipe_v_reverse">Canto superior direito -> centro médio -> canto superior esquerdo</string> + <string name="settings_gesture_swipe_v_reverse">V (invertido)</string> + <string name="settings_gesture_description_swipe_lambda">Inferior esquerdo -> superior médio -> inferior direito</string> + <string name="settings_gesture_swipe_lambda_reverse">Λ (invertido)</string> + <string name="settings_gesture_swipe_larger"><![CDATA[>]]></string> + <string name="settings_gesture_swipe_smaller"><![CDATA[<]]></string> + <string name="settings_gesture_swipe_v">V</string> + <string name="settings_gesture_swipe_lambda">Λ</string> + <string name="settings_gesture_description_swipe_larger">Canto superior esquerdo -> centro direito -> canto inferior esquerdo</string> + <string name="settings_gesture_tap_up">Toque + pra cima</string> + <string name="settings_gesture_description_tap_up">Toque e deslize pra cima</string> + <string name="settings_gesture_tap_down">Toque + pra baixo</string> + <string name="settings_gesture_description_tap_down">Toque e deslize pra baixo</string> + <string name="settings_gesture_tap_left">Toque + esquerda</string> + <string name="settings_gesture_description_tap_left">Toque e deslize pra esquerda</string> + <string name="settings_gesture_tap_right">Toque + direita</string> + <string name="settings_gesture_description_tap_right">Toque e deslize pra direita</string> + <string name="pin_shortcut_title">Adicionar atalho</string> + <string name="pin_shortcut_button_bind">Vincular ao gesto</string> + <string name="pin_shortcut_switch_visible">Mostrar na lista de apps</string> + <string name="list_other_track_play_pause">Música: Reproduzir / Pausar</string> + <string name="settings_gesture_description_swipe_smaller_reverse">Canto inferior direito -> centro esquerdo -> canto superior direito</string> + <string name="settings_gesture_description_swipe_lambda_reverse">Inferior direito -> superior médio -> inferior esquerdo</string> +</resources> From 55a54fb9a57deca0789b1304fa741d4bceba5e09 Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Wed, 5 Mar 2025 00:31:43 +0100 Subject: [PATCH 08/73] implement #45: show pinned shortcuts in app list --- .../de/jrpie/android/launcher/Application.kt | 12 +-- .../de/jrpie/android/launcher/Functions.kt | 33 +++++-- .../android/launcher/actions/AppAction.kt | 4 +- .../launcher/actions/ShortcutAction.kt | 2 +- .../android/launcher/apps/AbstractAppInfo.kt | 22 +++++ .../launcher/apps/AbstractDetailedAppInfo.kt | 42 +++++++++ .../jrpie/android/launcher/apps/AppFilter.kt | 28 +++--- .../de/jrpie/android/launcher/apps/AppInfo.kt | 18 +--- .../android/launcher/apps/DetailedAppInfo.kt | 63 ++++++++------ .../apps/DetailedPinnedShortcutInfo.kt | 66 ++++++++++++++ .../shortcuts => apps}/PinnedShortcutInfo.kt | 6 +- .../LauncherPreferences$Config.java | 12 +-- .../launcher/preferences/Preferences.kt | 17 ++-- .../launcher/preferences/legacy/Version1.kt | 17 +++- .../launcher/preferences/legacy/Version2.kt | 2 +- .../launcher/preferences/legacy/Version3.kt | 85 +++++++++++++++++++ .../serialization/PreferenceSerializers.kt | 52 ++++++++---- .../launcher/ui/PinShortcutActivity.kt | 24 +++++- .../ui/list/apps/AppsRecyclerAdapter.kt | 37 ++++---- .../ui/list/apps/ContextMenuActions.kt | 52 +++++++----- .../main/res/layout/activity_pin_shortcut.xml | 16 +++- app/src/main/res/values/donottranslate.xml | 1 + app/src/main/res/values/strings.xml | 1 + 23 files changed, 474 insertions(+), 138 deletions(-) create mode 100644 app/src/main/java/de/jrpie/android/launcher/apps/AbstractAppInfo.kt create mode 100644 app/src/main/java/de/jrpie/android/launcher/apps/AbstractDetailedAppInfo.kt create mode 100644 app/src/main/java/de/jrpie/android/launcher/apps/DetailedPinnedShortcutInfo.kt rename app/src/main/java/de/jrpie/android/launcher/{actions/shortcuts => apps}/PinnedShortcutInfo.kt (93%) create mode 100644 app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version3.kt 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 810fceb..09229ab 100644 --- a/app/src/main/java/de/jrpie/android/launcher/Application.kt +++ b/app/src/main/java/de/jrpie/android/launcher/Application.kt @@ -15,15 +15,15 @@ import androidx.core.content.ContextCompat import androidx.lifecycle.MutableLiveData import androidx.preference.PreferenceManager import de.jrpie.android.launcher.actions.TorchManager -import de.jrpie.android.launcher.apps.AppInfo -import de.jrpie.android.launcher.apps.DetailedAppInfo +import de.jrpie.android.launcher.apps.AbstractAppInfo +import de.jrpie.android.launcher.apps.AbstractDetailedAppInfo import de.jrpie.android.launcher.apps.isPrivateSpaceLocked import de.jrpie.android.launcher.preferences.LauncherPreferences import de.jrpie.android.launcher.preferences.migratePreferencesToNewVersion import de.jrpie.android.launcher.preferences.resetPreferences class Application : android.app.Application() { - val apps = MutableLiveData<List<DetailedAppInfo>>() + val apps = MutableLiveData<List<AbstractDetailedAppInfo>>() val privateSpaceLocked = MutableLiveData<Boolean>() private val profileAvailabilityBroadcastReceiver = object : BroadcastReceiver() { @@ -82,10 +82,12 @@ class Application : android.app.Application() { } var torchManager: TorchManager? = null - private var customAppNames: HashMap<AppInfo, String>? = null + private var customAppNames: HashMap<AbstractAppInfo, String>? = null private val listener = SharedPreferences.OnSharedPreferenceChangeListener { _, pref -> if (pref == getString(R.string.settings_apps_custom_names_key)) { customAppNames = LauncherPreferences.apps().customNames() + } else if (pref == LauncherPreferences.apps().keys().pinnedShortcuts()) { + loadApps() } } @@ -143,7 +145,7 @@ class Application : android.app.Application() { loadApps() } - fun getCustomAppNames(): HashMap<AppInfo, String> { + fun getCustomAppNames(): HashMap<AbstractAppInfo, String> { return (customAppNames ?: LauncherPreferences.apps().customNames() ?: HashMap()) .also { customAppNames = it } } 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 8fc95a3..8f5e08d 100644 --- a/app/src/main/java/de/jrpie/android/launcher/Functions.kt +++ b/app/src/main/java/de/jrpie/android/launcher/Functions.kt @@ -24,9 +24,12 @@ import androidx.annotation.RequiresApi import de.jrpie.android.launcher.actions.Action import de.jrpie.android.launcher.actions.Gesture import de.jrpie.android.launcher.actions.ShortcutAction -import de.jrpie.android.launcher.actions.shortcuts.PinnedShortcutInfo +import de.jrpie.android.launcher.apps.AbstractAppInfo.Companion.INVALID_USER +import de.jrpie.android.launcher.apps.AbstractDetailedAppInfo import de.jrpie.android.launcher.apps.AppInfo import de.jrpie.android.launcher.apps.DetailedAppInfo +import de.jrpie.android.launcher.apps.DetailedPinnedShortcutInfo +import de.jrpie.android.launcher.apps.PinnedShortcutInfo import de.jrpie.android.launcher.apps.getPrivateSpaceUser import de.jrpie.android.launcher.apps.isPrivateSpaceSupported import de.jrpie.android.launcher.preferences.LauncherPreferences @@ -99,9 +102,10 @@ fun removeUnusedShortcuts(context: Context) { } val userManager = context.getSystemService(Service.USER_SERVICE) as UserManager - val boundActions: Set<PinnedShortcutInfo> = + val boundActions: MutableSet<PinnedShortcutInfo> = Gesture.entries.mapNotNull { Action.forGesture(it) as? ShortcutAction }.map { it.shortcut } - .toSet() + .toMutableSet() + LauncherPreferences.apps().pinnedShortcuts()?.let { boundActions.addAll(it) } try { userManager.userProfiles.filter { !userManager.isQuietModeEnabled(it) }.forEach { profile -> getShortcuts(profile)?.groupBy { it.`package` }?.forEach { (p, shortcuts) -> @@ -135,9 +139,12 @@ fun openTutorial(context: Context) { /** * Load all apps. */ -fun getApps(packageManager: PackageManager, context: Context): MutableList<DetailedAppInfo> { - val start = System.currentTimeMillis() - val loadList = mutableListOf<DetailedAppInfo>() +fun getApps( + packageManager: PackageManager, + context: Context +): MutableList<AbstractDetailedAppInfo> { + var start = System.currentTimeMillis() + val loadList = mutableListOf<AbstractDetailedAppInfo>() val launcherApps = context.getSystemService(Service.LAUNCHER_APPS_SERVICE) as LauncherApps val userManager = context.getSystemService(Service.USER_SERVICE) as UserManager @@ -174,7 +181,7 @@ fun getApps(packageManager: PackageManager, context: Context): MutableList<Detai i.addCategory(Intent.CATEGORY_LAUNCHER) val allApps = packageManager.queryIntentActivities(i, 0) for (ri in allApps) { - val app = AppInfo(ri.activityInfo.packageName, null, AppInfo.INVALID_USER) + val app = AppInfo(ri.activityInfo.packageName, null, INVALID_USER) val detailedAppInfo = DetailedAppInfo( app, ri.loadLabel(packageManager), @@ -186,8 +193,18 @@ fun getApps(packageManager: PackageManager, context: Context): MutableList<Detai } loadList.sortBy { it.getCustomLabel(context).toString() } - val end = System.currentTimeMillis() + var end = System.currentTimeMillis() Log.i(LOG_TAG, "${loadList.size} apps loaded (${end - start}ms)") + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) { + start = System.currentTimeMillis() + LauncherPreferences.apps().pinnedShortcuts() + ?.mapNotNull { DetailedPinnedShortcutInfo.fromPinnedShortcutInfo(it, context) } + ?.let { + end = System.currentTimeMillis() + Log.i(LOG_TAG, "${it.size} shortcuts loaded (${end - start}ms)") + loadList.addAll(it) + } + } return loadList } diff --git a/app/src/main/java/de/jrpie/android/launcher/actions/AppAction.kt b/app/src/main/java/de/jrpie/android/launcher/actions/AppAction.kt index 90145aa..1446b13 100644 --- a/app/src/main/java/de/jrpie/android/launcher/actions/AppAction.kt +++ b/app/src/main/java/de/jrpie/android/launcher/actions/AppAction.kt @@ -11,7 +11,7 @@ import android.graphics.drawable.Drawable import android.util.Log import de.jrpie.android.launcher.R import de.jrpie.android.launcher.apps.AppInfo -import de.jrpie.android.launcher.apps.AppInfo.Companion.INVALID_USER +import de.jrpie.android.launcher.apps.AbstractAppInfo.Companion.INVALID_USER import de.jrpie.android.launcher.apps.DetailedAppInfo import de.jrpie.android.launcher.ui.list.apps.openSettings import kotlinx.serialization.SerialName @@ -67,7 +67,7 @@ class AppAction(val app: AppInfo) : Action { } override fun getIcon(context: Context): Drawable? { - return DetailedAppInfo.fromAppInfo(app, context)?.icon + return DetailedAppInfo.fromAppInfo(app, context)?.getIcon(context) } override fun isAvailable(context: Context): Boolean { diff --git a/app/src/main/java/de/jrpie/android/launcher/actions/ShortcutAction.kt b/app/src/main/java/de/jrpie/android/launcher/actions/ShortcutAction.kt index 8517b1a..a89f9e2 100644 --- a/app/src/main/java/de/jrpie/android/launcher/actions/ShortcutAction.kt +++ b/app/src/main/java/de/jrpie/android/launcher/actions/ShortcutAction.kt @@ -6,7 +6,7 @@ import android.content.pm.LauncherApps import android.graphics.Rect import android.graphics.drawable.Drawable import android.os.Build -import de.jrpie.android.launcher.actions.shortcuts.PinnedShortcutInfo +import de.jrpie.android.launcher.apps.PinnedShortcutInfo import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable diff --git a/app/src/main/java/de/jrpie/android/launcher/apps/AbstractAppInfo.kt b/app/src/main/java/de/jrpie/android/launcher/apps/AbstractAppInfo.kt new file mode 100644 index 0000000..dd60752 --- /dev/null +++ b/app/src/main/java/de/jrpie/android/launcher/apps/AbstractAppInfo.kt @@ -0,0 +1,22 @@ +package de.jrpie.android.launcher.apps + +import kotlinx.serialization.Serializable +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json + +/** + * This interface is implemented by [AppInfo] and [PinnedShortcutInfo]. + */ +@Serializable +sealed interface AbstractAppInfo { + fun serialize(): String { + return Json.encodeToString(this) + } + companion object { + const val INVALID_USER = -1 + + fun deserialize(serialized: String): AbstractAppInfo { + return Json.decodeFromString(serialized) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/de/jrpie/android/launcher/apps/AbstractDetailedAppInfo.kt b/app/src/main/java/de/jrpie/android/launcher/apps/AbstractDetailedAppInfo.kt new file mode 100644 index 0000000..9c7413d --- /dev/null +++ b/app/src/main/java/de/jrpie/android/launcher/apps/AbstractDetailedAppInfo.kt @@ -0,0 +1,42 @@ +package de.jrpie.android.launcher.apps + +import android.content.Context +import android.graphics.drawable.Drawable +import android.os.UserHandle +import android.util.Log +import de.jrpie.android.launcher.Application +import de.jrpie.android.launcher.actions.Action +import de.jrpie.android.launcher.preferences.LauncherPreferences + +/** + * This interface is implemented by [DetailedAppInfo] and [DetailedPinnedShortcutInfo] + */ +sealed interface AbstractDetailedAppInfo { + fun getRawInfo(): AbstractAppInfo + fun getLabel(): String + fun getIcon(context: Context): Drawable + fun getUser(context: Context): UserHandle + fun isPrivate(): Boolean + fun isRemovable(): Boolean + fun getAction(): Action + + + fun getCustomLabel(context: Context): String { + val map = (context.applicationContext as? Application)?.getCustomAppNames() + return map?.get(getRawInfo()) ?: getLabel() + } + + + fun setCustomLabel(label: CharSequence?) { + Log.i("Launcher", "Setting custom label for ${this.getRawInfo()} to ${label}.") + val map = LauncherPreferences.apps().customNames() ?: HashMap<AbstractAppInfo, String>() + + if (label.isNullOrEmpty()) { + map.remove(getRawInfo()) + } else { + map[getRawInfo()] = label.toString() + } + LauncherPreferences.apps().customNames(map) + } + +} \ No newline at end of file diff --git a/app/src/main/java/de/jrpie/android/launcher/apps/AppFilter.kt b/app/src/main/java/de/jrpie/android/launcher/apps/AppFilter.kt index ecc7eaa..ca387c0 100644 --- a/app/src/main/java/de/jrpie/android/launcher/apps/AppFilter.kt +++ b/app/src/main/java/de/jrpie/android/launcher/apps/AppFilter.kt @@ -6,6 +6,7 @@ import android.os.Build import de.jrpie.android.launcher.actions.Action import de.jrpie.android.launcher.actions.AppAction import de.jrpie.android.launcher.actions.Gesture +import de.jrpie.android.launcher.actions.ShortcutAction import de.jrpie.android.launcher.preferences.LauncherPreferences import java.util.Locale import kotlin.text.Regex.Companion.escape @@ -18,13 +19,14 @@ class AppFilter( var privateSpaceVisibility: AppSetVisibility = AppSetVisibility.VISIBLE ) { - operator fun invoke(apps: List<DetailedAppInfo>): List<DetailedAppInfo> { + operator fun invoke(apps: List<AbstractDetailedAppInfo>): List<AbstractDetailedAppInfo> { var apps = - apps.sortedBy { app -> app.getCustomLabel(context).toString().lowercase(Locale.ROOT) } + apps.sortedBy { app -> app.getCustomLabel(context).lowercase(Locale.ROOT) } val hidden = LauncherPreferences.apps().hidden() ?: setOf() val favorites = LauncherPreferences.apps().favorites() ?: setOf() - val private = apps.filter { it.isPrivateSpaceApp }.map { it.app }.toSet() + val private = apps.filter { it.isPrivate() } + .map { it.getRawInfo() }.toSet() apps = apps.filter { info -> favoritesVisibility.predicate(favorites, info) @@ -35,9 +37,13 @@ class AppFilter( if (LauncherPreferences.apps().hideBoundApps()) { val boundApps = Gesture.entries .filter(Gesture::isEnabled) - .mapNotNull { g -> (Action.forGesture(g) as? AppAction)?.app } + .mapNotNull { g -> Action.forGesture(g) } + .mapNotNull { + (it as? AppAction)?.app + ?: (it as? ShortcutAction)?.shortcut + } .toSet() - apps = apps.filterNot { info -> boundApps.contains(info.app) } + apps = apps.filterNot { info -> boundApps.contains(info.getRawInfo()) } } // normalize text for search @@ -57,11 +63,11 @@ class AppFilter( if (query.isEmpty()) { return apps } else { - val r: MutableList<DetailedAppInfo> = ArrayList() - val appsSecondary: MutableList<DetailedAppInfo> = ArrayList() + val r: MutableList<AbstractDetailedAppInfo> = ArrayList() + val appsSecondary: MutableList<AbstractDetailedAppInfo> = ArrayList() val normalizedQuery: String = normalize(query) for (item in apps) { - val itemLabel: String = normalize(item.getCustomLabel(context).toString()) + val itemLabel: String = normalize(item.getCustomLabel(context)) if (itemLabel.startsWith(normalizedQuery)) { r.add(item) @@ -77,11 +83,11 @@ class AppFilter( companion object { enum class AppSetVisibility( - val predicate: (set: Set<AppInfo>, DetailedAppInfo) -> Boolean + val predicate: (set: Set<AbstractAppInfo>, AbstractDetailedAppInfo) -> Boolean ) { VISIBLE({ _, _ -> true }), - HIDDEN({ set, appInfo -> !set.contains(appInfo.app) }), - EXCLUSIVE({ set, appInfo -> set.contains(appInfo.app) }), + HIDDEN({ set, appInfo -> !set.contains(appInfo.getRawInfo()) }), + EXCLUSIVE({ set, appInfo -> set.contains(appInfo.getRawInfo()) }), ; } diff --git a/app/src/main/java/de/jrpie/android/launcher/apps/AppInfo.kt b/app/src/main/java/de/jrpie/android/launcher/apps/AppInfo.kt index 21614f8..944cfaa 100644 --- a/app/src/main/java/de/jrpie/android/launcher/apps/AppInfo.kt +++ b/app/src/main/java/de/jrpie/android/launcher/apps/AppInfo.kt @@ -4,21 +4,18 @@ import android.app.Service import android.content.Context import android.content.pm.LauncherActivityInfo import android.content.pm.LauncherApps +import de.jrpie.android.launcher.apps.AbstractAppInfo.Companion.INVALID_USER import de.jrpie.android.launcher.getUserFromId +import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.Json /** * Represents an app installed on the users device. * Contains the minimal amount of data required to identify the app. */ @Serializable -class AppInfo(val packageName: String, val activityName: String?, val user: Int = INVALID_USER) { - - fun serialize(): String { - return Json.encodeToString(this) - } +@SerialName("app") +class AppInfo(val packageName: String, val activityName: String?, val user: Int = INVALID_USER): AbstractAppInfo { override fun equals(other: Any?): Boolean { if(other is AppInfo) { @@ -47,11 +44,4 @@ class AppInfo(val packageName: String, val activityName: String?, val user: Int return "AppInfo {package=$packageName, activity=$activityName, user=$user}" } - companion object { - const val INVALID_USER = -1 - - fun deserialize(serialized: String): AppInfo { - return Json.decodeFromString(serialized) - } - } } \ No newline at end of file diff --git a/app/src/main/java/de/jrpie/android/launcher/apps/DetailedAppInfo.kt b/app/src/main/java/de/jrpie/android/launcher/apps/DetailedAppInfo.kt index d77bf93..76f7fbb 100644 --- a/app/src/main/java/de/jrpie/android/launcher/apps/DetailedAppInfo.kt +++ b/app/src/main/java/de/jrpie/android/launcher/apps/DetailedAppInfo.kt @@ -4,20 +4,21 @@ import android.content.Context import android.content.pm.ApplicationInfo import android.content.pm.LauncherActivityInfo import android.graphics.drawable.Drawable -import android.util.Log -import de.jrpie.android.launcher.Application -import de.jrpie.android.launcher.preferences.LauncherPreferences +import android.os.UserHandle +import de.jrpie.android.launcher.actions.Action +import de.jrpie.android.launcher.actions.AppAction +import de.jrpie.android.launcher.getUserFromId /** * Stores information used to create [de.jrpie.android.launcher.ui.list.apps.AppsRecyclerAdapter] rows. */ class DetailedAppInfo( - val app: AppInfo, - val label: CharSequence, - val icon: Drawable, - val isPrivateSpaceApp: Boolean, - val isSystemApp: Boolean = false, -) { + private val app: AppInfo, + private val label: CharSequence, + private val icon: Drawable, + private val privateSpace: Boolean, + private val removable: Boolean = true, +): AbstractDetailedAppInfo { constructor(activityInfo: LauncherActivityInfo, private: Boolean) : this( AppInfo( @@ -28,29 +29,41 @@ class DetailedAppInfo( activityInfo.label, activityInfo.getBadgedIcon(0), private, - activityInfo.applicationInfo.flags.and(ApplicationInfo.FLAG_SYSTEM) != 0 + // App can be uninstalled iff it is not a system app + activityInfo.applicationInfo.flags.and(ApplicationInfo.FLAG_SYSTEM) == 0 ) - fun getCustomLabel(context: Context): CharSequence { - val map = (context.applicationContext as? Application)?.getCustomAppNames() ?: return label - return map[app] ?: label + + override fun getLabel(): String { + return label.toString() } - fun setCustomLabel(label: CharSequence?) { - - Log.i("Launcher", "Setting custom label for ${this.app} to ${label}.") - val map = LauncherPreferences.apps().customNames() ?: HashMap<AppInfo, String>() - - if (label.isNullOrEmpty()) { - map.remove(app) - } else { - map[app] = label.toString() - } - - LauncherPreferences.apps().customNames(map) + override fun getIcon(context: Context): Drawable { + return icon } + override fun getRawInfo(): AppInfo { + return app + } + + override fun getUser(context: Context): UserHandle { + return getUserFromId(app.user, context) + } + + override fun isPrivate(): Boolean { + return privateSpace + } + + override fun isRemovable(): Boolean { + return removable + } + + override fun getAction(): Action { + return AppAction(app) + } + + companion object { fun fromAppInfo(appInfo: AppInfo, context: Context): DetailedAppInfo? { return appInfo.getLauncherActivityInfo(context)?.let { diff --git a/app/src/main/java/de/jrpie/android/launcher/apps/DetailedPinnedShortcutInfo.kt b/app/src/main/java/de/jrpie/android/launcher/apps/DetailedPinnedShortcutInfo.kt new file mode 100644 index 0000000..f66034d --- /dev/null +++ b/app/src/main/java/de/jrpie/android/launcher/apps/DetailedPinnedShortcutInfo.kt @@ -0,0 +1,66 @@ +package de.jrpie.android.launcher.apps + +import android.app.Service +import android.content.Context +import android.content.pm.LauncherApps +import android.content.pm.ShortcutInfo +import android.graphics.drawable.Drawable +import android.os.Build +import android.os.UserHandle +import androidx.annotation.RequiresApi +import de.jrpie.android.launcher.actions.Action +import de.jrpie.android.launcher.actions.ShortcutAction +import de.jrpie.android.launcher.getUserFromId + +@RequiresApi(Build.VERSION_CODES.N_MR1) +class DetailedPinnedShortcutInfo( + private val shortcutInfo: PinnedShortcutInfo, + private val label: String, + private val icon: Drawable, + private val privateSpace: Boolean +) : AbstractDetailedAppInfo { + + constructor(context: Context, shortcut: ShortcutInfo) : this( + PinnedShortcutInfo(shortcut), + shortcut.longLabel.toString(), + (context.getSystemService(Service.LAUNCHER_APPS_SERVICE) as LauncherApps) + .getShortcutBadgedIconDrawable(shortcut, 0), + shortcut.userHandle == getPrivateSpaceUser(context) + ) + + override fun getRawInfo(): AbstractAppInfo { + return shortcutInfo + } + + override fun getLabel(): String { + return label + } + + override fun getIcon(context: Context): Drawable { + return icon + } + + override fun getUser(context: Context): UserHandle { + return getUserFromId(shortcutInfo.user, context) + } + + override fun isPrivate(): Boolean { + return privateSpace + } + + override fun isRemovable(): Boolean { + return true + } + + override fun getAction(): Action { + return ShortcutAction(shortcutInfo) + } + + companion object { + fun fromPinnedShortcutInfo(shortcutInfo: PinnedShortcutInfo, context: Context): DetailedPinnedShortcutInfo? { + return shortcutInfo.getShortcutInfo(context)?.let { + DetailedPinnedShortcutInfo(context, it) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/de/jrpie/android/launcher/actions/shortcuts/PinnedShortcutInfo.kt b/app/src/main/java/de/jrpie/android/launcher/apps/PinnedShortcutInfo.kt similarity index 93% rename from app/src/main/java/de/jrpie/android/launcher/actions/shortcuts/PinnedShortcutInfo.kt rename to app/src/main/java/de/jrpie/android/launcher/apps/PinnedShortcutInfo.kt index 796c737..a2815e5 100644 --- a/app/src/main/java/de/jrpie/android/launcher/actions/shortcuts/PinnedShortcutInfo.kt +++ b/app/src/main/java/de/jrpie/android/launcher/apps/PinnedShortcutInfo.kt @@ -1,4 +1,4 @@ -package de.jrpie.android.launcher.actions.shortcuts +package de.jrpie.android.launcher.apps import android.app.Service import android.content.ComponentName @@ -9,17 +9,19 @@ import android.content.pm.ShortcutInfo import android.os.Build import androidx.annotation.RequiresApi import de.jrpie.android.launcher.getUserFromId +import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @RequiresApi(Build.VERSION_CODES.N_MR1) @Serializable +@SerialName("shortcut") class PinnedShortcutInfo( val id: String, val packageName: String, val activityName: String, val user: Int -) { +): AbstractAppInfo { constructor(info: ShortcutInfo) : this(info.id, info.`package`, info.activity?.className ?: "", info.userHandle.hashCode()) 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 19362c2..9be85ab 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,9 @@ 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.MapAppInfoStringPreferenceSerializer; -import de.jrpie.android.launcher.preferences.serialization.SetAppInfoPreferenceSerializer; +import de.jrpie.android.launcher.preferences.serialization.MapAbstractAppInfoStringPreferenceSerializer; +import de.jrpie.android.launcher.preferences.serialization.SetAbstractAppInfoPreferenceSerializer; +import de.jrpie.android.launcher.preferences.serialization.SetPinnedShortcutInfoPreferenceSerializer; import de.jrpie.android.launcher.preferences.theme.Background; import de.jrpie.android.launcher.preferences.theme.ColorTheme; import de.jrpie.android.launcher.preferences.theme.Font; @@ -25,9 +26,10 @@ import eu.jonahbauer.android.preference.annotations.Preferences; @Preference(name = "version_code", type = int.class, defaultValue = "-1"), }), @PreferenceGroup(name = "apps", prefix = "settings_apps_", suffix = "_key", value = { - @Preference(name = "favorites", 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 = "favorites", type = Set.class, serializer = SetAbstractAppInfoPreferenceSerializer.class), + @Preference(name = "hidden", type = Set.class, serializer = SetAbstractAppInfoPreferenceSerializer.class), + @Preference(name = "pinned_shortcuts", type = Set.class, serializer = SetPinnedShortcutInfoPreferenceSerializer.class), + @Preference(name = "custom_names", type = HashMap.class, serializer = MapAbstractAppInfoStringPreferenceSerializer.class), @Preference(name = "hide_bound_apps", type = boolean.class, defaultValue = "false"), @Preference(name = "hide_paused_apps", type = boolean.class, defaultValue = "false"), @Preference(name = "hide_private_space_apps", type = boolean.class, defaultValue = "false"), diff --git a/app/src/main/java/de/jrpie/android/launcher/preferences/Preferences.kt b/app/src/main/java/de/jrpie/android/launcher/preferences/Preferences.kt index 9460125..59ecc7a 100644 --- a/app/src/main/java/de/jrpie/android/launcher/preferences/Preferences.kt +++ b/app/src/main/java/de/jrpie/android/launcher/preferences/Preferences.kt @@ -5,9 +5,12 @@ import android.util.Log import de.jrpie.android.launcher.BuildConfig import de.jrpie.android.launcher.actions.Action import de.jrpie.android.launcher.apps.AppInfo +import de.jrpie.android.launcher.apps.AbstractAppInfo +import de.jrpie.android.launcher.apps.AbstractAppInfo.Companion.INVALID_USER import de.jrpie.android.launcher.apps.DetailedAppInfo import de.jrpie.android.launcher.preferences.legacy.migratePreferencesFromVersion1 import de.jrpie.android.launcher.preferences.legacy.migratePreferencesFromVersion2 +import de.jrpie.android.launcher.preferences.legacy.migratePreferencesFromVersion3 import de.jrpie.android.launcher.preferences.legacy.migratePreferencesFromVersionUnknown import de.jrpie.android.launcher.ui.HomeActivity @@ -15,7 +18,7 @@ import de.jrpie.android.launcher.ui.HomeActivity * Increase when breaking changes are introduced and write an appropriate case in * `migratePreferencesToNewVersion` */ -const val PREFERENCE_VERSION = 3 +const val PREFERENCE_VERSION = 4 const val UNKNOWN_PREFERENCE_VERSION = -1 private const val TAG = "Launcher - Preferences" @@ -44,6 +47,10 @@ fun migratePreferencesToNewVersion(context: Context) { migratePreferencesFromVersion2() Log.i(TAG, "migration of preferences complete (2 -> ${PREFERENCE_VERSION}).") } + 3 -> { + migratePreferencesFromVersion3() + Log.i(TAG, "migration of preferences complete (3 -> ${PREFERENCE_VERSION}).") + } else -> { Log.w( @@ -66,16 +73,16 @@ fun resetPreferences(context: Context) { LauncherPreferences.internal().versionCode(PREFERENCE_VERSION) - val hidden: MutableSet<AppInfo> = mutableSetOf() + val hidden: MutableSet<AbstractAppInfo> = mutableSetOf() val launcher = DetailedAppInfo.fromAppInfo( AppInfo( BuildConfig.APPLICATION_ID, HomeActivity::class.java.name, - AppInfo.INVALID_USER + INVALID_USER ), context ) - launcher?.app?.let { hidden.add(it) } - Log.i(TAG,"Hiding ${launcher?.app}") + launcher?.getRawInfo()?.let { hidden.add(it) } + Log.i(TAG,"Hiding ${launcher?.getRawInfo()}") LauncherPreferences.apps().hidden(hidden) Action.resetToDefaultActions(context) diff --git a/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version1.kt b/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version1.kt index a61980a..6408b70 100644 --- a/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version1.kt +++ b/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version1.kt @@ -5,15 +5,26 @@ import de.jrpie.android.launcher.actions.AppAction import de.jrpie.android.launcher.actions.Gesture import de.jrpie.android.launcher.actions.LauncherAction import de.jrpie.android.launcher.apps.AppInfo -import de.jrpie.android.launcher.apps.AppInfo.Companion.INVALID_USER +import de.jrpie.android.launcher.apps.AbstractAppInfo.Companion.INVALID_USER import de.jrpie.android.launcher.preferences.LauncherPreferences import de.jrpie.android.launcher.preferences.PREFERENCE_VERSION -import de.jrpie.android.launcher.preferences.serialization.MapAppInfoStringPreferenceSerializer +import kotlinx.serialization.Serializable import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json import org.json.JSONException import org.json.JSONObject + +@Serializable +private class LegacyMapEntry(val key: AppInfo, val value: String) + +private fun serializeMapAppInfo(value: Map<AppInfo, String>?): Set<String>? { + return value?.map { (key, value) -> + Json.encodeToString(LegacyMapEntry(key, value)) + }?.toSet() +} + + val oldLauncherActionIds: Map<String, LauncherAction> = mapOf( Pair("launcher:settings", LauncherAction.SETTINGS), @@ -77,7 +88,7 @@ private fun Action.Companion.legacyFromPreference(id: String): Action? { private fun migrateAppInfoStringMap(key: String) { val preferences = LauncherPreferences.getSharedPreferences() - MapAppInfoStringPreferenceSerializer().serialize( + serializeMapAppInfo( preferences.getStringSet(key, setOf())?.mapNotNull { entry -> try { val obj = JSONObject(entry) diff --git a/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version2.kt b/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version2.kt index bcac3ae..4e6eae1 100644 --- a/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version2.kt +++ b/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version2.kt @@ -12,9 +12,9 @@ import de.jrpie.android.launcher.preferences.PREFERENCE_VERSION * (see [PREFERENCE_VERSION]) */ fun migratePreferencesFromVersion2() { - assert(PREFERENCE_VERSION == 3) assert(LauncherPreferences.internal().versionCode() == 2) // previously there was no setting for this Action.setActionForGesture(Gesture.BACK, LauncherAction.CHOOSE) LauncherPreferences.internal().versionCode(3) + migratePreferencesFromVersion3() } \ No newline at end of file diff --git a/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version3.kt b/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version3.kt new file mode 100644 index 0000000..7698e62 --- /dev/null +++ b/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version3.kt @@ -0,0 +1,85 @@ +package de.jrpie.android.launcher.preferences.legacy + +import android.content.SharedPreferences +import android.content.SharedPreferences.Editor +import de.jrpie.android.launcher.apps.AppInfo +import de.jrpie.android.launcher.apps.AbstractAppInfo +import de.jrpie.android.launcher.preferences.LauncherPreferences +import de.jrpie.android.launcher.preferences.PREFERENCE_VERSION +import de.jrpie.android.launcher.preferences.serialization.MapAbstractAppInfoStringPreferenceSerializer +import de.jrpie.android.launcher.preferences.serialization.SetAbstractAppInfoPreferenceSerializer +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.Json +import java.util.HashSet + +/** + * Migrate preferences from version 3 (used until version 0.0.23) to the current format + * (see [PREFERENCE_VERSION]) + */ + + +fun deserializeSet(value: Set<String>?): Set<AppInfo>? { + return value?.map { + Json.decodeFromString<AppInfo>(it) + }?.toHashSet() +} + +fun deserializeMap(value: Set<String>?): HashMap<AppInfo, String>? { + return value?.associateTo(HashMap()) { + val entry = Json.decodeFromString<MapEntry>(it) + Pair(entry.key, entry.value) + } +} + +@Serializable +private class MapEntry(val key: AppInfo, val value: String) + +private fun migrateSetAppInfo(key: String, preferences: SharedPreferences, editor: Editor) { + try { + val serializer = SetAbstractAppInfoPreferenceSerializer() + val set = HashSet<AbstractAppInfo>() + + deserializeSet(preferences.getStringSet(key, null))?.let { + set.addAll(it) + } + editor.putStringSet( + key, + serializer.serialize(set as java.util.Set<AbstractAppInfo>) as Set<String>? + ) + } catch (e: Exception) { + e.printStackTrace() + editor.putStringSet(key, null) + } + +} +private fun migrateMapAppInfoString(key: String, preferences: SharedPreferences, editor: Editor ) { + try { + val serializer = MapAbstractAppInfoStringPreferenceSerializer() + val map = HashMap<AbstractAppInfo, String>() + + deserializeMap(preferences.getStringSet(key, null))?.let { + map.putAll(it) + } + editor.putStringSet(key, serializer.serialize(map) as Set<String>?) + } catch (e: Exception) { + e.printStackTrace() + editor.putStringSet(key, null) + } +} + +fun migratePreferencesFromVersion3() { + assert(PREFERENCE_VERSION == 4) + assert(LauncherPreferences.internal().versionCode() == 3) + + val preferences = LauncherPreferences.getSharedPreferences() + val editor = preferences.edit() + migrateSetAppInfo(LauncherPreferences.apps().keys().favorites(), preferences, editor) + migrateSetAppInfo(LauncherPreferences.apps().keys().hidden(), preferences, editor) + migrateMapAppInfoString(LauncherPreferences.apps().keys().customNames(), preferences, editor) + + editor.apply() + + + + LauncherPreferences.internal().versionCode(4) +} \ No newline at end of file diff --git a/app/src/main/java/de/jrpie/android/launcher/preferences/serialization/PreferenceSerializers.kt b/app/src/main/java/de/jrpie/android/launcher/preferences/serialization/PreferenceSerializers.kt index 041fe4d..3e19daf 100644 --- a/app/src/main/java/de/jrpie/android/launcher/preferences/serialization/PreferenceSerializers.kt +++ b/app/src/main/java/de/jrpie/android/launcher/preferences/serialization/PreferenceSerializers.kt @@ -2,7 +2,8 @@ package de.jrpie.android.launcher.preferences.serialization -import de.jrpie.android.launcher.apps.AppInfo +import de.jrpie.android.launcher.apps.AbstractAppInfo +import de.jrpie.android.launcher.apps.PinnedShortcutInfo import eu.jonahbauer.android.preference.annotations.serializer.PreferenceSerializationException import eu.jonahbauer.android.preference.annotations.serializer.PreferenceSerializer import kotlinx.serialization.Serializable @@ -10,40 +11,61 @@ import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json -// Serializers for [LauncherPreference$Config] + @Suppress("UNCHECKED_CAST") -class SetAppInfoPreferenceSerializer : - PreferenceSerializer<java.util.Set<AppInfo>?, java.util.Set<java.lang.String>?> { +class SetAbstractAppInfoPreferenceSerializer : + PreferenceSerializer<java.util.Set<AbstractAppInfo>?, java.util.Set<java.lang.String>?> { @Throws(PreferenceSerializationException::class) - override fun serialize(value: java.util.Set<AppInfo>?): java.util.Set<java.lang.String> { - return value?.map(AppInfo::serialize)?.toHashSet() as java.util.Set<java.lang.String> + override fun serialize(value: java.util.Set<AbstractAppInfo>?): java.util.Set<java.lang.String> { + return value?.map(AbstractAppInfo::serialize) + ?.toHashSet() as java.util.Set<java.lang.String> } @Throws(PreferenceSerializationException::class) - override fun deserialize(value: java.util.Set<java.lang.String>?): java.util.Set<AppInfo>? { - return value?.map (java.lang.String::toString)?.map(AppInfo::deserialize)?.toHashSet() as? java.util.Set<AppInfo> + override fun deserialize(value: java.util.Set<java.lang.String>?): java.util.Set<AbstractAppInfo>? { + return value?.map(java.lang.String::toString)?.map(AbstractAppInfo::deserialize) + ?.toHashSet() as? java.util.Set<AbstractAppInfo> } } @Suppress("UNCHECKED_CAST") -class MapAppInfoStringPreferenceSerializer : - PreferenceSerializer<java.util.HashMap<AppInfo, String>?, java.util.Set<java.lang.String>?> { - - @Serializable - private class MapEntry(val key: AppInfo, val value: String) +class SetPinnedShortcutInfoPreferenceSerializer : + PreferenceSerializer<java.util.Set<PinnedShortcutInfo>?, java.util.Set<java.lang.String>?> { + @Throws(PreferenceSerializationException::class) + override fun serialize(value: java.util.Set<PinnedShortcutInfo>?): java.util.Set<java.lang.String> { + return value?.map { Json.encodeToString<PinnedShortcutInfo>(it) } + ?.toHashSet() as java.util.Set<java.lang.String> + } @Throws(PreferenceSerializationException::class) - override fun serialize(value: java.util.HashMap<AppInfo, String>?): java.util.Set<java.lang.String>? { + override fun deserialize(value: java.util.Set<java.lang.String>?): java.util.Set<PinnedShortcutInfo>? { + return value?.map(java.lang.String::toString) + ?.map { Json.decodeFromString<PinnedShortcutInfo>(it) } + ?.toHashSet() as? java.util.Set<PinnedShortcutInfo> + } +} + + +@Suppress("UNCHECKED_CAST") +class MapAbstractAppInfoStringPreferenceSerializer : + PreferenceSerializer<java.util.HashMap<AbstractAppInfo, String>?, java.util.Set<java.lang.String>?> { + + @Serializable + private class MapEntry(val key: AbstractAppInfo, val value: String) + + @Throws(PreferenceSerializationException::class) + override fun serialize(value: java.util.HashMap<AbstractAppInfo, String>?): java.util.Set<java.lang.String>? { return value?.map { (key, value) -> Json.encodeToString(MapEntry(key, value)) }?.toHashSet() as? java.util.Set<java.lang.String> } @Throws(PreferenceSerializationException::class) - override fun deserialize(value: java.util.Set<java.lang.String>?): java.util.HashMap<AppInfo, String>? { + override fun deserialize(value: java.util.Set<java.lang.String>?): java.util.HashMap<AbstractAppInfo, String>? { return value?.associateTo(HashMap()) { val entry = Json.decodeFromString<MapEntry>(it.toString()) Pair(entry.key, entry.value) } } } + diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/PinShortcutActivity.kt b/app/src/main/java/de/jrpie/android/launcher/ui/PinShortcutActivity.kt index d19fe04..4d5d700 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/PinShortcutActivity.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/PinShortcutActivity.kt @@ -21,7 +21,7 @@ import de.jrpie.android.launcher.R import de.jrpie.android.launcher.actions.Action import de.jrpie.android.launcher.actions.Gesture import de.jrpie.android.launcher.actions.ShortcutAction -import de.jrpie.android.launcher.actions.shortcuts.PinnedShortcutInfo +import de.jrpie.android.launcher.apps.PinnedShortcutInfo import de.jrpie.android.launcher.databinding.ActivityPinShortcutBinding import de.jrpie.android.launcher.preferences.LauncherPreferences @@ -29,6 +29,7 @@ class PinShortcutActivity : AppCompatActivity(), UIObject { private lateinit var binding: ActivityPinShortcutBinding private var isBound = false + private var request: PinItemRequest? = null override fun onCreate(savedInstanceState: Bundle?) { super<AppCompatActivity>.onCreate(savedInstanceState) @@ -46,6 +47,7 @@ class PinShortcutActivity : AppCompatActivity(), UIObject { val launcherApps = getSystemService(Service.LAUNCHER_APPS_SERVICE) as LauncherApps val request = launcherApps.getPinItemRequest(intent) + this.request = request if (request == null || request.requestType != PinItemRequest.REQUEST_TYPE_SHORTCUT) { finish() return @@ -84,6 +86,7 @@ class PinShortcutActivity : AppCompatActivity(), UIObject { } binding.pinShortcutClose.setOnClickListener { finish() } + binding.pinShortcutButtonOk.setOnClickListener { finish() } } override fun onStart() { @@ -91,6 +94,24 @@ class PinShortcutActivity : AppCompatActivity(), UIObject { super<UIObject>.onStart() } + override fun onDestroy() { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { + super.onDestroy() + return + } + if(binding.pinShortcutSwitchVisible.isChecked) { + if(!isBound) { + request?.accept() + } + request?.shortcutInfo?.let { + val set = LauncherPreferences.apps().pinnedShortcuts() ?: mutableSetOf() + set.add(PinnedShortcutInfo(it)) + LauncherPreferences.apps().pinnedShortcuts(set) + } + } + super.onDestroy() + } + override fun getTheme(): Resources.Theme { return modifyTheme(super.getTheme()) } @@ -124,5 +145,6 @@ class PinShortcutActivity : AppCompatActivity(), UIObject { override fun getItemCount(): Int { return gestures.size } + } } \ No newline at end of file diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/AppsRecyclerAdapter.kt b/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/AppsRecyclerAdapter.kt index 2d8e1eb..0c0407e 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/AppsRecyclerAdapter.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/AppsRecyclerAdapter.kt @@ -16,11 +16,10 @@ import androidx.recyclerview.widget.RecyclerView import de.jrpie.android.launcher.Application import de.jrpie.android.launcher.R import de.jrpie.android.launcher.REQUEST_CHOOSE_APP -import de.jrpie.android.launcher.actions.AppAction +import de.jrpie.android.launcher.apps.AbstractDetailedAppInfo import de.jrpie.android.launcher.apps.AppFilter import de.jrpie.android.launcher.apps.AppInfo import de.jrpie.android.launcher.apps.DetailedAppInfo -import de.jrpie.android.launcher.getUserFromId import de.jrpie.android.launcher.preferences.LauncherPreferences import de.jrpie.android.launcher.preferences.ListLayout import de.jrpie.android.launcher.ui.list.ListActivity @@ -47,7 +46,7 @@ class AppsRecyclerAdapter( RecyclerView.Adapter<AppsRecyclerAdapter.ViewHolder>() { private val apps = (activity.applicationContext as Application).apps - private val appsListDisplayed: MutableList<DetailedAppInfo> = mutableListOf() + private val appsListDisplayed: MutableList<AbstractDetailedAppInfo> = mutableListOf() // temporarily disable auto launch var disableAutoLaunch: Boolean = false @@ -83,11 +82,11 @@ class AppsRecyclerAdapter( if (layout.useBadgedText) { appLabel = activity.packageManager.getUserBadgedLabel( appLabel, - getUserFromId(appsListDisplayed[i].app.user, activity) + appsListDisplayed[i].getUser(activity) ).toString() } - val appIcon = appsListDisplayed[i].icon + val appIcon = appsListDisplayed[i].getIcon(activity) viewHolder.textView.text = appLabel viewHolder.img.setImageDrawable(appIcon) @@ -118,22 +117,26 @@ class AppsRecyclerAdapter( @Suppress("SameReturnValue") private fun showOptionsPopup( viewHolder: ViewHolder, - appInfo: DetailedAppInfo + appInfo: AbstractDetailedAppInfo ): Boolean { //create the popup menu val popup = PopupMenu(activity, viewHolder.img) popup.inflate(R.menu.menu_app) - if (appInfo.isSystemApp) { + if (!appInfo.isRemovable()) { popup.menu.findItem(R.id.app_menu_delete).setVisible(false) } - if (LauncherPreferences.apps().hidden()?.contains(appInfo.app) == true) { + if (appInfo !is DetailedAppInfo) { + popup.menu.findItem(R.id.app_menu_info).setVisible(false) + } + + if (LauncherPreferences.apps().hidden()?.contains(appInfo.getRawInfo()) == true) { popup.menu.findItem(R.id.app_menu_hidden).setTitle(R.string.list_app_hidden_remove) } - if (LauncherPreferences.apps().favorites()?.contains(appInfo.app) == true) { + if (LauncherPreferences.apps().favorites()?.contains(appInfo.getRawInfo()) == true) { popup.menu.findItem(R.id.app_menu_favorite).setTitle(R.string.list_app_favorite_remove) } @@ -141,19 +144,19 @@ class AppsRecyclerAdapter( popup.setOnMenuItemClickListener { when (it.itemId) { R.id.app_menu_delete -> { - appInfo.app.uninstall(activity); true + appInfo.getRawInfo().uninstall(activity); true } R.id.app_menu_info -> { - appInfo.app.openSettings(activity); true + (appInfo.getRawInfo() as? AppInfo)?.openSettings(activity); true } R.id.app_menu_favorite -> { - appInfo.app.toggleFavorite(); true + appInfo.getRawInfo().toggleFavorite(); true } R.id.app_menu_hidden -> { - appInfo.app.toggleHidden(root); true + appInfo.getRawInfo().toggleHidden(root); true } R.id.app_menu_rename -> { @@ -188,12 +191,12 @@ class AppsRecyclerAdapter( val appInfo = appsListDisplayed[pos] when (intention) { ListActivity.ListActivityIntention.VIEW -> { - AppAction(appInfo.app).invoke(activity, rect) + appInfo.getAction().invoke(activity, rect) } ListActivity.ListActivityIntention.PICK -> { val returnIntent = Intent() - AppAction(appInfo.app).writeToIntent(returnIntent) + appInfo.getAction().writeToIntent(returnIntent) returnIntent.putExtra("forGesture", forGesture) activity.setResult(REQUEST_CHOOSE_APP, returnIntent) activity.finish() @@ -211,8 +214,8 @@ class AppsRecyclerAdapter( && !disableAutoLaunch && LauncherPreferences.functionality().searchAutoLaunch() ) { - val info = appsListDisplayed[0] - AppAction(info.app).invoke(activity) + val app = appsListDisplayed[0] + app.getAction().invoke(activity) val inputMethodManager = activity.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/ContextMenuActions.kt b/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/ContextMenuActions.kt index 9636dc2..c1f3406 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/ContextMenuActions.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/ContextMenuActions.kt @@ -1,5 +1,6 @@ package de.jrpie.android.launcher.ui.list.apps +import android.app.Activity import android.app.Service import android.content.Context import android.content.Intent @@ -15,7 +16,10 @@ import com.google.android.material.snackbar.Snackbar import de.jrpie.android.launcher.R import de.jrpie.android.launcher.REQUEST_UNINSTALL import de.jrpie.android.launcher.apps.AppInfo +import de.jrpie.android.launcher.apps.AbstractAppInfo +import de.jrpie.android.launcher.apps.AbstractDetailedAppInfo import de.jrpie.android.launcher.apps.DetailedAppInfo +import de.jrpie.android.launcher.apps.PinnedShortcutInfo import de.jrpie.android.launcher.getUserFromId import de.jrpie.android.launcher.preferences.LauncherPreferences @@ -32,27 +36,33 @@ fun AppInfo.openSettings( } } -fun AppInfo.uninstall(activity: android.app.Activity) { - val packageName = this.packageName - val userId = this.user +fun AbstractAppInfo.uninstall(activity: Activity) { + if (this is AppInfo) { + val packageName = this.packageName + val userId = this.user - Log.i(LOG_TAG, "uninstalling $this") + Log.i(LOG_TAG, "uninstalling $this") - val intent = Intent(Intent.ACTION_UNINSTALL_PACKAGE) - intent.data = Uri.parse("package:$packageName") - getUserFromId(userId, activity).let { user -> - intent.putExtra(Intent.EXTRA_USER, user) + val intent = Intent(Intent.ACTION_UNINSTALL_PACKAGE) + intent.data = Uri.parse("package:$packageName") + getUserFromId(userId, activity).let { user -> + intent.putExtra(Intent.EXTRA_USER, user) + } + + intent.putExtra(Intent.EXTRA_RETURN_RESULT, true) + activity.startActivityForResult( + intent, + REQUEST_UNINSTALL + ) + } else if(this is PinnedShortcutInfo) { + val pinned = LauncherPreferences.apps().pinnedShortcuts() ?: mutableSetOf() + pinned.remove(this) + LauncherPreferences.apps().pinnedShortcuts(pinned) } - - intent.putExtra(Intent.EXTRA_RETURN_RESULT, true) - activity.startActivityForResult( - intent, - REQUEST_UNINSTALL - ) } -fun AppInfo.toggleFavorite() { - val favorites: MutableSet<AppInfo> = +fun AbstractAppInfo.toggleFavorite() { + val favorites: MutableSet<AbstractAppInfo> = LauncherPreferences.apps().favorites() ?: mutableSetOf() if (favorites.contains(this)) { @@ -69,8 +79,8 @@ fun AppInfo.toggleFavorite() { /** * @param view: used to show a snackbar letting the user undo the action */ -fun AppInfo.toggleHidden(view: View) { - val hidden: MutableSet<AppInfo> = +fun AbstractAppInfo.toggleHidden(view: View) { + val hidden: MutableSet<AbstractAppInfo> = LauncherPreferences.apps().hidden() ?: mutableSetOf() if (hidden.contains(this)) { hidden.remove(this) @@ -87,9 +97,9 @@ fun AppInfo.toggleHidden(view: View) { LauncherPreferences.apps().hidden(hidden) } -fun DetailedAppInfo.showRenameDialog(context: Context) { +fun AbstractDetailedAppInfo.showRenameDialog(context: Context) { AlertDialog.Builder(context, R.style.AlertDialogCustom).apply { - setTitle(context.getString(R.string.dialog_rename_title, label)) + setTitle(context.getString(R.string.dialog_rename_title, getLabel())) setView(R.layout.dialog_rename_app) setNegativeButton(R.string.dialog_cancel) { d, _ -> d.cancel() } setPositiveButton(R.string.dialog_rename_ok) { d, _ -> @@ -102,7 +112,7 @@ fun DetailedAppInfo.showRenameDialog(context: Context) { }.create().also { it.show() }.apply { val input = findViewById<EditText>(R.id.dialog_rename_app_edit_text) input?.setText(getCustomLabel(context)) - input?.hint = label + input?.hint = getLabel() } } diff --git a/app/src/main/res/layout/activity_pin_shortcut.xml b/app/src/main/res/layout/activity_pin_shortcut.xml index c401b42..5e10118 100644 --- a/app/src/main/res/layout/activity_pin_shortcut.xml +++ b/app/src/main/res/layout/activity_pin_shortcut.xml @@ -80,7 +80,6 @@ android:minHeight="40dp" tools:drawableLeft="@drawable/baseline_settings_24" tools:text="Shortcut name" /> - <!-- <Space android:layout_width="match_parent" android:layout_height="10dp" /> @@ -90,8 +89,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="?android:textColor" + android:checked="true" android:text="@string/pin_shortcut_switch_visible" /> - --> <Space android:layout_width="match_parent" @@ -103,8 +102,21 @@ android:layout_height="wrap_content" android:text="@string/pin_shortcut_button_bind" /> + <Space + android:layout_width="match_parent" + android:layout_height="10dp" /> + </LinearLayout> </ScrollView> + + <Button + android:id="@+id/pin_shortcut_button_ok" + android:layout_margin="10dp" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/pin_shortcut_button_ok" + app:layout_constraintBottom_toBottomOf="parent" /> + </androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml index 9dd7402..a2e4ad6 100644 --- a/app/src/main/res/values/donottranslate.xml +++ b/app/src/main/res/values/donottranslate.xml @@ -11,6 +11,7 @@ <string name="settings_internal_version_code_key" translatable="false">internal.version_code</string> <string name="settings_apps_favorites_key" translatable="false">apps.favorites</string> <string name="settings_apps_hidden_key" translatable="false">apps.hidden</string> + <string name="settings_apps_pinned_shortcuts_key" translatable="false">apps.pinned_shortcuts</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_paused_apps_key" translatable="false">apps.hide_paused_apps</string> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fc5f883..8e13753 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -263,6 +263,7 @@ <!-- Pin shortcuts --> <string name="pin_shortcut_title">Add Shortcut</string> <string name="pin_shortcut_button_bind">Bind to gesture</string> + <string name="pin_shortcut_button_ok">Ok</string> <string name="pin_shortcut_switch_visible">Show in app list</string> <!-- From 1b12032750740507d3dc48681a4fa54892b40c93 Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Tue, 11 Mar 2025 15:58:07 +0100 Subject: [PATCH 09/73] add FUNDING.yml --- .github/FUNDING.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 9a671f0..209b346 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,3 +1,3 @@ -# How you can support finnmglas/Launcher +# How you can support jrpie/Launcher -custom: sponsor.finnmglas.com +custom: https://s.jrpie.de/launcher-donate From a5ec8bb796841cc0da6e028373b3f1f8f741bcf3 Mon Sep 17 00:00:00 2001 From: Vossa Excelencia <nationalistic.tention@hele.win> Date: Wed, 5 Mar 2025 18:45:49 +0000 Subject: [PATCH 10/73] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (255 of 255 strings) Translation: jrpie-Launcher/Launcher Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/pt_BR/ --- app/src/main/res/values-pt-rBR/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index a922186..6a6149c 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -309,4 +309,6 @@ <string name="list_other_track_play_pause">Música: Reproduzir / Pausar</string> <string name="settings_gesture_description_swipe_smaller_reverse">Canto inferior direito -> centro esquerdo -> canto superior direito</string> <string name="settings_gesture_description_swipe_lambda_reverse">Inferior direito -> superior médio -> inferior esquerdo</string> + <string name="settings_list_reverse_layout">Lista de apps inversa</string> + <string name="pin_shortcut_button_ok">Ok</string> </resources> From f776fbb88e2c1fe378bdbb45ba8b9e90048cb7c9 Mon Sep 17 00:00:00 2001 From: anmoti <at@anmoti.com> Date: Wed, 12 Mar 2025 12:36:18 +0000 Subject: [PATCH 11/73] Added translation using Weblate (Japanese) --- app/src/main/res/values-ja/strings.xml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 app/src/main/res/values-ja/strings.xml diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml new file mode 100644 index 0000000..a6b3dae --- /dev/null +++ b/app/src/main/res/values-ja/strings.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources></resources> \ No newline at end of file From 3664159782d98052070e3d6fe0d987649c8ab228 Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Thu, 13 Mar 2025 15:38:00 +0100 Subject: [PATCH 12/73] fix #116 --- .../java/de/jrpie/android/launcher/Functions.kt | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) 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 8f5e08d..81e58d7 100644 --- a/app/src/main/java/de/jrpie/android/launcher/Functions.kt +++ b/app/src/main/java/de/jrpie/android/launcher/Functions.kt @@ -93,12 +93,17 @@ fun getUserFromId(userId: Int?, context: Context): UserHandle { fun removeUnusedShortcuts(context: Context) { val launcherApps = context.getSystemService(Service.LAUNCHER_APPS_SERVICE) as LauncherApps fun getShortcuts(profile: UserHandle): List<ShortcutInfo>? { - return launcherApps.getShortcuts( - ShortcutQuery().apply { - setQueryFlags(ShortcutQuery.FLAG_MATCH_PINNED) - }, - profile - ) + return try { + launcherApps.getShortcuts( + ShortcutQuery().apply { + setQueryFlags(ShortcutQuery.FLAG_MATCH_PINNED) + }, + profile + ) + } catch (e: IllegalStateException) { + // https://github.com/jrpie/launcher/issues/116 + return null + } } val userManager = context.getSystemService(Service.USER_SERVICE) as UserManager From d7dd1aa71a413bbd8735b4330ded32f1339ebdce Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Thu, 13 Mar 2025 16:28:01 +0100 Subject: [PATCH 13/73] refactor hide navigation bar * move code to UIObject * remove listener * rename 'full screen' to 'hide status bar' --- .../LauncherPreferences$Config.java | 4 +- .../jrpie/android/launcher/ui/HomeActivity.kt | 27 ------------ .../de/jrpie/android/launcher/ui/UIObject.kt | 42 +++++++++++++++---- .../android/launcher/ui/list/ListActivity.kt | 2 +- app/src/main/res/values/donottranslate.xml | 2 +- app/src/main/res/values/strings.xml | 4 +- app/src/main/res/xml/preferences.xml | 8 ++-- 7 files changed, 45 insertions(+), 44 deletions(-) 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 aacff13..78c5611 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 @@ -59,9 +59,9 @@ import eu.jonahbauer.android.preference.annotations.Preferences; }), @PreferenceGroup(name = "display", prefix = "settings_display_", suffix = "_key", value = { @Preference(name = "screen_timeout_disabled", type = boolean.class, defaultValue = "false"), - @Preference(name = "full_screen", type = boolean.class, defaultValue = "true"), - @Preference(name = "rotate_screen", type = boolean.class, defaultValue = "true"), + @Preference(name = "hide_status_bar", type = boolean.class, defaultValue = "true"), @Preference(name = "hide_navigation_bar", type = boolean.class, defaultValue = "false"), + @Preference(name = "rotate_screen", type = boolean.class, defaultValue = "true"), }), @PreferenceGroup(name = "functionality", prefix = "settings_functionality_", suffix = "_key", value = { @Preference(name = "search_auto_launch", type = boolean.class, defaultValue = "true"), 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 1100e0c..61a4250 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 @@ -110,33 +110,6 @@ class HomeActivity : UIObject, AppCompatActivity() { } } - @Suppress("DEPRECATION") - private fun hideNavigationBar() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - window.insetsController?.apply { - hide(WindowInsets.Type.navigationBars()) - systemBarsBehavior = - WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE - } - } else { - val decorView = window.decorView - val uiOptions = (View.SYSTEM_UI_FLAG_HIDE_NAVIGATION - or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY - or View.SYSTEM_UI_FLAG_IMMERSIVE - or View.SYSTEM_UI_FLAG_LAYOUT_STABLE) - - // Try to hide the navigation bar but do not hide the status bar - decorView.systemUiVisibility = uiOptions - - // Add listener to hide the navigation bar - decorView.setOnSystemUiVisibilityChangeListener { visibility -> - if (visibility and View.SYSTEM_UI_FLAG_FULLSCREEN == 0) { - decorView.systemUiVisibility = uiOptions - } - } - } - } private fun updateSettingsFallbackButtonVisibility() { // If µLauncher settings can not be reached from any action bound to an enabled gesture, diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/UIObject.kt b/app/src/main/java/de/jrpie/android/launcher/ui/UIObject.kt index 3702bb2..d97388f 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/UIObject.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/UIObject.kt @@ -3,7 +3,11 @@ package de.jrpie.android.launcher.ui import android.app.Activity import android.content.pm.ActivityInfo import android.content.res.Resources +import android.os.Build +import android.view.View import android.view.Window +import android.view.WindowInsets +import android.view.WindowInsetsController import android.view.WindowManager import de.jrpie.android.launcher.preferences.LauncherPreferences @@ -14,7 +18,7 @@ import de.jrpie.android.launcher.preferences.LauncherPreferences fun setWindowFlags(window: Window, homeScreen: Boolean) { window.setFlags(0, 0) // clear flags // Display notification bar - if (LauncherPreferences.display().fullScreen()) + if (LauncherPreferences.display().hideStatusBar()) window.setFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN @@ -36,17 +40,19 @@ fun setWindowFlags(window: Window, homeScreen: Boolean) { } + interface UIObject { fun onCreate() { - if (this is Activity) { - setWindowFlags(window, isHomeScreen()) - - if (!LauncherPreferences.display().rotateScreen()) { - requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR - } + if (this !is Activity) { + return + } + setWindowFlags(window, isHomeScreen()) + if (!LauncherPreferences.display().rotateScreen()) { + requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR } } + fun onStart() { setOnClicks() adjustLayout() @@ -70,4 +76,26 @@ interface UIObject { fun isHomeScreen(): Boolean { return false } + + + @Suppress("DEPRECATION") + fun hideNavigationBar() { + if (this !is Activity) { + return + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + window.insetsController?.apply { + hide(WindowInsets.Type.navigationBars()) + systemBarsBehavior = + WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE + } + } else { + // Try to hide the navigation bar but do not hide the status bar + window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY + or View.SYSTEM_UI_FLAG_IMMERSIVE + or View.SYSTEM_UI_FLAG_LAYOUT_STABLE) + } + } } \ No newline at end of file diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/list/ListActivity.kt b/app/src/main/java/de/jrpie/android/launcher/ui/list/ListActivity.kt index c4ecded..334bd62 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/list/ListActivity.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/list/ListActivity.kt @@ -155,7 +155,7 @@ class ListActivity : AppCompatActivity(), UIObject { binding.listContainer.context.resources.displayMetrics.heightPixels val diff = height - r.bottom if (diff != 0 && - LauncherPreferences.display().fullScreen() + LauncherPreferences.display().hideStatusBar() ) { if (binding.listContainer.paddingBottom != diff) { binding.listContainer.setPadding(0, 0, 0, diff) diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml index ec87cf8..7d89272 100644 --- a/app/src/main/res/values/donottranslate.xml +++ b/app/src/main/res/values/donottranslate.xml @@ -135,8 +135,8 @@ - --> <string name="settings_display_screen_timeout_disabled_key" translatable="false">display.disable_timeout</string> - <string name="settings_display_full_screen_key" translatable="false">display.use_full_screen</string> <string name="settings_display_rotate_screen_key" translatable="false">display.rotate_screen</string> + <string name="settings_display_hide_status_bar_key" translatable="false">display.use_full_screen</string> <string name="settings_display_hide_navigation_bar_key" translatable="false">display.hide_navigation</string> <string name="settings_enabled_gestures_double_swipe_key" translatable="false">enabled_gestures.double_actions</string> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 870e202..51bf623 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -153,9 +153,9 @@ <string name="settings_launcher_section_display">Display</string> <string name="settings_display_screen_timeout_disabled">Keep screen on</string> - <string name="settings_display_full_screen">Use full screen</string> - <string name="settings_display_rotate_screen">Rotate screen</string> + <string name="settings_display_hide_status_bar">Hide status bar</string> <string name="settings_display_hide_navigation_bar">Hide navigation bar</string> + <string name="settings_display_rotate_screen">Rotate screen</string> <string name="settings_launcher_section_functionality">Functionality</string> diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 180a261..62552d2 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -168,10 +168,6 @@ <PreferenceCategory android:title="@string/settings_launcher_section_display" app:allowDividerAbove="false"> - <SwitchPreference - android:key="@string/settings_display_full_screen_key" - android:defaultValue="true" - android:title="@string/settings_display_full_screen"/> <SwitchPreference android:key="@string/settings_display_rotate_screen_key" android:defaultValue="true" @@ -180,6 +176,10 @@ android:key="@string/settings_display_screen_timeout_disabled_key" android:defaultValue="false" android:title="@string/settings_display_screen_timeout_disabled"/> + <SwitchPreference + android:key="@string/settings_display_hide_status_bar_key" + android:defaultValue="true" + android:title="@string/settings_display_hide_status_bar"/> <SwitchPreference android:key="@string/settings_display_hide_navigation_bar_key" android:defaultValue="false" From c9ee2c6304f9745cd314784e1d8174adbb2f2f53 Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Fri, 14 Mar 2025 02:00:26 +0100 Subject: [PATCH 14/73] handle exception when acessing shortcuts --- .../de/jrpie/android/launcher/Functions.kt | 2 +- .../launcher/apps/PinnedShortcutInfo.kt | 23 +++++++++++-------- 2 files changed, 15 insertions(+), 10 deletions(-) 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 81e58d7..7c2abbf 100644 --- a/app/src/main/java/de/jrpie/android/launcher/Functions.kt +++ b/app/src/main/java/de/jrpie/android/launcher/Functions.kt @@ -100,7 +100,7 @@ fun removeUnusedShortcuts(context: Context) { }, profile ) - } catch (e: IllegalStateException) { + } catch (e: Exception) { // https://github.com/jrpie/launcher/issues/116 return null } diff --git a/app/src/main/java/de/jrpie/android/launcher/apps/PinnedShortcutInfo.kt b/app/src/main/java/de/jrpie/android/launcher/apps/PinnedShortcutInfo.kt index a2815e5..1dc1e1f 100644 --- a/app/src/main/java/de/jrpie/android/launcher/apps/PinnedShortcutInfo.kt +++ b/app/src/main/java/de/jrpie/android/launcher/apps/PinnedShortcutInfo.kt @@ -28,15 +28,20 @@ class PinnedShortcutInfo( fun getShortcutInfo(context: Context): ShortcutInfo? { val launcherApps = context.getSystemService(Service.LAUNCHER_APPS_SERVICE) as LauncherApps - return launcherApps.getShortcuts( - ShortcutQuery().apply { - setQueryFlags(ShortcutQuery.FLAG_MATCH_PINNED) - setPackage(packageName) - setActivity(ComponentName(packageName, activityName)) - setShortcutIds(listOf(id)) - }, - getUserFromId(user, context) - )?.firstOrNull() + return try { + launcherApps.getShortcuts( + ShortcutQuery().apply { + setQueryFlags(ShortcutQuery.FLAG_MATCH_PINNED) + setPackage(packageName) + setActivity(ComponentName(packageName, activityName)) + setShortcutIds(listOf(id)) + }, + getUserFromId(user, context) + )?.firstOrNull() + } catch(_: Exception) { + // can throw SecurityException or IllegalStateException when profile is locked + null + } } override fun equals(other: Any?): Boolean { From b156b68d5380cc18582b9784e4868b1cd1bb85ed Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Fri, 14 Mar 2025 02:39:30 +0100 Subject: [PATCH 15/73] improve German translation --- app/src/main/res/values-de/strings.xml | 32 +++++++++++++------------- app/src/main/res/values/strings.xml | 1 - 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index e7c7546..17b840f 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -6,8 +6,8 @@ - --> <string name="alert_cant_open_title">App kann nicht geöffnet werden</string> - <string name="alert_cant_open_message">Möchtest du die App-Einstellungen anpassen?</string> - <string name="toast_cant_open_message">Öffne die Einstellungen um für diese Geste eine Aktion zu wählen</string> + <string name="alert_cant_open_message">App-Einstellungen anpassen?</string> + <string name="toast_cant_open_message">Einstellungen öffnen um für diese Geste eine Aktion zu wählen</string> <!-- - - Settings @@ -118,7 +118,7 @@ <string name="settings_list_layout_item_grid">Raster</string> <string name="settings_general_choose_home_screen">Launcher wählen</string> <string name="settings_meta_cant_select_launcher">App Info</string> - <string name="settings_meta_cant_select_launcher_msg">Dein Gerät unterstützt diese Funktion nicht. Stattdessen die App Details bearbeiten?</string> + <string name="settings_meta_cant_select_launcher_msg">Das Gerät unterstützt diese Funktion nicht. Stattdessen die App Details bearbeiten?</string> <string name="settings_meta_show_tutorial">Zum Tutorial</string> <string name="settings_meta_reset">Einstellungen zurücksetzen</string> <string name="settings_meta_reset_confirm">Alle Einstellungen gehen verloren. Weitermachen?</string> @@ -164,23 +164,23 @@ --> <string name="list_other_torch">Taschenlampe umschalten</string> <string name="tutorial_title">Tutorial</string> - <string name="tutorial_start_text">Nimm dir kurz Zeit und lerne, wie du diesen Launcher verwendest!</string> + <string name="tutorial_start_text">Hier eine kurze Erklärung, wie dieser Launcher funktioniert.</string> <string name="tutorial_concept_title">Konzept</string> - <string name="tutorial_concept_text">µLauncher bietet eine minimalistische, effiziente und ablenkungsfreie digitale Umgebung.\n\nDie App kostet dich nichts, enthält keine Werbung und sammelt keinerlei Daten.</string> - <string name="tutorial_concept_text_2">Launcher ist open-source (MIT license) und auf GitHub!\n\nSchau gerne mal dort vorbei!</string> + <string name="tutorial_concept_text">µLauncher bietet eine minimalistische, effiziente und ablenkungsfreie digitale Umgebung.\n\nDie App ist freie Software, enthält keine Werbung und sammelt keinerlei Daten.</string> + <string name="tutorial_concept_text_2">Der Quellcode ist bei GitHub zu finden.</string> <string name="tutorial_usage_title">Benutzung</string> - <string name="tutorial_usage_text">Auf deinem Homescreen siehst du nur das Datum und die Uhrzeit. Keine Ablenkung.</string> - <string name="tutorial_usage_text_2">Du öffnest Apps indem du über den Bildschirm wischt oder die Lautstärketasten drückst. Gleich wählst du deine Apps.</string> + <string name="tutorial_usage_text">Der Homescreen zeigt nur das Datum und die Uhrzeit. Keine Ablenkung.</string> + <string name="tutorial_usage_text_2">Häufig verwendete Apps können mittels Gesten, z.B. Wischen oder den Lautstärketasten geöffnet werden. Gleich können die Apps ausgewählt werden.</string> <string name="tutorial_setup_title">Einrichtung</string> - <string name="tutorial_setup_text">Wir haben dir ein paar Standardapps ausgewählt, du kannst sie hier gerne ändern:</string> - <string name="tutorial_setup_text_2">Du kannst deine Auswahl in den Einstellungen später jederzeit ändern.</string> + <string name="tutorial_setup_text">Es wurden Standardapps ausgewählt, die Zuordnung kann hier angepasst werden:</string> + <string name="tutorial_setup_text_2">Die Auswahl kann in den Einstellungen später jederzeit geändert werden.</string> <string name="tutorial_finish_title">Los gehts!</string> - <string name="tutorial_finish_text">Du bist bereit loszulegen!\n\nIch hoffe diese App ist nützlich für dich!\n\n- Finn (der Entwickler)\n\tund Josia (der einige Änderungen vorgenommen hat und den Fork μLauncher entwickelt)</string> + <string name="tutorial_finish_text">Es kann losgehen!\n\nWir hoffen, dass diese App hilfreich ist!\n\n- Finn (der Entwickler)\n\tund Josia (der einige Änderungen vorgenommen hat und den Fork μLauncher entwickelt)</string> <string name="tutorial_finish_button">Starten</string> <string name="settings">Einstellungen</string> <string name="ic_menu_alt">Mehr Optionen</string> <string name="list_other_expand_notifications_panel">Benachrichtigungen</string> - <string name="alert_cant_expand_status_bar_panel">Fehler: Diese Funktion wird von deinem Gerät leider nicht unterstützt.</string> + <string name="alert_cant_expand_status_bar_panel">Fehler: Die Funktion wird von diesem Gerät leider nicht unterstützt.</string> <string name="settings_clock_show_seconds">Sekunden anzeigen</string> <string name="undo">Rückgängig</string> <string name="list_other_expand_settings_panel">Schnelleinstellungen</string> @@ -195,7 +195,7 @@ <string name="alert_requires_android_v">Diese Funktionalität benötigt Android 15 oder neuer.</string> <string name="snackbar_app_hidden">Die App wurde versteckt. Sie kann in den Einstellungen wieder sichtbar gemacht werden.</string> <string name="toast_device_admin_not_enabled">µLauncher muss Geräteadministrator sein, um den Bildschirm sperren zu dürfen.</string> - <string name="device_admin_explanation">Dies ist erforderlich, damit µLauncher den Bildschirm spreen kann.</string> + <string name="device_admin_explanation">Dies ist erforderlich, damit µLauncher den Bildschirm sperren kann.</string> <string name="device_admin_description">Die Aktion \"Bildschirm sperren\" aktivieren</string> <string name="alert_no_torch_found">Es wurde keine geeignete Kamera gefunden.</string> <string name="alert_torch_access_exception">Fehler: Kein Zugriff auf die Kamera möglich.</string> @@ -234,8 +234,8 @@ Dies erfordert sehr weitgehende Berechtigungen. µLauncher wird diese ausschließlich zum Sperren des Bildschirms verwenden. <br/> - (Irgeneiner gerade heruntergeladenen App sollte man eine solche Behauptung natürlich nicht einfach glauben. - Du kannst jedoch den <a href=\"https://github.com/jrpie/Launcher\">Source Code</a> selbst prüfen.) + (Irgendeiner gerade heruntergeladenen App sollte man eine solche Behauptung natürlich nicht einfach glauben. + Der <a href=\"https://github.com/jrpie/Launcher\">Quelltext</a> dieser App ist jedoch frei verfügbar und kann überprüft werden.) <br/><br/><br/><br/> @@ -277,4 +277,4 @@ <string name="dialog_consent_accessibility_consent">Ich willige ein, dass µLauncher eine Bedienungshilfe für Zwecke verwendet, die nicht unter Barrierefreiheit fallen.</string> <string name="dialog_consent_accessibility_data_collection">Ich willige ein, dass µLauncher keine Daten sammelt.</string> <string name="dialog_consent_accessibility_title">Bedienungshilfe aktivieren</string> -</resources> \ No newline at end of file +</resources> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 902e147..3177442 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -192,7 +192,6 @@ --> <string name="settings_general_choose_home_screen">Set μLauncher as home screen</string> <string name="settings_meta_cant_select_launcher">App Info</string> - <string name="settings_meta_cant_select_launcher_msg">Your device does not support this feature. Manage application details instead?</string> <string name="settings_meta_show_tutorial">View Launcher Tutorial</string> From 6cd17343fcc856a6fab0ef6ffbea28f58a174ef6 Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Fri, 14 Mar 2025 04:09:28 +0100 Subject: [PATCH 16/73] show questionmark when unkown app or shortcut is bound to gesture --- .../actions/SettingsFragmentActionsRecycler.kt | 10 ++++++++-- .../main/res/drawable/baseline_question_mark_24.xml | 12 ++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 app/src/main/res/drawable/baseline_question_mark_24.xml diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/settings/actions/SettingsFragmentActionsRecycler.kt b/app/src/main/java/de/jrpie/android/launcher/ui/settings/actions/SettingsFragmentActionsRecycler.kt index d7862fa..1f91913 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/settings/actions/SettingsFragmentActionsRecycler.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/settings/actions/SettingsFragmentActionsRecycler.kt @@ -11,6 +11,7 @@ import android.view.ViewGroup import android.widget.Button import android.widget.ImageView import android.widget.TextView +import androidx.appcompat.content.res.AppCompatResources import androidx.fragment.app.Fragment import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView @@ -94,6 +95,8 @@ class SettingsFragmentActionsRecycler : Fragment(), UIObject { class ActionsRecyclerAdapter(val activity: Activity) : RecyclerView.Adapter<ActionsRecyclerAdapter.ViewHolder>() { + private val drawableUnknown = AppCompatResources.getDrawable(activity, R.drawable.baseline_question_mark_24) + private val gesturesList: ArrayList<Gesture> = Gesture.entries.filter(Gesture::isEnabled) as ArrayList<Gesture> @@ -115,15 +118,18 @@ class ActionsRecyclerAdapter(val activity: Activity) : private fun updateViewHolder(gesture: Gesture, viewHolder: ViewHolder) { val action = Action.forGesture(gesture) - val drawable = action?.getIcon(activity) - if (action == null || drawable == null) { + if (action == null) { viewHolder.img.visibility = View.INVISIBLE viewHolder.removeAction.visibility = View.GONE viewHolder.chooseButton.visibility = View.VISIBLE return } + // Use the unknown icon if there is an action, but we can't find its icon. + // Probably an app was uninstalled. + val drawable = action.getIcon(activity) ?: drawableUnknown + viewHolder.img.visibility = View.VISIBLE viewHolder.removeAction.visibility = View.VISIBLE viewHolder.chooseButton.visibility = View.INVISIBLE diff --git a/app/src/main/res/drawable/baseline_question_mark_24.xml b/app/src/main/res/drawable/baseline_question_mark_24.xml new file mode 100644 index 0000000..9a2b28a --- /dev/null +++ b/app/src/main/res/drawable/baseline_question_mark_24.xml @@ -0,0 +1,12 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:tint="?attr/colorControlNormal" + android:viewportWidth="24" + android:viewportHeight="24"> + + <path + android:fillColor="@android:color/white" + android:pathData="M11.07,12.85c0.77,-1.39 2.25,-2.21 3.11,-3.44c0.91,-1.29 0.4,-3.7 -2.18,-3.7c-1.69,0 -2.52,1.28 -2.87,2.34L6.54,6.96C7.25,4.83 9.18,3 11.99,3c2.35,0 3.96,1.07 4.78,2.41c0.7,1.15 1.11,3.3 0.03,4.9c-1.2,1.77 -2.35,2.31 -2.97,3.45c-0.25,0.46 -0.35,0.76 -0.35,2.24h-2.89C10.58,15.22 10.46,13.95 11.07,12.85zM14,20c0,1.1 -0.9,2 -2,2s-2,-0.9 -2,-2c0,-1.1 0.9,-2 2,-2S14,18.9 14,20z" /> + +</vector> From c7af387a944dfb90a2a50db80a582cfa192caea5 Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Fri, 14 Mar 2025 04:11:47 +0100 Subject: [PATCH 17/73] implement #98 - hide lock icon when 'hide private space when locked' setting is set --- .../launcher/actions/LauncherAction.kt | 17 ++++-- .../android/launcher/apps/PrivateSpace.kt | 14 +++++ .../android/launcher/ui/list/ListActivity.kt | 58 ++++++++++--------- 3 files changed, 57 insertions(+), 32 deletions(-) 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 1ed6473..3c89a67 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 @@ -13,6 +13,7 @@ import androidx.appcompat.content.res.AppCompatResources import de.jrpie.android.launcher.Application import de.jrpie.android.launcher.R import de.jrpie.android.launcher.apps.AppFilter +import de.jrpie.android.launcher.apps.hidePrivateSpaceWhenLocked import de.jrpie.android.launcher.apps.isPrivateSpaceSupported import de.jrpie.android.launcher.apps.togglePrivateSpaceLock import de.jrpie.android.launcher.preferences.LauncherPreferences @@ -66,7 +67,11 @@ enum class LauncherAction( R.string.list_other_list_private_space, R.drawable.baseline_security_24, { context -> - openAppsList(context, private = true) + if ((context.applicationContext as Application).privateSpaceLocked.value != true + || !hidePrivateSpaceWhenLocked(context) + ) { + openAppsList(context, private = true) + } }, available = { _ -> isPrivateSpaceSupported() @@ -83,31 +88,31 @@ enum class LauncherAction( "volume_up", R.string.list_other_volume_up, R.drawable.baseline_volume_up_24, - { context -> audioVolumeAdjust(context, true)} + { context -> audioVolumeAdjust(context, true) } ), VOLUME_DOWN( "volume_down", R.string.list_other_volume_down, R.drawable.baseline_volume_down_24, - { context -> audioVolumeAdjust(context, false)} + { context -> audioVolumeAdjust(context, false) } ), TRACK_PLAY_PAUSE( "play_pause_track", R.string.list_other_track_play_pause, R.drawable.baseline_play_arrow_24, - { context -> audioManagerPressKey(context, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE)} + { context -> audioManagerPressKey(context, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE) } ), TRACK_NEXT( "next_track", R.string.list_other_track_next, R.drawable.baseline_skip_next_24, - { context -> audioManagerPressKey(context, KeyEvent.KEYCODE_MEDIA_NEXT)} + { context -> audioManagerPressKey(context, KeyEvent.KEYCODE_MEDIA_NEXT) } ), TRACK_PREV( "previous_track", R.string.list_other_track_previous, R.drawable.baseline_skip_previous_24, - { context -> audioManagerPressKey(context, KeyEvent.KEYCODE_MEDIA_PREVIOUS)} + { context -> audioManagerPressKey(context, KeyEvent.KEYCODE_MEDIA_PREVIOUS) } ), EXPAND_NOTIFICATIONS_PANEL( "expand_notifications_panel", diff --git a/app/src/main/java/de/jrpie/android/launcher/apps/PrivateSpace.kt b/app/src/main/java/de/jrpie/android/launcher/apps/PrivateSpace.kt index 9b37d60..a1241af 100644 --- a/app/src/main/java/de/jrpie/android/launcher/apps/PrivateSpace.kt +++ b/app/src/main/java/de/jrpie/android/launcher/apps/PrivateSpace.kt @@ -95,6 +95,12 @@ fun lockPrivateSpace(context: Context, lock: Boolean) { if (!isPrivateSpaceSupported()) { return } + + // silently return when trying to unlock but hide when locked is set + if (!lock && hidePrivateSpaceWhenLocked(context)) { + return + } + val userManager = context.getSystemService(Context.USER_SERVICE) as UserManager val privateSpaceUser = getPrivateSpaceUser(context) ?: return userManager.requestQuietModeEnabled(lock, privateSpaceUser) @@ -116,3 +122,11 @@ fun togglePrivateSpaceLock(context: Context) { } } +fun hidePrivateSpaceWhenLocked(context: Context): Boolean { + // TODO: perhaps this should be cached + + // https://cs.android.com/android/platform/superproject/main/+/main:packages/apps/Launcher3/src/com/android/launcher3/util/SettingsCache.java;l=61;drc=56bf7ad33bc9d5ed3c18e7abefeec5c177ec75d7 + val key = "hide_privatespace_entry_point" + return Settings.Secure.getInt(context.contentResolver, key, 0) == 1 +} + diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/list/ListActivity.kt b/app/src/main/java/de/jrpie/android/launcher/ui/list/ListActivity.kt index 334bd62..95ed56e 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/list/ListActivity.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/list/ListActivity.kt @@ -22,6 +22,7 @@ import de.jrpie.android.launcher.R import de.jrpie.android.launcher.REQUEST_UNINSTALL import de.jrpie.android.launcher.actions.LauncherAction import de.jrpie.android.launcher.apps.AppFilter +import de.jrpie.android.launcher.apps.hidePrivateSpaceWhenLocked import de.jrpie.android.launcher.apps.isPrivateSpaceLocked import de.jrpie.android.launcher.apps.isPrivateSpaceSetUp import de.jrpie.android.launcher.apps.togglePrivateSpaceLock @@ -34,10 +35,12 @@ import de.jrpie.android.launcher.ui.list.other.ListFragmentOther // TODO: Better solution for this intercommunication functionality (used in list-fragments) var intention = ListActivity.ListActivityIntention.VIEW -var favoritesVisibility: AppFilter.Companion.AppSetVisibility = AppFilter.Companion.AppSetVisibility.VISIBLE +var favoritesVisibility: AppFilter.Companion.AppSetVisibility = + AppFilter.Companion.AppSetVisibility.VISIBLE var privateSpaceVisibility: AppFilter.Companion.AppSetVisibility = AppFilter.Companion.AppSetVisibility.VISIBLE -var hiddenVisibility: AppFilter.Companion.AppSetVisibility = AppFilter.Companion.AppSetVisibility.HIDDEN +var hiddenVisibility: AppFilter.Companion.AppSetVisibility = + AppFilter.Companion.AppSetVisibility.HIDDEN var forGesture: String? = null /** @@ -52,6 +55,23 @@ class ListActivity : AppCompatActivity(), UIObject { private fun updateLockIcon(locked: Boolean) { + if ( + // only show lock for VIEW intention + (intention != ListActivityIntention.VIEW) + // hide lock when private space does not exist + || !isPrivateSpaceSetUp(this) + // hide lock when private space apps are hidden from the main list and we are not in the private space list + || (LauncherPreferences.apps().hidePrivateSpaceApps() + && privateSpaceVisibility != AppFilter.Companion.AppSetVisibility.EXCLUSIVE) + // hide lock when private space is locked and the hidden when locked setting is set + || (locked && hidePrivateSpaceWhenLocked(this)) + ) { + binding.listLock.visibility = View.GONE + return + } + + binding.listLock.visibility = View.VISIBLE + binding.listLock.setImageDrawable( AppCompatResources.getDrawable( this, @@ -74,7 +94,6 @@ class ListActivity : AppCompatActivity(), UIObject { } - enum class ListActivityIntention(val titleResource: Int) { VIEW(R.string.list_title_view), /* view list of apps */ PICK(R.string.list_title_pick) /* choose app or action to associate to a gesture */ @@ -119,20 +138,6 @@ class ListActivity : AppCompatActivity(), UIObject { LauncherAction.SETTINGS.launch(this@ListActivity) } - binding.listLock.visibility = - if (intention != ListActivityIntention.VIEW) { - View.GONE - } else if (!isPrivateSpaceSetUp(this)) { - View.GONE - } else if (LauncherPreferences.apps().hidePrivateSpaceApps()) { - if (privateSpaceVisibility == AppFilter.Companion.AppSetVisibility.EXCLUSIVE) { - View.VISIBLE - } else { - View.GONE - } - } else { - View.VISIBLE - } if (privateSpaceVisibility == AppFilter.Companion.AppSetVisibility.EXCLUSIVE) { isPrivateSpaceSetUp(this, showToast = true, launchSettings = true) @@ -200,15 +205,16 @@ class ListActivity : AppCompatActivity(), UIObject { fun updateTitle() { var titleResource = intention.titleResource if (intention == ListActivityIntention.VIEW) { - titleResource = if (hiddenVisibility == AppFilter.Companion.AppSetVisibility.EXCLUSIVE) { - R.string.list_title_hidden - } else if (privateSpaceVisibility == AppFilter.Companion.AppSetVisibility.EXCLUSIVE) { - R.string.list_title_private_space - } else if (favoritesVisibility == AppFilter.Companion.AppSetVisibility.EXCLUSIVE) { - R.string.list_title_favorite - } else { - R.string.list_title_view - } + titleResource = + if (hiddenVisibility == AppFilter.Companion.AppSetVisibility.EXCLUSIVE) { + R.string.list_title_hidden + } else if (privateSpaceVisibility == AppFilter.Companion.AppSetVisibility.EXCLUSIVE) { + R.string.list_title_private_space + } else if (favoritesVisibility == AppFilter.Companion.AppSetVisibility.EXCLUSIVE) { + R.string.list_title_favorite + } else { + R.string.list_title_view + } } binding.listHeading.text = getString(titleResource) From e250a58ef4509c682376470b557bf5cf72713006 Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Fri, 14 Mar 2025 13:37:41 +0100 Subject: [PATCH 18/73] add new action: adjust volume --- .../android/launcher/actions/LauncherAction.kt | 18 ++++++++++-------- .../res/drawable/baseline_volume_adjust_24.xml | 16 ++++++++++++++++ app/src/main/res/values-de/strings.xml | 5 +++-- app/src/main/res/values/strings.xml | 5 +++-- 4 files changed, 32 insertions(+), 12 deletions(-) create mode 100644 app/src/main/res/drawable/baseline_volume_adjust_24.xml 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 3c89a67..5d2be94 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 @@ -88,13 +88,19 @@ enum class LauncherAction( "volume_up", R.string.list_other_volume_up, R.drawable.baseline_volume_up_24, - { context -> audioVolumeAdjust(context, true) } + { context -> audioVolumeAdjust(context, AudioManager.ADJUST_RAISE) } ), VOLUME_DOWN( "volume_down", R.string.list_other_volume_down, R.drawable.baseline_volume_down_24, - { context -> audioVolumeAdjust(context, false) } + { context -> audioVolumeAdjust(context, AudioManager.ADJUST_LOWER) } + ), + VOLUME_ADJUST( + "volume_adjust", + R.string.list_other_volume_adjust, + R.drawable.baseline_volume_adjust_24, + { context -> audioVolumeAdjust(context, AudioManager.ADJUST_SAME) } ), TRACK_PLAY_PAUSE( "play_pause_track", @@ -181,17 +187,13 @@ private fun audioManagerPressKey(context: Context, key: Int) { } -private fun audioVolumeAdjust(context: Context, louder: Boolean) { +private fun audioVolumeAdjust(context: Context, direction: Int) { val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager audioManager.adjustStreamVolume( AudioManager.STREAM_MUSIC, - if (louder) { - AudioManager.ADJUST_RAISE - } else { - AudioManager.ADJUST_LOWER - }, + direction, AudioManager.FLAG_SHOW_UI ) } diff --git a/app/src/main/res/drawable/baseline_volume_adjust_24.xml b/app/src/main/res/drawable/baseline_volume_adjust_24.xml new file mode 100644 index 0000000..38e6a8b --- /dev/null +++ b/app/src/main/res/drawable/baseline_volume_adjust_24.xml @@ -0,0 +1,16 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + + <path + android:fillColor="?android:textColor" + android:pathData="m 3,9 v 6 h 4 l 5,5 V 4 L 7,9 Z m 13.5,3 C 16.5,10.23 15.48,8.71 14,7.97 v 8.05 c 1.48,-0.73 2.5,-2.25 2.5,-4.02 z" /> + <path + android:fillAlpha="0.5" + android:fillColor="?android:textColor" + android:pathData="m 14,3.23 v 2.06 c 2.89,0.86 5,3.54 5,6.71 0,3.17 -2.11,5.85 -5,6.71 v 2.06 C 18.01,19.86 21,16.28 21,12 21,7.72 18.01,4.14 14,3.23 Z" + android:strokeAlpha="0.5" /> + +</vector> diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 17b840f..cf7f681 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -152,8 +152,9 @@ <string name="list_other_list">Alle Anwendungen</string> <string name="list_other_list_favorites">Favoriten</string> <string name="list_other_toggle_private_space_lock">Privaten Bereich (ent)sperren</string> - <string name="list_other_volume_up">Musik: Lauter</string> - <string name="list_other_volume_down">Musik: Leiser</string> + <string name="list_other_volume_up">Lauter</string> + <string name="list_other_volume_down">Leiser</string> + <string name="list_other_volume_adjust">Lautstärke ändern</string> <string name="list_other_track_next">Musik: Weiter</string> <string name="list_other_track_previous">Musik: Zurück</string> <string name="list_other_nop">Nichts tun</string> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3177442..1a79b5f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -250,8 +250,9 @@ <string name="list_other_list_favorites">Favorite Applications</string> <string name="list_other_list_private_space">Private Space</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_down">Music: Quieter</string> + <string name="list_other_volume_up">Raise Volume</string> + <string name="list_other_volume_down">Lower Volume</string> + <string name="list_other_volume_adjust">Adjust Volume</string> <string name="list_other_track_next">Music: Next</string> <string name="list_other_track_previous">Music: Previous</string> <string name="list_other_track_play_pause">Music: Play / Pause</string> From 077ee4381a7783ff1d044b9cb6cce437eae2f942 Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Fri, 14 Mar 2025 15:27:26 +0100 Subject: [PATCH 19/73] lint --- .../de/jrpie/android/launcher/Application.kt | 11 +++--- .../de/jrpie/android/launcher/Functions.kt | 4 +-- .../LauncherPreferences$Config.java | 2 ++ .../launcher/preferences/legacy/Version1.kt | 2 +- .../launcher/preferences/legacy/Version3.kt | 16 ++++----- .../jrpie/android/launcher/ui/HomeActivity.kt | 15 ++++---- .../launcher/ui/TouchGestureDetector.kt | 34 +++++++++++++++---- .../ui/list/apps/AppsRecyclerAdapter.kt | 2 +- .../ui/list/apps/ContextMenuActions.kt | 3 +- .../ui/list/other/OtherRecyclerAdapter.kt | 2 +- .../ui/settings/meta/SettingsFragmentMeta.kt | 3 +- .../launcher/ui/tutorial/TutorialActivity.kt | 17 +++++++++- 12 files changed, 75 insertions(+), 36 deletions(-) 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 09229ab..e674e4e 100644 --- a/app/src/main/java/de/jrpie/android/launcher/Application.kt +++ b/app/src/main/java/de/jrpie/android/launcher/Application.kt @@ -10,6 +10,8 @@ import android.content.pm.ShortcutInfo import android.os.AsyncTask import android.os.Build import android.os.Build.VERSION_CODES +import android.os.Handler +import android.os.Looper import android.os.UserHandle import androidx.core.content.ContextCompat import androidx.lifecycle.MutableLiveData @@ -108,12 +110,10 @@ class Application : android.app.Application() { // Try to restore old preferences migratePreferencesToNewVersion(this) - // First time opening the app: set defaults and start tutorial + // First time opening the app: set defaults + // The tutorial is started from HomeActivity#onStart, as starting it here is blocked by android if (!LauncherPreferences.internal().started()) { resetPreferences(this) - - LauncherPreferences.internal().started(true) - openTutorial(this) } @@ -134,7 +134,8 @@ class Application : android.app.Application() { it.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE) } } - ContextCompat.registerReceiver(this, profileAvailabilityBroadcastReceiver, filter, + ContextCompat.registerReceiver( + this, profileAvailabilityBroadcastReceiver, filter, ContextCompat.RECEIVER_EXPORTED ) } 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 7c2abbf..57f13a5 100644 --- a/app/src/main/java/de/jrpie/android/launcher/Functions.kt +++ b/app/src/main/java/de/jrpie/android/launcher/Functions.kt @@ -135,9 +135,7 @@ fun openInBrowser(url: String, context: Context) { } fun openTutorial(context: Context) { - context.startActivity(Intent(context, TutorialActivity::class.java).apply { - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - }) + context.startActivity(Intent(context, TutorialActivity::class.java)) } 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 ca60591..85979fe 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 @@ -21,8 +21,10 @@ import eu.jonahbauer.android.preference.annotations.Preferences; r = R.class, value = { @PreferenceGroup(name = "internal", prefix = "settings_internal_", suffix = "_key", value = { + // set after the user finished the tutorial @Preference(name = "started", type = boolean.class, defaultValue = "false"), @Preference(name = "started_time", type = long.class), + // see PREFERENCE_VERSION in de.jrpie.android.launcher.preferences.Preferences.kt @Preference(name = "version_code", type = int.class, defaultValue = "-1"), }), @PreferenceGroup(name = "apps", prefix = "settings_apps_", suffix = "_key", value = { diff --git a/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version1.kt b/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version1.kt index 6408b70..6252811 100644 --- a/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version1.kt +++ b/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version1.kt @@ -100,7 +100,7 @@ private fun migrateAppInfoStringMap(key: String) { } }?.toMap(HashMap()) )?.let { - preferences.edit().putStringSet(key, it as Set<String>).apply() + preferences.edit().putStringSet(key, it).apply() } } diff --git a/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version3.kt b/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version3.kt index 7698e62..4a9241f 100644 --- a/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version3.kt +++ b/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version3.kt @@ -11,6 +11,7 @@ import de.jrpie.android.launcher.preferences.serialization.SetAbstractAppInfoPre import kotlinx.serialization.Serializable import kotlinx.serialization.json.Json import java.util.HashSet +import androidx.core.content.edit /** * Migrate preferences from version 3 (used until version 0.0.23) to the current format @@ -42,6 +43,7 @@ private fun migrateSetAppInfo(key: String, preferences: SharedPreferences, edito deserializeSet(preferences.getStringSet(key, null))?.let { set.addAll(it) } + @Suppress("UNCHECKED_CAST") editor.putStringSet( key, serializer.serialize(set as java.util.Set<AbstractAppInfo>) as Set<String>? @@ -60,6 +62,7 @@ private fun migrateMapAppInfoString(key: String, preferences: SharedPreferences, deserializeMap(preferences.getStringSet(key, null))?.let { map.putAll(it) } + @Suppress("UNCHECKED_CAST") editor.putStringSet(key, serializer.serialize(map) as Set<String>?) } catch (e: Exception) { e.printStackTrace() @@ -72,14 +75,11 @@ fun migratePreferencesFromVersion3() { assert(LauncherPreferences.internal().versionCode() == 3) val preferences = LauncherPreferences.getSharedPreferences() - val editor = preferences.edit() - migrateSetAppInfo(LauncherPreferences.apps().keys().favorites(), preferences, editor) - migrateSetAppInfo(LauncherPreferences.apps().keys().hidden(), preferences, editor) - migrateMapAppInfoString(LauncherPreferences.apps().keys().customNames(), preferences, editor) - - editor.apply() - - + preferences.edit { + migrateSetAppInfo(LauncherPreferences.apps().keys().favorites(), preferences, this) + migrateSetAppInfo(LauncherPreferences.apps().keys().hidden(), preferences, this) + migrateMapAppInfoString(LauncherPreferences.apps().keys().customNames(), preferences, this) + } LauncherPreferences.internal().versionCode(4) } \ No newline at end of file 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 61a4250..7875473 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 @@ -9,9 +9,6 @@ import android.util.DisplayMetrics import android.view.KeyEvent import android.view.MotionEvent import android.view.View -import android.view.Window -import android.view.WindowInsets -import android.view.WindowInsetsController import android.window.OnBackInvokedDispatcher import androidx.appcompat.app.AppCompatActivity import androidx.core.view.isVisible @@ -20,6 +17,7 @@ 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.ui.tutorial.TutorialActivity import java.util.Locale @@ -58,7 +56,6 @@ class HomeActivity : UIObject, AppCompatActivity() { super<AppCompatActivity>.onCreate(savedInstanceState) super<UIObject>.onCreate() - val displayMetrics = DisplayMetrics() windowManager.defaultDisplay.getMetrics(displayMetrics) @@ -88,8 +85,6 @@ class HomeActivity : UIObject, AppCompatActivity() { binding.buttonFallbackSettings.setOnClickListener { LauncherAction.SETTINGS.invoke(this) } - - } override fun onStart() { @@ -97,6 +92,11 @@ class HomeActivity : UIObject, AppCompatActivity() { super<UIObject>.onStart() + // If the tutorial was not finished, start it + if (!LauncherPreferences.internal().started()) { + openTutorial(this) + } + LauncherPreferences.getSharedPreferences() .registerOnSharedPreferenceChangeListener(sharedPreferencesListener) @@ -220,7 +220,8 @@ class HomeActivity : UIObject, AppCompatActivity() { } override fun onTouchEvent(event: MotionEvent): Boolean { - return touchGestureDetector.onTouchEvent(event) || super.onTouchEvent(event) + touchGestureDetector.onTouchEvent(event) + return true } override fun setOnClicks() { diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/TouchGestureDetector.kt b/app/src/main/java/de/jrpie/android/launcher/ui/TouchGestureDetector.kt index 00629a5..1c05d54 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/TouchGestureDetector.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/TouchGestureDetector.kt @@ -1,6 +1,8 @@ package de.jrpie.android.launcher.ui import android.content.Context +import android.os.Handler +import android.os.Looper import android.view.MotionEvent import android.view.ViewConfiguration import de.jrpie.android.launcher.actions.Gesture @@ -27,6 +29,8 @@ class TouchGestureDetector( private val MIN_TRIANGLE_HEIGHT = 250 + private val longPressHandler = Handler(Looper.getMainLooper()) + data class Vector(val x: Float, val y: Float) { fun absSquared(): Float { @@ -83,16 +87,28 @@ class TouchGestureDetector( } private var paths = HashMap<Int, PointerPath>() + private var gestureIsLongClick = false private var lastTappedTime = 0L private var lastTappedLocation: Vector? = null - fun onTouchEvent(event: MotionEvent): Boolean { + fun onTouchEvent(event: MotionEvent) { val pointerIdToIndex = (0..<event.pointerCount).associateBy { event.getPointerId(it) } if (event.actionMasked == MotionEvent.ACTION_DOWN) { - paths = HashMap() + synchronized(this@TouchGestureDetector) { + paths = HashMap() + gestureIsLongClick = false + } + longPressHandler.postDelayed({ + synchronized(this@TouchGestureDetector) { + if (paths.entries.size == 1 && paths.entries.firstOrNull()?.value?.isTap() == true) { + gestureIsLongClick = true + Gesture.LONG_CLICK.invoke(context) + } + } + }, LONG_PRESS_TIMEOUT.toLong()) } // add new pointers @@ -122,9 +138,17 @@ class TouchGestureDetector( } if (event.actionMasked == MotionEvent.ACTION_UP) { + synchronized(this@TouchGestureDetector) { + // if the long press handler is still running, kill it + longPressHandler.removeCallbacksAndMessages(null) + // if the gesture was already detected as a long click, there is nothing to do + if (gestureIsLongClick) { + return + } + } classifyPaths(paths, event.downTime, event.eventTime) } - return true + return } private fun getGestureForDirection(direction: Vector): Gesture? { @@ -171,10 +195,6 @@ class TouchGestureDetector( lastTappedTime = timeEnd lastTappedLocation = mainPointerPath.last } - } else if (duration > LONG_PRESS_TIMEOUT) { - // TODO: Don't wait until the finger is lifted. - // Instead set a timer to start long click as soon as LONG_PRESS_TIMEOUT is reached - Gesture.LONG_CLICK.invoke(context) } } else { // detect swipes diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/AppsRecyclerAdapter.kt b/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/AppsRecyclerAdapter.kt index 0c0407e..1f275e4 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/AppsRecyclerAdapter.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/AppsRecyclerAdapter.kt @@ -67,7 +67,7 @@ class AppsRecyclerAdapter( override fun onClick(v: View) { val rect = Rect() img.getGlobalVisibleRect(rect) - selectItem(adapterPosition, rect) + selectItem(bindingAdapterPosition, rect) } init { diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/ContextMenuActions.kt b/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/ContextMenuActions.kt index c1f3406..8b681b9 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/ContextMenuActions.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/ContextMenuActions.kt @@ -22,6 +22,7 @@ import de.jrpie.android.launcher.apps.DetailedAppInfo import de.jrpie.android.launcher.apps.PinnedShortcutInfo import de.jrpie.android.launcher.getUserFromId import de.jrpie.android.launcher.preferences.LauncherPreferences +import androidx.core.net.toUri private const val LOG_TAG = "AppContextMenu" @@ -44,7 +45,7 @@ fun AbstractAppInfo.uninstall(activity: Activity) { Log.i(LOG_TAG, "uninstalling $this") val intent = Intent(Intent.ACTION_UNINSTALL_PACKAGE) - intent.data = Uri.parse("package:$packageName") + intent.data = "package:$packageName".toUri() getUserFromId(userId, activity).let { user -> intent.putExtra(Intent.EXTRA_USER, user) } 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 97d1c84..dfba334 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 @@ -33,7 +33,7 @@ class OtherRecyclerAdapter(val activity: Activity) : override fun onClick(v: View) { - val pos = adapterPosition + val pos = bindingAdapterPosition val content = othersList[pos] forGesture?.let { returnChoiceIntent(it, content) } diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/settings/meta/SettingsFragmentMeta.kt b/app/src/main/java/de/jrpie/android/launcher/ui/settings/meta/SettingsFragmentMeta.kt index 70a225d..4cce930 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/settings/meta/SettingsFragmentMeta.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/settings/meta/SettingsFragmentMeta.kt @@ -16,6 +16,7 @@ import de.jrpie.android.launcher.copyToClipboard import de.jrpie.android.launcher.databinding.SettingsMetaBinding import de.jrpie.android.launcher.getDeviceInfo import de.jrpie.android.launcher.openInBrowser +import de.jrpie.android.launcher.openTutorial import de.jrpie.android.launcher.preferences.resetPreferences import de.jrpie.android.launcher.ui.LegalInfoActivity import de.jrpie.android.launcher.ui.UIObject @@ -48,7 +49,7 @@ class SettingsFragmentMeta : Fragment(), UIObject { override fun setOnClicks() { binding.settingsMetaButtonViewTutorial.setOnClickListener { - startActivity(Intent(this.context, TutorialActivity::class.java)) + openTutorial(requireContext()) } // prompting for settings-reset confirmation diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/TutorialActivity.kt b/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/TutorialActivity.kt index 28e2e02..fd60d19 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/TutorialActivity.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/TutorialActivity.kt @@ -2,7 +2,9 @@ package de.jrpie.android.launcher.ui.tutorial import android.content.Intent import android.content.res.Resources +import android.os.Build import android.os.Bundle +import android.window.OnBackInvokedDispatcher import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager @@ -33,6 +35,19 @@ class TutorialActivity : AppCompatActivity(), UIObject { super<AppCompatActivity>.onCreate(savedInstanceState) super<UIObject>.onCreate() + // Handle back key / gesture on Android 13+ + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + onBackInvokedDispatcher.registerOnBackInvokedCallback( + OnBackInvokedDispatcher.PRIORITY_OVERLAY + ) { + // prevent going back when the tutorial is shown for the first time + if (!LauncherPreferences.internal().started()) { + return@registerOnBackInvokedCallback + } + finish() + } + } + // Initialise layout setContentView(R.layout.tutorial) @@ -60,7 +75,7 @@ class TutorialActivity : AppCompatActivity(), UIObject { } } - // Default: prevent going back, allow if viewed again later + // prevent going back when the tutorial is shown for the first time override fun onBackPressed() { if (LauncherPreferences.internal().started()) super.onBackPressed() From 55af3927063b31ba75d5e03a2794f7284175fcba Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Fri, 14 Mar 2025 15:40:06 +0100 Subject: [PATCH 20/73] add donate button --- .../ui/settings/meta/SettingsFragmentMeta.kt | 48 +++++++------------ app/src/main/res/layout/settings_meta.xml | 11 ++++- app/src/main/res/values-de/strings.xml | 1 + app/src/main/res/values/donottranslate.xml | 1 + app/src/main/res/values/strings.xml | 1 + 5 files changed, 29 insertions(+), 33 deletions(-) diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/settings/meta/SettingsFragmentMeta.kt b/app/src/main/java/de/jrpie/android/launcher/ui/settings/meta/SettingsFragmentMeta.kt index 4cce930..26f276a 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/settings/meta/SettingsFragmentMeta.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/settings/meta/SettingsFragmentMeta.kt @@ -48,6 +48,15 @@ class SettingsFragmentMeta : Fragment(), UIObject { override fun setOnClicks() { + fun bindURL(view: View, urlRes: Int) { + view.setOnClickListener { + openInBrowser( + getString(urlRes), + requireContext() + ) + } + } + binding.settingsMetaButtonViewTutorial.setOnClickListener { openTutorial(requireContext()) } @@ -70,12 +79,7 @@ class SettingsFragmentMeta : Fragment(), UIObject { // view code - binding.settingsMetaButtonViewCode.setOnClickListener { - openInBrowser( - getString(R.string.settings_meta_link_github), - requireContext() - ) - } + bindURL(binding.settingsMetaButtonViewCode, R.string.settings_meta_link_github) // report a bug binding.settingsMetaButtonReportBug.setOnClickListener { @@ -111,37 +115,19 @@ class SettingsFragmentMeta : Fragment(), UIObject { } // join chat - binding.settingsMetaButtonJoinChat.setOnClickListener { - openInBrowser( - getString(R.string.settings_meta_chat_url), - requireContext() - ) - } - + bindURL(binding.settingsMetaButtonJoinChat, R.string.settings_meta_chat_url) // contact developer - binding.settingsMetaButtonContact.setOnClickListener { - openInBrowser( - getString(R.string.settings_meta_contact_url), - requireContext() - ) - } + // bindURL(binding.settingsMetaButtonContact, R.string.settings_meta_contact_url) // contact fork developer - binding.settingsMetaButtonForkContact.setOnClickListener { - openInBrowser( - getString(R.string.settings_meta_fork_contact_url), - requireContext() - ) - } + bindURL(binding.settingsMetaButtonForkContact, R.string.settings_meta_fork_contact_url) + + // donate + bindURL(binding.settingsMetaButtonDonate, R.string.settings_meta_donate_url) // privacy policy - binding.settingsMetaButtonPrivacy.setOnClickListener { - openInBrowser( - getString(R.string.settings_meta_privacy_url), - requireContext() - ) - } + bindURL(binding.settingsMetaButtonPrivacy, R.string.settings_meta_privacy_url) // legal info binding.settingsMetaButtonLicenses.setOnClickListener { diff --git a/app/src/main/res/layout/settings_meta.xml b/app/src/main/res/layout/settings_meta.xml index a5876e6..6f21baa 100644 --- a/app/src/main/res/layout/settings_meta.xml +++ b/app/src/main/res/layout/settings_meta.xml @@ -59,12 +59,12 @@ android:text="@string/settings_meta_join_chat" android:textAllCaps="false" /> - <Button + <!--<Button android:id="@+id/settings_meta_button_contact" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/settings_meta_contact" - android:textAllCaps="false" /> + android:textAllCaps="false" />--> <Button android:id="@+id/settings_meta_button_fork_contact" @@ -73,6 +73,13 @@ android:text="@string/settings_meta_fork_contact" android:textAllCaps="false" /> + <Button + android:id="@+id/settings_meta_button_donate" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/settings_meta_donate" + android:textAllCaps="false" /> + <Space android:layout_width="match_parent" android:layout_height="64sp" /> diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index cf7f681..349d730 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -129,6 +129,7 @@ <string name="dialog_report_bug_create_report">Report erstellen</string> <string name="settings_meta_fork_contact">Entwickler des Fork kontaktieren</string> <string name="settings_meta_join_chat">Dem µLauncher-Chat beitreten</string> + <string name="settings_meta_donate">Spenden</string> <string name="settings_meta_privacy">Datenschutzerklärung</string> <!-- - diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml index e5bd375..33d2e57 100644 --- a/app/src/main/res/values/donottranslate.xml +++ b/app/src/main/res/values/donottranslate.xml @@ -164,6 +164,7 @@ <string name="settings_meta_privacy_url" translatable="false">https://s.jrpie.de/android-legal</string> <string name="settings_meta_contact_url" translatable="false">https://www.finnmglas.com/contact/</string> <string name="settings_meta_chat_url" translatable="false">https://s.jrpie.de/launcher-chat</string> + <string name="settings_meta_donate_url" translatable="false">https://s.jrpie.de/launcher-donate</string> <!-- - diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1a79b5f..a051a67 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -210,6 +210,7 @@ <string name="settings_meta_fork_contact">Contact the developer of the fork</string> <string name="settings_meta_join_chat">Join µLauncher chat</string> + <string name="settings_meta_donate">Donate</string> <string name="settings_meta_privacy">Privacy Policy</string> From 492749a340995c832c07fe16fb884f7762985cd3 Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Fri, 14 Mar 2025 16:03:59 +0100 Subject: [PATCH 21/73] remove global variables from ListActivity --- .../android/launcher/ui/list/ListActivity.kt | 27 +++++++++---------- .../launcher/ui/list/apps/ListFragmentApps.kt | 25 ++++++++--------- .../ui/list/other/OtherRecyclerAdapter.kt | 4 +-- 3 files changed, 25 insertions(+), 31 deletions(-) diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/list/ListActivity.kt b/app/src/main/java/de/jrpie/android/launcher/ui/list/ListActivity.kt index 95ed56e..64bd850 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/list/ListActivity.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/list/ListActivity.kt @@ -1,7 +1,6 @@ package de.jrpie.android.launcher.ui.list import android.app.Activity -import android.content.Context import android.content.Intent import android.content.res.Resources import android.graphics.Rect @@ -33,16 +32,6 @@ import de.jrpie.android.launcher.ui.list.apps.ListFragmentApps import de.jrpie.android.launcher.ui.list.other.ListFragmentOther -// TODO: Better solution for this intercommunication functionality (used in list-fragments) -var intention = ListActivity.ListActivityIntention.VIEW -var favoritesVisibility: AppFilter.Companion.AppSetVisibility = - AppFilter.Companion.AppSetVisibility.VISIBLE -var privateSpaceVisibility: AppFilter.Companion.AppSetVisibility = - AppFilter.Companion.AppSetVisibility.VISIBLE -var hiddenVisibility: AppFilter.Companion.AppSetVisibility = - AppFilter.Companion.AppSetVisibility.HIDDEN -var forGesture: String? = null - /** * The [ListActivity] is the most general purpose activity in Launcher: * - used to view all apps and edit their settings @@ -52,11 +41,19 @@ var forGesture: String? = null */ class ListActivity : AppCompatActivity(), UIObject { private lateinit var binding: ListBinding + var intention = ListActivityIntention.VIEW + var favoritesVisibility: AppFilter.Companion.AppSetVisibility = + AppFilter.Companion.AppSetVisibility.VISIBLE + var privateSpaceVisibility: AppFilter.Companion.AppSetVisibility = + AppFilter.Companion.AppSetVisibility.VISIBLE + var hiddenVisibility: AppFilter.Companion.AppSetVisibility = + AppFilter.Companion.AppSetVisibility.HIDDEN + var forGesture: String? = null private fun updateLockIcon(locked: Boolean) { if ( - // only show lock for VIEW intention + // only show lock for VIEW intention (intention != ListActivityIntention.VIEW) // hide lock when private space does not exist || !isPrivateSpaceSetUp(this) @@ -261,7 +258,7 @@ private val TAB_TITLES = arrayOf( * The [ListSectionsPagerAdapter] returns the fragment, * which corresponds to the selected tab in [ListActivity]. */ -class ListSectionsPagerAdapter(private val context: Context, fm: FragmentManager) : +class ListSectionsPagerAdapter(private val activity: ListActivity, fm: FragmentManager) : FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { override fun getItem(position: Int): Fragment { @@ -273,11 +270,11 @@ class ListSectionsPagerAdapter(private val context: Context, fm: FragmentManager } override fun getPageTitle(position: Int): CharSequence { - return context.resources.getString(TAB_TITLES[position]) + return activity.resources.getString(TAB_TITLES[position]) } override fun getCount(): Int { - return when (intention) { + return when (activity.intention) { ListActivity.ListActivityIntention.VIEW -> 1 else -> 2 } diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/ListFragmentApps.kt b/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/ListFragmentApps.kt index a02c50f..1a55bbb 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/ListFragmentApps.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/ListFragmentApps.kt @@ -17,11 +17,6 @@ import de.jrpie.android.launcher.databinding.ListAppsBinding import de.jrpie.android.launcher.preferences.LauncherPreferences import de.jrpie.android.launcher.ui.UIObject import de.jrpie.android.launcher.ui.list.ListActivity -import de.jrpie.android.launcher.ui.list.favoritesVisibility -import de.jrpie.android.launcher.ui.list.forGesture -import de.jrpie.android.launcher.ui.list.hiddenVisibility -import de.jrpie.android.launcher.ui.list.intention -import de.jrpie.android.launcher.ui.list.privateSpaceVisibility import de.jrpie.android.launcher.ui.openSoftKeyboard @@ -54,7 +49,7 @@ class ListFragmentApps : Fragment(), UIObject { .registerOnSharedPreferenceChangeListener(sharedPreferencesListener) binding.listAppsCheckBoxFavorites.isChecked = - (favoritesVisibility == AppFilter.Companion.AppSetVisibility.EXCLUSIVE) + ((activity as? ListActivity)?.favoritesVisibility == AppFilter.Companion.AppSetVisibility.EXCLUSIVE) } override fun onStop() { @@ -67,16 +62,17 @@ class ListFragmentApps : Fragment(), UIObject { override fun setOnClicks() {} override fun adjustLayout() { + val listActivity = activity as? ListActivity ?: return appsRecyclerAdapter = AppsRecyclerAdapter( - requireActivity(), binding.root, intention, forGesture, + listActivity, binding.root, listActivity.intention, listActivity.forGesture, appFilter = AppFilter( requireContext(), "", - favoritesVisibility = favoritesVisibility, - privateSpaceVisibility = privateSpaceVisibility, - hiddenVisibility = hiddenVisibility + favoritesVisibility = listActivity.favoritesVisibility, + privateSpaceVisibility = listActivity.privateSpaceVisibility, + hiddenVisibility = listActivity.hiddenVisibility ), layout = LauncherPreferences.list().layout() ) @@ -124,7 +120,8 @@ class ListFragmentApps : Fragment(), UIObject { if (newText == " " && !appsRecyclerAdapter.disableAutoLaunch && - intention == ListActivity.ListActivityIntention.VIEW && + (activity as? ListActivity)?.intention + == ListActivity.ListActivityIntention.VIEW && LauncherPreferences.functionality().searchAutoLaunch() ) { appsRecyclerAdapter.disableAutoLaunch = true @@ -141,17 +138,17 @@ class ListFragmentApps : Fragment(), UIObject { }) binding.listAppsCheckBoxFavorites.setOnClickListener { - favoritesVisibility = + listActivity.favoritesVisibility = if (binding.listAppsCheckBoxFavorites.isChecked) { AppFilter.Companion.AppSetVisibility.EXCLUSIVE } else { AppFilter.Companion.AppSetVisibility.VISIBLE } - appsRecyclerAdapter.setFavoritesVisibility(favoritesVisibility) + appsRecyclerAdapter.setFavoritesVisibility(listActivity.favoritesVisibility) (activity as? ListActivity)?.updateTitle() } - if (intention == ListActivity.ListActivityIntention.VIEW + if (listActivity.intention == ListActivity.ListActivityIntention.VIEW && LauncherPreferences.functionality().searchAutoOpenKeyboard() ) { binding.listAppsSearchview.openSoftKeyboard(requireContext()) 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 dfba334..70d5376 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 @@ -11,7 +11,7 @@ import androidx.recyclerview.widget.RecyclerView import de.jrpie.android.launcher.R import de.jrpie.android.launcher.REQUEST_CHOOSE_APP import de.jrpie.android.launcher.actions.LauncherAction -import de.jrpie.android.launcher.ui.list.forGesture +import de.jrpie.android.launcher.ui.list.ListActivity /** * The [OtherRecyclerAdapter] will only be displayed in the ListActivity, @@ -36,7 +36,7 @@ class OtherRecyclerAdapter(val activity: Activity) : val pos = bindingAdapterPosition val content = othersList[pos] - forGesture?.let { returnChoiceIntent(it, content) } + (activity as? ListActivity)?.forGesture?.let { returnChoiceIntent(it, content) } } init { From 541e60356c0e41d37b2f67f47810f51c3cbc68cd Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Fri, 14 Mar 2025 16:35:13 +0100 Subject: [PATCH 22/73] implement #98 - disable functionality because of Android bug: https://issuetracker.google.com/issues/352276244#comment5 --- .../de/jrpie/android/launcher/apps/PrivateSpace.kt | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/de/jrpie/android/launcher/apps/PrivateSpace.kt b/app/src/main/java/de/jrpie/android/launcher/apps/PrivateSpace.kt index a1241af..e44ff1c 100644 --- a/app/src/main/java/de/jrpie/android/launcher/apps/PrivateSpace.kt +++ b/app/src/main/java/de/jrpie/android/launcher/apps/PrivateSpace.kt @@ -91,6 +91,7 @@ fun isPrivateSpaceLocked(context: Context): Boolean { val privateSpaceUser = getPrivateSpaceUser(context) ?: return false return userManager.isQuietModeEnabled(privateSpaceUser) } + fun lockPrivateSpace(context: Context, lock: Boolean) { if (!isPrivateSpaceSupported()) { return @@ -123,10 +124,16 @@ fun togglePrivateSpaceLock(context: Context) { } fun hidePrivateSpaceWhenLocked(context: Context): Boolean { - // TODO: perhaps this should be cached + // Trying to access the setting as a 3rd party launcher raises a security exception. + // This is an Android bug: https://issuetracker.google.com/issues/352276244#comment5 + // The logic for this is implemented. + // TODO: replace this once the Android bug is fixed + return false + // TODO: perhaps this should be cached // https://cs.android.com/android/platform/superproject/main/+/main:packages/apps/Launcher3/src/com/android/launcher3/util/SettingsCache.java;l=61;drc=56bf7ad33bc9d5ed3c18e7abefeec5c177ec75d7 - val key = "hide_privatespace_entry_point" - return Settings.Secure.getInt(context.contentResolver, key, 0) == 1 + + // val key = "hide_privatespace_entry_point" + // return Settings.Secure.getInt(context.contentResolver, key, 0) == 1 } From e02ca4091faf0a457dd2239505859ae9fa19fa60 Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Fri, 14 Mar 2025 16:35:41 +0100 Subject: [PATCH 23/73] 0.1.0 --- app/build.gradle | 4 ++-- app/src/main/res/values/strings.xml | 2 +- fastlane/metadata/android/en-US/changelogs/40.txt | 13 +++++++++++++ 3 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 fastlane/metadata/android/en-US/changelogs/40.txt diff --git a/app/build.gradle b/app/build.gradle index 103ce56..c75bb3d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -23,8 +23,8 @@ android { minSdkVersion 21 targetSdkVersion 35 compileSdk 35 - versionCode 39 - versionName "0.0.23" + versionCode 40 + versionName "0.1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a051a67..4512b62 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -179,7 +179,7 @@ <string name="settings_apps_hide_paused_apps">Hide paused apps</string> <string name="settings_apps_hide_private_space_apps">Hide private space from app list</string> <string name="settings_list_layout">Layout of app list</string> - <string name="settings_list_reverse_layout">Reverse app list</string> + <string name="settings_list_reverse_layout">Reverse the app list</string> <string name="settings_list_layout_item_default">Default</string> <string name="settings_list_layout_item_text">Text</string> diff --git a/fastlane/metadata/android/en-US/changelogs/40.txt b/fastlane/metadata/android/en-US/changelogs/40.txt new file mode 100644 index 0000000..b457e2f --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/40.txt @@ -0,0 +1,13 @@ +* Pinned shortcuts can now be added to app list +* New action: adjust volume (thank you, zabrinu!) +* Added option to hide navigation bar (thank you, acanoe!) +* Added option to reverse the app list (thank you, spacefrogg!) +* Show question mark icon when an unknown app is bound to a gesture + +* Improved German translation +* Improved Portuguese translation (thank you, "Vossa Excelencia"!) + +* Fixed detection of long click gesture +* Fixed blurred text in dialogs +* Fixed a crash when private space is locked after app restarts (thank you, alexytomi!) +* Fixed some additional bugs From 3597baee1f7d3c1a07c08db3e8956a051aef6cad Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Fri, 14 Mar 2025 22:33:08 +0100 Subject: [PATCH 24/73] fix problem which switching from grayscale icons back to normal --- .../main/java/de/jrpie/android/launcher/Functions.kt | 2 +- .../main/java/de/jrpie/android/launcher/ui/Helper.kt | 12 ++++++++---- .../launcher/ui/list/apps/AppsRecyclerAdapter.kt | 12 ++++++------ .../actions/SettingsFragmentActionsRecycler.kt | 4 +--- 4 files changed, 16 insertions(+), 14 deletions(-) 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 57f13a5..d5e8d13 100644 --- a/app/src/main/java/de/jrpie/android/launcher/Functions.kt +++ b/app/src/main/java/de/jrpie/android/launcher/Functions.kt @@ -194,7 +194,7 @@ fun getApps( loadList.add(detailedAppInfo) } } - loadList.sortBy { it.getCustomLabel(context).toString() } + loadList.sortBy { it.getCustomLabel(context) } var end = System.currentTimeMillis() Log.i(LOG_TAG, "${loadList.size} apps loaded (${end - start}ms)") diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/Helper.kt b/app/src/main/java/de/jrpie/android/launcher/ui/Helper.kt index b8fc82e..1ca4d2b 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/Helper.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/Helper.kt @@ -27,10 +27,14 @@ fun View.blink( } // Taken from: https://stackoverflow.com/a/30340794/12787264 -fun ImageView.transformGrayscale() { - this.colorFilter = ColorMatrixColorFilter(ColorMatrix().apply { - setSaturation(0f) - }) +fun ImageView.transformGrayscale(grayscale: Boolean) { + this.colorFilter = if (grayscale) { + ColorMatrixColorFilter(ColorMatrix().apply { + setSaturation(0f) + }) + } else { + null + } } diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/AppsRecyclerAdapter.kt b/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/AppsRecyclerAdapter.kt index 1f275e4..c4428b7 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/AppsRecyclerAdapter.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/AppsRecyclerAdapter.kt @@ -47,6 +47,7 @@ class AppsRecyclerAdapter( private val apps = (activity.applicationContext as Application).apps private val appsListDisplayed: MutableList<AbstractDetailedAppInfo> = mutableListOf() + private val grayscale = LauncherPreferences.theme().monochromeIcons() // temporarily disable auto launch var disableAutoLaunch: Boolean = false @@ -79,20 +80,19 @@ class AppsRecyclerAdapter( override fun onBindViewHolder(viewHolder: ViewHolder, i: Int) { var appLabel = appsListDisplayed[i].getCustomLabel(activity) + val appIcon = appsListDisplayed[i].getIcon(activity) + + viewHolder.img.transformGrayscale(grayscale) + viewHolder.img.setImageDrawable(appIcon.constantState?.newDrawable() ?: appIcon) + if (layout.useBadgedText) { appLabel = activity.packageManager.getUserBadgedLabel( appLabel, appsListDisplayed[i].getUser(activity) ).toString() } - - val appIcon = appsListDisplayed[i].getIcon(activity) - viewHolder.textView.text = appLabel - viewHolder.img.setImageDrawable(appIcon) - if (LauncherPreferences.theme().monochromeIcons()) - viewHolder.img.transformGrayscale() // decide when to show the options popup menu about if (intention == ListActivity.ListActivityIntention.VIEW) { diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/settings/actions/SettingsFragmentActionsRecycler.kt b/app/src/main/java/de/jrpie/android/launcher/ui/settings/actions/SettingsFragmentActionsRecycler.kt index 1f91913..630b5b0 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/settings/actions/SettingsFragmentActionsRecycler.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/settings/actions/SettingsFragmentActionsRecycler.kt @@ -143,9 +143,7 @@ class ActionsRecyclerAdapter(val activity: Activity) : val description = gesture.getDescription(activity) viewHolder.descriptionTextView.text = description - - if (LauncherPreferences.theme().monochromeIcons()) - viewHolder.img.transformGrayscale() + viewHolder.img.transformGrayscale(LauncherPreferences.theme().monochromeIcons()) updateViewHolder(gesture, viewHolder) viewHolder.img.setOnClickListener { chooseApp(gesture) } From c1511cd475331381221bdfe4a033f31006fb86b1 Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Sat, 15 Mar 2025 03:11:08 +0100 Subject: [PATCH 25/73] merge #124 - improve tutorial * Add new "app list" section * Rename fragments * Replace screenshots * Replace ViewPager by ViewPager2 * Add navigation buttons Co-authored-by: Luke Wass <wassupluke@gmail.com> --- .../launcher/ui/tutorial/TutorialActivity.kt | 109 ++++++++++++------ ...mentStart.kt => TutorialFragment0Start.kt} | 12 +- ...Concept.kt => TutorialFragment1Concept.kt} | 10 +- ...mentUsage.kt => TutorialFragment2Usage.kt} | 6 +- .../tutorial/tabs/TutorialFragment3AppList.kt | 30 +++++ ...mentSetup.kt => TutorialFragment4Setup.kt} | 6 +- ...ntFinish.kt => TutorialFragment5Finish.kt} | 10 +- .../drawable/baseline_navigate_before_24.xml | 11 ++ .../drawable/baseline_navigate_next_24.xml | 11 ++ .../main/res/drawable/home_round_screen.png | Bin 163224 -> 0 bytes app/src/main/res/drawable/round_outline.xml | 6 + .../main/res/drawable/tutorial_app_list.png | Bin 0 -> 127430 bytes .../res/drawable/tutorial_home_screen.png | Bin 0 -> 23704 bytes app/src/main/res/layout/tutorial.xml | 32 ++++- ...utorial_start.xml => tutorial_0_start.xml} | 14 +-- ...ial_concept.xml => tutorial_1_concept.xml} | 21 +++- ...utorial_usage.xml => tutorial_2_usage.xml} | 6 +- .../main/res/layout/tutorial_3_app_list.xml | 64 ++++++++++ ...utorial_setup.xml => tutorial_4_setup.xml} | 2 +- ...orial_finish.xml => tutorial_5_finish.xml} | 3 +- app/src/main/res/values/donottranslate.xml | 2 +- app/src/main/res/values/strings.xml | 47 ++++---- 22 files changed, 298 insertions(+), 104 deletions(-) rename app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/{TutorialFragmentStart.kt => TutorialFragment0Start.kt} (59%) rename app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/{TutorialFragmentConcept.kt => TutorialFragment1Concept.kt} (68%) rename app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/{TutorialFragmentUsage.kt => TutorialFragment2Usage.kt} (75%) create mode 100644 app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment3AppList.kt rename app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/{TutorialFragmentSetup.kt => TutorialFragment4Setup.kt} (74%) rename app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/{TutorialFragmentFinish.kt => TutorialFragment5Finish.kt} (80%) create mode 100644 app/src/main/res/drawable/baseline_navigate_before_24.xml create mode 100644 app/src/main/res/drawable/baseline_navigate_next_24.xml delete mode 100644 app/src/main/res/drawable/home_round_screen.png create mode 100644 app/src/main/res/drawable/round_outline.xml create mode 100644 app/src/main/res/drawable/tutorial_app_list.png create mode 100644 app/src/main/res/drawable/tutorial_home_screen.png rename app/src/main/res/layout/{tutorial_start.xml => tutorial_0_start.xml} (62%) rename app/src/main/res/layout/{tutorial_concept.xml => tutorial_1_concept.xml} (75%) rename app/src/main/res/layout/{tutorial_usage.xml => tutorial_2_usage.xml} (92%) create mode 100644 app/src/main/res/layout/tutorial_3_app_list.xml rename app/src/main/res/layout/{tutorial_setup.xml => tutorial_4_setup.xml} (95%) rename app/src/main/res/layout/{tutorial_finish.xml => tutorial_5_finish.xml} (92%) diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/TutorialActivity.kt b/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/TutorialActivity.kt index fd60d19..12c6c8a 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/TutorialActivity.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/TutorialActivity.kt @@ -4,23 +4,26 @@ import android.content.Intent import android.content.res.Resources import android.os.Build import android.os.Bundle +import android.view.View import android.window.OnBackInvokedDispatcher import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment -import androidx.fragment.app.FragmentManager -import androidx.fragment.app.FragmentPagerAdapter -import androidx.viewpager.widget.ViewPager -import com.google.android.material.tabs.TabLayout -import de.jrpie.android.launcher.R +import androidx.fragment.app.FragmentActivity +import androidx.viewpager2.adapter.FragmentStateAdapter +import androidx.viewpager2.widget.ViewPager2 +import com.google.android.material.tabs.TabLayoutMediator import de.jrpie.android.launcher.REQUEST_CHOOSE_APP +import de.jrpie.android.launcher.databinding.TutorialBinding import de.jrpie.android.launcher.preferences.LauncherPreferences import de.jrpie.android.launcher.saveListActivityChoice import de.jrpie.android.launcher.ui.UIObject -import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragmentConcept -import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragmentFinish -import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragmentSetup -import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragmentStart -import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragmentUsage +import de.jrpie.android.launcher.ui.blink +import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragment0Start +import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragment1Concept +import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragment2Usage +import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragment3AppList +import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragment4Setup +import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragment5Finish /** * The [TutorialActivity] is displayed automatically on new installations. @@ -31,10 +34,16 @@ import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragmentUsage */ class TutorialActivity : AppCompatActivity(), UIObject { + private lateinit var binding: TutorialBinding + override fun onCreate(savedInstanceState: Bundle?) { super<AppCompatActivity>.onCreate(savedInstanceState) super<UIObject>.onCreate() + // Initialise layout + binding = TutorialBinding.inflate(layoutInflater) + setContentView(binding.root) + // Handle back key / gesture on Android 13+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { onBackInvokedDispatcher.registerOnBackInvokedCallback( @@ -48,15 +57,51 @@ class TutorialActivity : AppCompatActivity(), UIObject { } } - // Initialise layout - setContentView(R.layout.tutorial) // set up tabs and swiping in settings - val sectionsPagerAdapter = TutorialSectionsPagerAdapter(supportFragmentManager) - val viewPager: ViewPager = findViewById(R.id.tutorial_viewpager) - viewPager.adapter = sectionsPagerAdapter - val tabs: TabLayout = findViewById(R.id.tutorial_tabs) - tabs.setupWithViewPager(viewPager) + val sectionsPagerAdapter = TutorialSectionsPagerAdapter(this) + binding.tutorialViewpager.apply { + adapter = sectionsPagerAdapter + currentItem = 0 + registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { + override fun onPageSelected(position: Int) { + binding.tutorialButtonNext.apply { + val lastItem = sectionsPagerAdapter.itemCount - 1 + visibility = if (position == lastItem) { + View.INVISIBLE + } else { + View.VISIBLE + } + if (position == 0) { + blink() + } else { + clearAnimation() + } + } + binding.tutorialButtonBack.apply { + visibility = if (position == 0) { + View.INVISIBLE + } else { + View.VISIBLE + } + } + } + }) + } + TabLayoutMediator(binding.tutorialTabs, binding.tutorialViewpager) { _, _ -> }.attach() + binding.tutorialButtonNext.setOnClickListener { + binding.tutorialViewpager.apply { + setCurrentItem( + (currentItem + 1).coerceAtMost(sectionsPagerAdapter.itemCount - 1), + true + ) + } + } + binding.tutorialButtonBack.setOnClickListener { + binding.tutorialViewpager.apply { + setCurrentItem((currentItem - 1).coerceAtLeast(0), true) + } + } } override fun getTheme(): Resources.Theme { @@ -89,26 +134,22 @@ class TutorialActivity : AppCompatActivity(), UIObject { * * Tabs: (Start | Concept | Usage | Setup | Finish) */ -class TutorialSectionsPagerAdapter(fm: FragmentManager) : - FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { +class TutorialSectionsPagerAdapter(activity: FragmentActivity) : + FragmentStateAdapter(activity) { - override fun getItem(position: Int): Fragment { + override fun getItemCount(): Int { + return 6 + } + + override fun createFragment(position: Int): Fragment { return when (position) { - 0 -> TutorialFragmentStart() - 1 -> TutorialFragmentConcept() - 2 -> TutorialFragmentUsage() - 3 -> TutorialFragmentSetup() - 4 -> TutorialFragmentFinish() + 0 -> TutorialFragment0Start() + 1 -> TutorialFragment1Concept() + 2 -> TutorialFragment2Usage() + 3 -> TutorialFragment3AppList() + 4 -> TutorialFragment4Setup() + 5 -> TutorialFragment5Finish() else -> Fragment() } } - - /* We don't use titles here, as we have the dots */ - override fun getPageTitle(position: Int): CharSequence { - return "" - } - - override fun getCount(): Int { - return 5 - } } diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragmentStart.kt b/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment0Start.kt similarity index 59% rename from app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragmentStart.kt rename to app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment0Start.kt index 445ded1..5ce5920 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragmentStart.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment0Start.kt @@ -5,24 +5,22 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment -import de.jrpie.android.launcher.databinding.TutorialStartBinding +import de.jrpie.android.launcher.databinding.Tutorial0StartBinding import de.jrpie.android.launcher.ui.UIObject -import de.jrpie.android.launcher.ui.blink /** - * The [TutorialFragmentStart] is a used as a tab in the TutorialActivity. + * The [TutorialFragment0Start] is a used as a tab in the TutorialActivity. * * It displays info about the app and gets the user into the tutorial */ -class TutorialFragmentStart : Fragment(), UIObject { +class TutorialFragment0Start : Fragment(), UIObject { - private lateinit var binding: TutorialStartBinding + private lateinit var binding: Tutorial0StartBinding override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { - binding = TutorialStartBinding.inflate(inflater, container, false) - binding.tutorialStartIconRight.blink() + binding = Tutorial0StartBinding.inflate(inflater, container, false) return binding.root } diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragmentConcept.kt b/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment1Concept.kt similarity index 68% rename from app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragmentConcept.kt rename to app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment1Concept.kt index f0fd233..876266e 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragmentConcept.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment1Concept.kt @@ -6,22 +6,22 @@ import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import de.jrpie.android.launcher.BuildConfig -import de.jrpie.android.launcher.databinding.TutorialConceptBinding +import de.jrpie.android.launcher.databinding.Tutorial1ConceptBinding import de.jrpie.android.launcher.ui.UIObject /** - * The [TutorialFragmentConcept] is a used as a tab in the TutorialActivity. + * The [TutorialFragment1Concept] is a used as a tab in the TutorialActivity. * * It is used to display info about Launchers concept (open source, efficiency ...) */ -class TutorialFragmentConcept : Fragment(), UIObject { - private lateinit var binding: TutorialConceptBinding +class TutorialFragment1Concept : Fragment(), UIObject { + private lateinit var binding: Tutorial1ConceptBinding override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { - binding = TutorialConceptBinding.inflate(inflater, container, false) + binding = Tutorial1ConceptBinding.inflate(inflater, container, false) binding.tutorialConceptBadgeVersion.text = BuildConfig.VERSION_NAME return binding.root } diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragmentUsage.kt b/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment2Usage.kt similarity index 75% rename from app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragmentUsage.kt rename to app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment2Usage.kt index 90db232..4b24dcd 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragmentUsage.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment2Usage.kt @@ -9,17 +9,17 @@ import de.jrpie.android.launcher.R import de.jrpie.android.launcher.ui.UIObject /** - * The [TutorialFragmentUsage] is a used as a tab in the TutorialActivity. + * The [TutorialFragment2Usage] is a used as a tab in the TutorialActivity. * * Tells the user how his screen will look and how the app can be used */ -class TutorialFragmentUsage : Fragment(), UIObject { +class TutorialFragment2Usage : Fragment(), UIObject { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - return inflater.inflate(R.layout.tutorial_usage, container, false) + return inflater.inflate(R.layout.tutorial_2_usage, container, false) } override fun onStart() { diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment3AppList.kt b/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment3AppList.kt new file mode 100644 index 0000000..78698aa --- /dev/null +++ b/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment3AppList.kt @@ -0,0 +1,30 @@ +package de.jrpie.android.launcher.ui.tutorial.tabs + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import de.jrpie.android.launcher.R +import de.jrpie.android.launcher.ui.UIObject + +/** + * The [TutorialFragment3AppList] is a used as a tab in the TutorialActivity. + * + * Tells the user how his screen will look and how the app can be used + */ +class TutorialFragment3AppList : Fragment(), UIObject { + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + return inflater.inflate(R.layout.tutorial_3_app_list, container, false) + } + + override fun onStart() { + super<Fragment>.onStart() + super<UIObject>.onStart() + } + +} diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragmentSetup.kt b/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment4Setup.kt similarity index 74% rename from app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragmentSetup.kt rename to app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment4Setup.kt index 09ef4c9..56eb6ca 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragmentSetup.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment4Setup.kt @@ -9,17 +9,17 @@ import de.jrpie.android.launcher.R import de.jrpie.android.launcher.ui.UIObject /** - * The [TutorialFragmentSetup] is a used as a tab in the TutorialActivity. + * The [TutorialFragment4Setup] is a used as a tab in the TutorialActivity. * * It is used to display info in the tutorial */ -class TutorialFragmentSetup : Fragment(), UIObject { +class TutorialFragment4Setup : Fragment(), UIObject { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - return inflater.inflate(R.layout.tutorial_setup, container, false) + return inflater.inflate(R.layout.tutorial_4_setup, container, false) } override fun onStart() { diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragmentFinish.kt b/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment5Finish.kt similarity index 80% rename from app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragmentFinish.kt rename to app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment5Finish.kt index 2d01d0a..2fd093e 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragmentFinish.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment5Finish.kt @@ -6,25 +6,25 @@ import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import de.jrpie.android.launcher.BuildConfig.VERSION_CODE -import de.jrpie.android.launcher.databinding.TutorialFinishBinding +import de.jrpie.android.launcher.databinding.Tutorial5FinishBinding import de.jrpie.android.launcher.preferences.LauncherPreferences import de.jrpie.android.launcher.setDefaultHomeScreen import de.jrpie.android.launcher.ui.UIObject /** - * The [TutorialFragmentFinish] is a used as a tab in the TutorialActivity. + * The [TutorialFragment5Finish] is a used as a tab in the TutorialActivity. * * It is used to display further resources and let the user start Launcher */ -class TutorialFragmentFinish : Fragment(), UIObject { +class TutorialFragment5Finish : Fragment(), UIObject { - private lateinit var binding: TutorialFinishBinding + private lateinit var binding: Tutorial5FinishBinding override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { - binding = TutorialFinishBinding.inflate(inflater, container, false) + binding = Tutorial5FinishBinding.inflate(inflater, container, false) return binding.root } diff --git a/app/src/main/res/drawable/baseline_navigate_before_24.xml b/app/src/main/res/drawable/baseline_navigate_before_24.xml new file mode 100644 index 0000000..4097b26 --- /dev/null +++ b/app/src/main/res/drawable/baseline_navigate_before_24.xml @@ -0,0 +1,11 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + + <path + android:fillColor="?android:textColor" + android:pathData="M15.41,7.41L14,6l-6,6 6,6 1.41,-1.41L10.83,12z" /> + +</vector> diff --git a/app/src/main/res/drawable/baseline_navigate_next_24.xml b/app/src/main/res/drawable/baseline_navigate_next_24.xml new file mode 100644 index 0000000..22cef28 --- /dev/null +++ b/app/src/main/res/drawable/baseline_navigate_next_24.xml @@ -0,0 +1,11 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + + <path + android:fillColor="?android:textColor" + android:pathData="M10,6L8.59,7.41 13.17,12l-4.58,4.59L10,18l6,-6z" /> + +</vector> diff --git a/app/src/main/res/drawable/home_round_screen.png b/app/src/main/res/drawable/home_round_screen.png deleted file mode 100644 index f0237e8a5e25863a283f5c06d714db6a7fa9d3e4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 163224 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ⅈHbq)y8JA0;Dv*1{~G> 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	^!xyW@^&X00eos|<u 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 diff --git a/app/src/main/res/drawable/round_outline.xml b/app/src/main/res/drawable/round_outline.xml new file mode 100644 index 0000000..3650338 --- /dev/null +++ b/app/src/main/res/drawable/round_outline.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- https://stackoverflow.com/a/30692466 --> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle"> + <corners android:radius="10dp" /> +</shape> \ No newline at end of file diff --git a/app/src/main/res/drawable/tutorial_app_list.png b/app/src/main/res/drawable/tutorial_app_list.png new file mode 100644 index 0000000000000000000000000000000000000000..66ebaaf7db1e6207f91fc549513c0d8947b481c2 GIT binary patch literal 127430 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%0DY7oKfb*{gTc$@&;BQd3iR%%>{Su9 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�G03`|y&LZ2oDb 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/tutorial_home_screen.png b/app/src/main/res/drawable/tutorial_home_screen.png new file mode 100644 index 0000000000000000000000000000000000000000..ccbce5def5eb0584ae3c516aa0bf0a118bfaeda1 GIT binary patch literal 23704 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 U?n~QjbmE$k`5z@$Zv6GX0F|~}$p8QV literal 0 HcmV?d00001 diff --git a/app/src/main/res/layout/tutorial.xml b/app/src/main/res/layout/tutorial.xml index 7f2fd8c..5520aa1 100644 --- a/app/src/main/res/layout/tutorial.xml +++ b/app/src/main/res/layout/tutorial.xml @@ -10,7 +10,7 @@ tools:context=".ui.tutorial.TutorialActivity"> - <androidx.viewpager.widget.ViewPager + <androidx.viewpager2.widget.ViewPager2 android:id="@+id/tutorial_viewpager" android:layout_width="0dp" android:layout_height="0dp" @@ -22,15 +22,37 @@ app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.0" /> + <ImageView + android:id="@+id/tutorial_button_back" + android:layout_width="50dp" + android:layout_height="50dp" + android:gravity="center" + android:alpha="0.5" + android:src="@drawable/baseline_navigate_before_24" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/tutorial_viewpager" /> + + <com.google.android.material.tabs.TabLayout android:id="@+id/tutorial_tabs" - android:layout_width="match_parent" - android:layout_height="wrap_content" + android:layout_width="0dp" + android:layout_height="50dp" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toStartOf="@+id/tutorial_button_next" + app:layout_constraintStart_toEndOf="@+id/tutorial_button_back" app:tabBackground="@drawable/tutorial_tab_selector" app:tabGravity="center" - app:tabIndicatorHeight="0dp" + app:tabIndicatorHeight="0dp" /> + + <ImageView + android:id="@+id/tutorial_button_next" + android:layout_width="50dp" + android:layout_height="50dp" + android:gravity="center" + android:src="@drawable/baseline_navigate_next_24" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" /> + app:layout_constraintTop_toBottomOf="@+id/tutorial_viewpager" /> </androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/tutorial_start.xml b/app/src/main/res/layout/tutorial_0_start.xml similarity index 62% rename from app/src/main/res/layout/tutorial_start.xml rename to app/src/main/res/layout/tutorial_0_start.xml index f431486..d383f5e 100644 --- a/app/src/main/res/layout/tutorial_start.xml +++ b/app/src/main/res/layout/tutorial_0_start.xml @@ -8,7 +8,7 @@ android:paddingRight="32sp" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".ui.tutorial.tabs.TutorialFragmentStart"> + tools:context=".ui.tutorial.tabs.TutorialFragment0Start"> <TextView android:id="@+id/tutorial_start_text" @@ -21,16 +21,4 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> - - <TextView - android:id="@+id/tutorial_start_icon_right" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text=">>>>>>" - android:textSize="64sp" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/tutorial_start_text" /> - </androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/tutorial_concept.xml b/app/src/main/res/layout/tutorial_1_concept.xml similarity index 75% rename from app/src/main/res/layout/tutorial_concept.xml rename to app/src/main/res/layout/tutorial_1_concept.xml index 9b8495b..9b85552 100644 --- a/app/src/main/res/layout/tutorial_concept.xml +++ b/app/src/main/res/layout/tutorial_1_concept.xml @@ -8,7 +8,7 @@ android:paddingRight="32sp" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".ui.tutorial.tabs.TutorialFragmentConcept"> + tools:context=".ui.tutorial.tabs.TutorialFragment1Concept"> <TextView android:id="@+id/tutorial_concept_title" @@ -28,11 +28,10 @@ android:gravity="center" android:text="@string/tutorial_concept_text" android:textSize="18sp" - app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/tutorial_concept_title" - app:layout_constraintVertical_bias="0.19999999" /> + app:layout_constraintBottom_toTopOf="@id/tutorial_concept_badge_version_label"/> <TextView android:id="@+id/tutorial_concept_text_2" @@ -60,6 +59,22 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/tutorial_concept_text" + tools:text="0.0.7" + tools:ignore="ContentDescription" /> + + <TextView + android:id="@+id/tutorial_concept_badge_version_label" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginStart="32dp" + android:layout_marginEnd="32dp" + android:gravity="center" + android:textSize="18sp" + android:text="@string/tutorial_concept_label_version" + app:layout_constraintBottom_toTopOf="@+id/tutorial_concept_badge_version" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintHorizontal_bias="0.0" + app:layout_constraintStart_toStartOf="parent" tools:ignore="ContentDescription" /> </androidx.constraintlayout.widget.ConstraintLayout> diff --git a/app/src/main/res/layout/tutorial_usage.xml b/app/src/main/res/layout/tutorial_2_usage.xml similarity index 92% rename from app/src/main/res/layout/tutorial_usage.xml rename to app/src/main/res/layout/tutorial_2_usage.xml index 29bc475..d395eee 100644 --- a/app/src/main/res/layout/tutorial_usage.xml +++ b/app/src/main/res/layout/tutorial_2_usage.xml @@ -7,7 +7,7 @@ android:layout_height="match_parent" android:paddingLeft="32sp" android:paddingRight="32sp" - tools:context=".ui.tutorial.tabs.TutorialFragmentUsage"> + tools:context=".ui.tutorial.tabs.TutorialFragment2Usage"> <TextView android:id="@+id/tutorial_usage_title" @@ -39,12 +39,12 @@ android:layout_width="0dp" android:layout_height="0dp" android:scaleType="centerInside" - android:src="@drawable/home_round_screen" + android:src="@drawable/tutorial_home_screen" app:layout_constraintBottom_toTopOf="@id/tutorial_usage_text_2" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="@+id/tutorial_usage_text" app:layout_constraintTop_toBottomOf="@id/tutorial_usage_text" - app:srcCompat="@drawable/home_round_screen" + app:srcCompat="@drawable/tutorial_home_screen" tools:ignore="ContentDescription" /> <TextView diff --git a/app/src/main/res/layout/tutorial_3_app_list.xml b/app/src/main/res/layout/tutorial_3_app_list.xml new file mode 100644 index 0000000..ae7eda1 --- /dev/null +++ b/app/src/main/res/layout/tutorial_3_app_list.xml @@ -0,0 +1,64 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/tutorial_usage_container" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingLeft="32sp" + android:paddingRight="32sp" + tools:context=".ui.tutorial.tabs.TutorialFragment3AppList"> + + <TextView + android:id="@+id/tutorial_app_list_title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="16dp" + android:text="@string/tutorial_app_list_title" + android:textSize="30sp" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <TextView + android:id="@+id/tutorial_app_list_text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="16dp" + android:layout_marginBottom="32dp" + android:gravity="center" + android:text="@string/tutorial_app_list_text" + android:textSize="18sp" + app:layout_constraintBottom_toTopOf="@+id/tutorial_app_list_screen" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/tutorial_app_list_title" /> + + <ImageView + android:id="@+id/tutorial_app_list_screen" + android:layout_width="0dp" + android:layout_height="0dp" + android:scaleType="centerInside" + android:src="@drawable/tutorial_app_list" + app:layout_constraintBottom_toTopOf="@id/tutorial_app_list_text_2" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="@+id/tutorial_app_list_text" + app:layout_constraintTop_toBottomOf="@id/tutorial_app_list_text" + app:srcCompat="@drawable/tutorial_app_list" + tools:ignore="ContentDescription" /> + + <TextView + android:id="@+id/tutorial_app_list_text_2" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="32dp" + android:layout_marginBottom="16dp" + android:gravity="center" + android:text="@string/tutorial_app_list_text_2" + android:textSize="18sp" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/tutorial_app_list_screen" /> + +</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/tutorial_setup.xml b/app/src/main/res/layout/tutorial_4_setup.xml similarity index 95% rename from app/src/main/res/layout/tutorial_setup.xml rename to app/src/main/res/layout/tutorial_4_setup.xml index 15990aa..bf62261 100644 --- a/app/src/main/res/layout/tutorial_setup.xml +++ b/app/src/main/res/layout/tutorial_4_setup.xml @@ -8,7 +8,7 @@ android:layout_height="match_parent" android:paddingLeft="32sp" android:paddingRight="32sp" - tools:context=".ui.tutorial.tabs.TutorialFragmentSetup"> + tools:context=".ui.tutorial.tabs.TutorialFragment4Setup"> <TextView android:id="@+id/tutorial_setup_title" diff --git a/app/src/main/res/layout/tutorial_finish.xml b/app/src/main/res/layout/tutorial_5_finish.xml similarity index 92% rename from app/src/main/res/layout/tutorial_finish.xml rename to app/src/main/res/layout/tutorial_5_finish.xml index eea44af..dedf53f 100644 --- a/app/src/main/res/layout/tutorial_finish.xml +++ b/app/src/main/res/layout/tutorial_5_finish.xml @@ -7,7 +7,7 @@ android:paddingRight="32sp" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".ui.tutorial.tabs.TutorialFragmentFinish"> + tools:context=".ui.tutorial.tabs.TutorialFragment5Finish"> <TextView android:id="@+id/tutorial_finish_title" @@ -24,6 +24,7 @@ android:id="@+id/tutorial_finish_text" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:gravity="center" android:text="@string/tutorial_finish_text" android:textSize="18sp" app:layout_constraintBottom_toTopOf="@id/tutorial_finish_button_start" diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml index 33d2e57..89ec086 100644 --- a/app/src/main/res/values/donottranslate.xml +++ b/app/src/main/res/values/donottranslate.xml @@ -176,7 +176,7 @@ <!-- Legal --> <string name="legal_info_text"><![CDATA[ - <h2>µLauncher</h2> + <h2>μLauncher</h2> Modifications to Launcher. <p><a href=\"https://github.com/jrpie/launcher\">github.com/jrpie/launcher</a></p> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4512b62..b94a92b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -193,7 +193,7 @@ <string name="settings_general_choose_home_screen">Set μLauncher as home screen</string> <string name="settings_meta_cant_select_launcher">App Info</string> - <string name="settings_meta_show_tutorial">View Launcher Tutorial</string> + <string name="settings_meta_show_tutorial">View µLauncher Tutorial</string> <string name="settings_meta_reset">Reset Settings</string> <string name="settings_meta_reset_confirm">You are going to discard all your preferences. Continue?</string> @@ -202,14 +202,14 @@ <string name="settings_meta_report_bug">Report a bug</string> <string name="dialog_report_bug_title">Report a bug</string> - <string name="dialog_report_bug_info">Thank you for helping to improve µLauncher!\nPlease consider adding the following information to your bug report:</string> + <string name="dialog_report_bug_info">Thank you for helping to improve μLauncher!\nPlease consider adding the following information to your bug report:</string> <string name="dialog_report_bug_button_clipboard">Copy to clipboard</string> <string name="dialog_report_bug_security_info">Please do not report security vulnerabilities publicly on GitHub, but use the following instead:</string> <string name="dialog_report_bug_button_security">Report a security vulnerability</string> <string name="dialog_report_bug_create_report">Create report</string> <string name="settings_meta_fork_contact">Contact the developer of the fork</string> - <string name="settings_meta_join_chat">Join µLauncher chat</string> + <string name="settings_meta_join_chat">Join μLauncher chat</string> <string name="settings_meta_donate">Donate</string> <string name="settings_meta_privacy">Privacy Policy</string> @@ -246,7 +246,7 @@ <string name="list_apps_search_hint">Search</string> <string name="list_apps_search_hint_no_auto_launch">Search (no auto launch)</string> - <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_favorites">Favorite Applications</string> <string name="list_other_list_private_space">Private Space</string> @@ -274,22 +274,29 @@ - --> <string name="tutorial_title">Tutorial</string> - <string name="tutorial_start_text">Take a few seconds to learn how to use this Launcher!</string> + <string name="tutorial_start_text">👋\n\nTake a few seconds to learn how to use this Launcher!</string> <string name="tutorial_concept_title">Concept</string> - <string name="tutorial_concept_text">Launcher is designed to be minimal, efficient and free of distraction. It is free of payments, ads and tracking services.</string> - <string name="tutorial_concept_text_2">The app is open-source (MIT license) and available on GitHub! Make sure to check out the repository!</string> + <string name="tutorial_concept_text">μLauncher is designed to be minimal, efficient and free of distraction. + \n\nIt contains no ads and collects no data.</string> + <string name="tutorial_concept_text_2">It is free software (MIT license)!\nMake sure to check out the repository!</string> + <string name="tutorial_concept_label_version">Version</string> <string name="tutorial_usage_title">Usage</string> <string name="tutorial_usage_text">Your home screen contains the local date and time. No distraction.</string> - <string name="tutorial_usage_text_2">You can launch your apps with a single swipe or button press. Choose some in the next slide.</string> + <string name="tutorial_usage_text_2">You can launch your most important apps with touch gestures or button presses.</string> + + <string name="tutorial_app_list_title">All Apps</string> + <string name="tutorial_app_list_text">You can quickly search through all apps in the app list.\n\nSwipe up to open it, or bind it to a different gesture.</string> + <string name="tutorial_app_list_text_2">Once only one app matches, it launches automatically.\nThis can be disabled by prefixing the query with a space.</string> + <string name="tutorial_setup_title">Setup</string> <string name="tutorial_setup_text">We chose some default apps for you. You can change them now if you want to:</string> <string name="tutorial_setup_text_2">You can also change your selection later.</string> <string name="tutorial_finish_title">Let\'s go!</string> - <string name="tutorial_finish_text">You are ready to get started! I hope this is of great value to you! - Finn (who made Launcher) \tand Josia (who made some improvements and maintains the fork μLauncher)</string> + <string name="tutorial_finish_text">You are ready to get started!\n\nI hope this is of great value to you!\n\n- Finn (who made Launcher) and Josia (who made some improvements and maintains the fork μLauncher)</string> <string name="tutorial_finish_button">Start</string> @@ -301,7 +308,7 @@ <string name="snackbar_app_hidden">App hidden. You can make it visible again in settings.</string> <string name="undo">Undo</string> <string name="list_other_expand_settings_panel">Quick Settings</string> - <string name="toast_device_admin_not_enabled">µLauncher needs to be a device admin in order to lock the screen.</string> + <string name="toast_device_admin_not_enabled">μLauncher needs to be a device admin in order to lock the screen.</string> <string name="device_admin_explanation">This is required for the lock screen action.</string> <string name="device_admin_description">Enable the lock screen action</string> <string name="alert_no_torch_found">No camera with torch detected.</string> @@ -311,18 +318,18 @@ <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_private_space_default_home_screen">μLauncher needs to be the default home screen to access private space.</string> <string name="tooltip_lock_private_space">Lock private space</string> <string name="tooltip_unlock_private_space">Unlock 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="accessibility_service_name">µLauncher - lock screen</string> + <string name="accessibility_service_name">μLauncher - lock screen</string> <string name="accessibility_service_description"> - Setting µLauncher as an accessibility service allows it to lock the screen. + Setting μLauncher as an accessibility service allows it to lock the screen. Note that excessive permissions are required. You should never grant such permissions lightly to any app. - µLauncher will use the accessibility service only for locking the screen. You can check the source code to make sure. + μLauncher will use the accessibility service only for locking the screen. You can check the source code to make sure. - Note that locking the screen can also be accomplished by granting µLauncher device administrator permissions. However that method doesn\'t work with fingerprint and face unlock. + Note that locking the screen can also be accomplished by granting μLauncher device administrator permissions. However that method doesn\'t work with fingerprint and face unlock. </string> @@ -340,7 +347,7 @@ <h3>Accessibility Service</h3> Requires excessive privileges. - µLauncher will use those privileges only for locking the screen. + μLauncher will use those privileges only for locking the screen. <br/> (You really should not trust a random app you just downloaded with such a claim, but you can check the <a href=\"https://github.com/jrpie/Launcher\">source code</a>.) <br/> @@ -363,11 +370,11 @@ <string name="dialog_select_color_ok">Ok</string> <string name="dialog_select_color_color_hex">Color</string> <string name="dialog_choose_color_title">Choose color</string> - <string name="dialog_consent_accessibility_privileges">I am aware that this will grant far-reaching privileges to µLauncher.</string> + <string name="dialog_consent_accessibility_privileges">I am aware that this will grant far-reaching privileges to μLauncher.</string> <string name="dialog_consent_accessibility_other_options">I am aware that other options exist (using device administrator privileges or the power button).</string> - <string name="dialog_consent_accessibility_consent">I consent to µLauncher using the accessibility service to provide functionality unrelated to accessibility.</string> - <string name="dialog_consent_accessibility_data_collection">I consent to µLauncher not collecting any data.</string> - <string name="dialog_consent_accessibility_text"><![CDATA[You are about to activate the accessibility service. This will grant <strong>far-reaching privileges</strong> to µLauncher.<br/>µLauncher will use these privileges <strong>only to lock the screen</strong>. µLauncher <strong>will never collect any data</strong>. In particular, µLauncher does not use the accessibility service to collect any data.]]></string> + <string name="dialog_consent_accessibility_consent">I consent to μLauncher using the accessibility service to provide functionality unrelated to accessibility.</string> + <string name="dialog_consent_accessibility_data_collection">I consent to μLauncher not collecting any data.</string> + <string name="dialog_consent_accessibility_text"><![CDATA[You are about to activate the accessibility service. This will grant <strong>far-reaching privileges</strong> to μLauncher.<br/>μLauncher will use these privileges <strong>only to lock the screen</strong>. μLauncher <strong>will never collect any data</strong>. In particular, μLauncher does not use the accessibility service to collect any data.]]></string> <string name="dialog_consent_accessibility_title">Activating the Accessibility Service</string> <string name="dialog_consent_accessibility_ok">Activate Accessibility Service</string> <string name="dialog_cancel">Cancel</string> From 75b22400c5eee341938df2bf3aac68e8543f1eb0 Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Sat, 15 Mar 2025 17:24:19 +0100 Subject: [PATCH 26/73] try to fix #125 --- app/src/main/res/layout/list_apps_row.xml | 7 +++++-- app/src/main/res/layout/list_apps_row_variant_grid.xml | 3 ++- app/src/main/res/layout/list_apps_row_variant_text.xml | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/src/main/res/layout/list_apps_row.xml b/app/src/main/res/layout/list_apps_row.xml index 85ce5e6..0229195 100644 --- a/app/src/main/res/layout/list_apps_row.xml +++ b/app/src/main/res/layout/list_apps_row.xml @@ -15,18 +15,21 @@ app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" + tools:src="@mipmap/ic_launcher_round" tools:ignore="ContentDescription" /> <TextView android:id="@+id/list_apps_row_name" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginStart="60sp" + android:layout_marginStart="20sp" android:gravity="start" android:text="" android:textSize="20sp" + tools:text="@string/app_name" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintStart_toStartOf="parent" + app:layout_constraintStart_toEndOf="@id/list_apps_row_icon" + app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/list_apps_row_variant_grid.xml b/app/src/main/res/layout/list_apps_row_variant_grid.xml index 1a9058c..ee57c45 100644 --- a/app/src/main/res/layout/list_apps_row_variant_grid.xml +++ b/app/src/main/res/layout/list_apps_row_variant_grid.xml @@ -15,6 +15,7 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintEnd_toEndOf="parent" + tools:src="@mipmap/ic_launcher_round" tools:ignore="ContentDescription" /> <TextView @@ -25,7 +26,7 @@ android:paddingTop="5dp" android:text="" android:textSize="11sp" - tools:text="some app" + tools:text="@string/app_name" app:layout_constraintTop_toBottomOf="@id/list_apps_row_icon" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" diff --git a/app/src/main/res/layout/list_apps_row_variant_text.xml b/app/src/main/res/layout/list_apps_row_variant_text.xml index 700dd7c..cba4672 100644 --- a/app/src/main/res/layout/list_apps_row_variant_text.xml +++ b/app/src/main/res/layout/list_apps_row_variant_text.xml @@ -32,6 +32,6 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" - tools:text="some app" /> + tools:text="@string/app_name" /> </androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file From 72f9c0595f36debc74d713ed7226871d6470b4e3 Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Sat, 15 Mar 2025 19:23:44 +0100 Subject: [PATCH 27/73] handle MotionEvent.ACTION_CANCEL in TouchGestureDetector (see #126) --- .../launcher/ui/TouchGestureDetector.kt | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/TouchGestureDetector.kt b/app/src/main/java/de/jrpie/android/launcher/ui/TouchGestureDetector.kt index 1c05d54..74b8351 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/TouchGestureDetector.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/TouchGestureDetector.kt @@ -87,24 +87,40 @@ class TouchGestureDetector( } private var paths = HashMap<Int, PointerPath>() - private var gestureIsLongClick = false + + /* Set when + * - the longPressHandler has detected this gesture as a long press + * - the gesture was cancelled by MotionEvent.ACTION_CANCEL + * In any case, the current gesture should be ignored by further detection logic. + */ + private var cancelled = false private var lastTappedTime = 0L private var lastTappedLocation: Vector? = null fun onTouchEvent(event: MotionEvent) { + + if (event.actionMasked == MotionEvent.ACTION_CANCEL) { + synchronized(this@TouchGestureDetector) { + cancelled = true + } + } + val pointerIdToIndex = (0..<event.pointerCount).associateBy { event.getPointerId(it) } if (event.actionMasked == MotionEvent.ACTION_DOWN) { synchronized(this@TouchGestureDetector) { paths = HashMap() - gestureIsLongClick = false + cancelled = false } longPressHandler.postDelayed({ synchronized(this@TouchGestureDetector) { + if (cancelled) { + return@postDelayed + } if (paths.entries.size == 1 && paths.entries.firstOrNull()?.value?.isTap() == true) { - gestureIsLongClick = true + cancelled = true Gesture.LONG_CLICK.invoke(context) } } @@ -142,7 +158,7 @@ class TouchGestureDetector( // if the long press handler is still running, kill it longPressHandler.removeCallbacksAndMessages(null) // if the gesture was already detected as a long click, there is nothing to do - if (gestureIsLongClick) { + if (cancelled) { return } } From bd70b822cf6efdff8b70c4fdc616ae44082ef3f9 Mon Sep 17 00:00:00 2001 From: class0068 <monkeyotw@proton.me> Date: Thu, 13 Mar 2025 22:24:37 +0000 Subject: [PATCH 28/73] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 98.4% (251 of 255 strings) Translation: jrpie-Launcher/Launcher Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/zh_Hans/ --- app/src/main/res/values-zh-rCN/strings.xml | 61 +++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 793ef9d..72acf81 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -47,7 +47,7 @@ <string name="settings_display_full_screen">使用全屏</string> <string name="settings_launcher_section_functionality">功能</string> <string name="settings_enabled_gestures_edge_swipe">边缘滑动动作</string> - <string name="settings_functionality_auto_launch">零点击启动唯一搜索结果</string> + <string name="settings_functionality_auto_launch">直接启动匹配搜索内容的应用</string> <string name="settings_functionality_auto_keyboard">搜索时呼出键盘</string> <string name="settings_launcher_sensitivity">灵敏度</string> <string name="settings_meta_cant_select_launcher">应用信息</string> @@ -213,4 +213,63 @@ <string name="toast_private_space_default_home_screen">µLauncher 需要作为默认的主屏幕来访问私人空间。</string> <string name="toast_activity_not_found_search_web">没有找到处理搜索的应用。</string> <string name="toast_activity_not_found_browser">无法打开 URL:找不到浏览器。</string> + <string name="dialog_consent_accessibility_privileges">我已知晓,这将赋予 µLauncher 广泛且重要的权限。</string> + <string name="settings_apps_hide_private_space_apps">在应用程序列表中隐藏私人空间</string> + <string name="settings_apps_hide_paused_apps">隐藏已被暂停的应用</string> + <string name="settings_gesture_description_back">返回按键 / 返回手势</string> + <string name="settings_gesture_description_tap_down">先单击然后再下滑</string> + <string name="settings_functionality_search_web">在网络上搜索</string> + <string name="settings_gesture_description_swipe_smaller">(从)右上 (滑向)中左(滑向)右下</string> + <string name="settings_functionality_search_web_summary">通过按回车键在应用列表搜索界面激活网络搜索。</string> + <string name="settings_gesture_description_swipe_lambda">(从)左下 (滑向)中上(滑向)右下</string> + <string name="screen_lock_method_dialog_text"><![CDATA[ + <h1>选择锁定设备的方式</h1> + 有2种方式可以用来锁定屏幕。 + 遗憾的是,两者都有缺点:<br/><br/> + + <h3>通过设置“设备管理应用”</h3> + 无法和指纹解锁和脸部解锁共同使用。 + + <br/> + <br/> + + <h3>通过“无障碍”功能</h3> + 需要更多的权限。 + µLauncher 将这些权限仅用于锁定屏幕。 + <br/> + (对于任何一个从网上下载的应用所做的类似声明,你都不应该抱持“默认为可信”的态度,你可以并应该检查一下它的<a href=\"https://github.com/jrpie/Launcher\">源代码</a>.) + <br/> + 在某些设备上,激活辅助功能服务后,启动PIN码将不再用于加密数据。 + 如果遇到该问题,可以通过<a href="https://issuetracker.google.com/issues/37010136#comment36">该方法</a>重新激活启动PIN码用于数据加密。 + + <br/><br/><br/><br/> + 你可以在设置中随时更改这个选项。 + ]]></string> + <string name="list_apps_search_hint_no_auto_launch">搜索(不触发自动启动应用程序)</string> + <string name="dialog_consent_accessibility_text"><![CDATA[您即将激活“无障碍”服务。这将授予 µLauncher <strong>广泛且重要的权限</strong>。<br/>µLauncher 将这些权限<strong>仅用于锁定屏幕</strong>。µLauncher <strong>绝不会收集任何数据</strong>。尤其是,µLauncher 不会使用“无障碍”服务来收集任何数据。]]></string> + <string name="settings_gesture_description_swipe_larger">(从)左上 (滑向)中右(滑向)左下</string> + <string name="settings_gesture_tap_up">单击 + 上滑</string> + <string name="settings_gesture_tap_down">单击 + 下滑</string> + <string name="settings_gesture_tap_left">单击 + 左滑</string> + <string name="settings_gesture_description_tap_left">先单击然后再左滑</string> + <string name="settings_gesture_description_tap_up">先单击然后再上滑</string> + <string name="settings_gesture_tap_right">单击 + 右滑</string> + <string name="settings_gesture_description_tap_right">先单击然后再右滑</string> + <string name="settings_gesture_description_swipe_larger_reverse">(从)左下 (滑向)中右(滑向)左上</string> + <string name="settings_gesture_description_swipe_smaller_reverse">(从)右下 (滑向)中左(滑向)右上</string> + <string name="settings_gesture_description_swipe_v">(从)左上 (滑向)中下(滑向)右上</string> + <string name="settings_gesture_description_swipe_v_reverse">(从)右上 (滑向)中下(滑向)左上</string> + <string name="settings_gesture_description_swipe_lambda_reverse">(从)右下 (滑向)中上(滑向)左下</string> + <string name="settings_gesture_swipe_lambda_reverse">Λ (反向)</string> + <string name="settings_gesture_swipe_v_reverse">V(反向)</string> + <string name="settings_gesture_swipe_larger_reverse"><![CDATA[> (反向)]]></string> + <string name="settings_gesture_swipe_smaller_reverse"><![CDATA[< (反向)]]></string> + <string name="settings_functionality_auto_launch_summary">按空格键临时暂停该功能。</string> + <string name="settings_list_layout">应用程序列表样式</string> + <string name="pin_shortcut_button_bind">绑定到手势</string> + <string name="list_other_track_play_pause">音乐:播放 / 暂停</string> + <string name="dialog_report_bug_button_security">报告安全漏洞</string> + <string name="dialog_report_bug_security_info">安全漏洞请不要在 Github 上以公开的方式提交,而是使用以下方式进行报告:</string> + <string name="dialog_report_bug_info">感谢您帮助改进 µLauncher!\n请考虑在您的应用程序错误报告中添加以下信息:</string> + <string name="dialog_consent_accessibility_other_options">我已知晓,还有其他替代方法(使用设备管理员权限或电源按键)。</string> </resources> From 59f4a2904484c65397ff19637b865e6a1785ce75 Mon Sep 17 00:00:00 2001 From: anmoti <at@anmoti.com> Date: Thu, 13 Mar 2025 22:27:15 +0000 Subject: [PATCH 29/73] Translated using Weblate (Japanese) Currently translated at 17.6% (3 of 17 strings) Translation: jrpie-Launcher/metadata Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/metadata/ja/ --- .../android/ja-JP/full_description.txt | 22 +++++++++++++++++++ .../android/ja-JP/short_description.txt | 1 + fastlane/metadata/android/ja-JP/title.txt | 1 + 3 files changed, 24 insertions(+) create mode 100644 fastlane/metadata/android/ja-JP/full_description.txt create mode 100644 fastlane/metadata/android/ja-JP/short_description.txt create mode 100644 fastlane/metadata/android/ja-JP/title.txt diff --git a/fastlane/metadata/android/ja-JP/full_description.txt b/fastlane/metadata/android/ja-JP/full_description.txt new file mode 100644 index 0000000..7d7e6bf --- /dev/null +++ b/fastlane/metadata/android/ja-JP/full_description.txt @@ -0,0 +1,22 @@ +µLauncherは、スワイプジェスチャとタップだけでアプリを起動できるホーム画面です。 +必要最小限で、効率的で、気が散らない。 + +ホーム画面には日付、時刻、壁紙のみが表示されます。 +戻るを押すか上にスワイプすると(これは設定可能)、 +インストールされているすべてのアプリのリストが開き、効率的に検索できます。 + + +このアプリは、Finn M Glas氏のアプリ <a href="https://f-droid.org/packages/com.finnmglas.launcher/">Launcher</a> のフォークです。 + +機能: +* 35種のジェスチャーにアクションを設定できます。 +* アクションは以下のいずれかになります: + - アプリを起動 + - アプリを表示 + - お気に入りのアプリを表示 + - ボリュームを上げる/下げる + - 音楽: 次/前の曲 + - 画面をロック + - ライトの切り替え + - 通知 / クイック設定を表示 +* 仕事用プロファイルに対応しているので、Shelterなどのアプリも使えます。 diff --git a/fastlane/metadata/android/ja-JP/short_description.txt b/fastlane/metadata/android/ja-JP/short_description.txt new file mode 100644 index 0000000..58b8c41 --- /dev/null +++ b/fastlane/metadata/android/ja-JP/short_description.txt @@ -0,0 +1 @@ +気が散らない、最小限の Android ホーム画面。 diff --git a/fastlane/metadata/android/ja-JP/title.txt b/fastlane/metadata/android/ja-JP/title.txt new file mode 100644 index 0000000..4305604 --- /dev/null +++ b/fastlane/metadata/android/ja-JP/title.txt @@ -0,0 +1 @@ +µLauncher From 943867d9385cb875396654d0c128692074309f4b Mon Sep 17 00:00:00 2001 From: anmoti <at@anmoti.com> Date: Thu, 13 Mar 2025 22:46:11 +0000 Subject: [PATCH 30/73] Translated using Weblate (Japanese) Currently translated at 78.4% (200 of 255 strings) Translation: jrpie-Launcher/Launcher Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/ja/ --- app/src/main/res/values-ja/strings.xml | 202 ++++++++++++++++++++++++- 1 file changed, 201 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index a6b3dae..077bb7e 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -1,2 +1,202 @@ <?xml version="1.0" encoding="utf-8"?> -<resources></resources> \ No newline at end of file +<resources> + <string name="alert_cant_open_title">アプリを開けません</string> + <string name="alert_cant_open_message">設定を変更しますか?</string> + <string name="settings_title">設定</string> + <string name="settings_tab_app">アプリ</string> + <string name="settings_tab_launcher">ランチャー</string> + <string name="settings_tab_meta">その他</string> + <string name="toast_cant_open_message">このジェスチャのアクションを選択するには設定を開きます</string> + <string name="settings_gesture_description_up">上にスワイプ</string> + <string name="settings_gesture_description_tap_up">タップしてから上にスワイプ</string> + <string name="settings_gesture_double_up">Double Up</string> + <string name="settings_gesture_tap_up">Tap + Up</string> + <string name="settings_gesture_up">Up</string> + <string name="settings_gesture_back">Back</string> + <string name="settings_gesture_description_double_up">2本指で上にスワイプ</string> + <string name="settings_gesture_down">Down</string> + <string name="settings_gesture_description_down">下にスワイプ</string> + <string name="settings_gesture_tap_down">Tap + Down</string> + <string name="settings_gesture_description_tap_down">タップしてから下にスワイプ</string> + <string name="settings_gesture_double_down">Double Down</string> + <string name="settings_gesture_description_double_down">2本指で下にスワイプ</string> + <string name="settings_gesture_left">Left</string> + <string name="settings_gesture_description_left">左にスワイプ</string> + <string name="settings_gesture_tap_left">Tap + Left</string> + <string name="settings_gesture_description_tap_left">タップしてから左にスワイプ</string> + <string name="settings_gesture_double_left">Double Left</string> + <string name="settings_gesture_description_double_left">2本指で左にスワイプ</string> + <string name="settings_gesture_right">Right</string> + <string name="settings_gesture_description_right">右にスワイプ</string> + <string name="settings_gesture_description_tap_right">タップしてから右にスワイプ</string> + <string name="settings_gesture_double_right">Double Right</string> + <string name="settings_gesture_right_top_edge">Right (Top)</string> + <string name="settings_gesture_description_right_top_edge">画面の上部で右にスワイプ</string> + <string name="settings_gesture_right_bottom_edge">Right (Bottom)</string> + <string name="settings_gesture_description_right_bottom_edge">画面の下部で右にスワイプ</string> + <string name="settings_gesture_left_bottom_edge">Left (Bottom)</string> + <string name="settings_gesture_description_left_bottom_edge">画面の下部で左にスワイプ</string> + <string name="settings_gesture_left_top_edge">Left (Top)</string> + <string name="settings_gesture_description_left_top_edge">画面の上部で左にスワイプ</string> + <string name="settings_gesture_up_left_edge">Up (Left Edge)</string> + <string name="settings_gesture_up_right_edge">Up (Right Edge)</string> + <string name="settings_gesture_description_up_right_edge">画面の右端で上にスワイプ</string> + <string name="settings_gesture_down_left_edge">Down (Left Edge)</string> + <string name="settings_gesture_description_down_left_edge">画面の左端で下にスワイプ</string> + <string name="settings_gesture_down_right_edge">Down (Right Edge)</string> + <string name="settings_gesture_swipe_larger"><![CDATA[>]]></string> + <string name="settings_gesture_description_swipe_larger">左上 -> 右中 -> 左下</string> + <string name="settings_gesture_swipe_larger_reverse"><![CDATA[> (Reverse)]]></string> + <string name="settings_gesture_description_swipe_larger_reverse">左下 -> 右中 -> 左上</string> + <string name="settings_gesture_swipe_smaller"><![CDATA[<]]></string> + <string name="settings_gesture_description_swipe_smaller">右上 -> 左中 -> 右下</string> + <string name="settings_gesture_swipe_smaller_reverse"><![CDATA[< (Reverse)]]></string> + <string name="settings_gesture_swipe_v">V</string> + <string name="settings_gesture_description_swipe_v">左上 -> 中下 -> 右上</string> + <string name="settings_gesture_swipe_v_reverse">V (Reverse)</string> + <string name="settings_gesture_description_swipe_v_reverse">右上 -> 中下 -> 左上</string> + <string name="settings_gesture_swipe_lambda">Λ</string> + <string name="settings_gesture_description_swipe_lambda">左下 -> 中上 -> 右下</string> + <string name="settings_gesture_swipe_lambda_reverse">Λ (Reverse)</string> + <string name="settings_gesture_description_swipe_lambda_reverse">右下 -> 中上 -> 左下</string> + <string name="settings_gesture_vol_down">Volume Down</string> + <string name="settings_gesture_description_vol_down">音量ダウンボタンを押す</string> + <string name="settings_gesture_double_click">Double Click</string> + <string name="settings_gesture_description_double_click">空白部分をダブルタップ</string> + <string name="settings_gesture_long_click">Long Click</string> + <string name="settings_gesture_date">Date</string> + <string name="settings_gesture_description_date">日付をタップ</string> + <string name="settings_gesture_time">Time</string> + <string name="settings_gesture_description_time">時刻をタップ</string> + <string name="settings_apps_choose">アプリを選択</string> + <string name="settings_launcher_section_appearance">外観</string> + <string name="settings_theme_color_theme">カラーテーマ</string> + <string name="settings_theme_color_theme_item_default">デフォルト</string> + <string name="settings_theme_color_theme_item_dark">ダーク</string> + <string name="settings_theme_color_theme_item_dynamic">ダイナミック</string> + <string name="settings_theme_text_shadow">文字の影</string> + <string name="settings_theme_background_item_transparent">透明</string> + <string name="settings_theme_background_item_blur">ブラー</string> + <string name="settings_theme_background_item_solid">ソリッド</string> + <string name="settings_theme_font">フォント</string> + <string name="settings_theme_font_item_system_default">システムデフォルト</string> + <string name="settings_theme_monochrome_icons">モノクロのアプリアイコン</string> + <string name="settings_launcher_section_date_time"><![CDATA[Date & time]]></string> + <string name="settings_clock_color">色</string> + <string name="settings_clock_time_visible">時刻を表示</string> + <string name="settings_clock_date_visible">日付を表示</string> + <string name="settings_clock_localized">ローカライズされた日付形式を使用する</string> + <string name="settings_clock_show_seconds">秒を表示</string> + <string name="settings_clock_flip_date_time">日付と時刻を反転</string> + <string name="settings_theme_wallpaper">壁紙を選択</string> + <string name="settings_launcher_change_wallpaper">壁紙を変更</string> + <string name="settings_launcher_section_display">表示</string> + <string name="settings_display_screen_timeout_disabled">画面オンを維持</string> + <string name="settings_display_full_screen">フルスクリーンを仕様</string> + <string name="settings_display_rotate_screen">画面の回転</string> + <string name="settings_enabled_gestures_double_swipe_summary">2本指でスワイプ</string> + <string name="settings_enabled_gestures_edge_swipe">Edgeスワイプアクション</string> + <string name="settings_enabled_gestures_edge_swipe_summary">画面端でスワイプ</string> + <string name="settings_functionality_search_web_summary">アプリリストで検索中にリターンキーを押すとWeb検索が起動します。</string> + <string name="settings_functionality_search_web">Webで検索</string> + <string name="settings_functionality_auto_keyboard">検索時にキーボードを表示</string> + <string name="settings_launcher_section_apps">アプリ</string> + <string name="settings_apps_hide_bound_apps">ジェスチャーに設定されたアプリをアプリ一覧に表示しない</string> + <string name="settings_apps_hide_paused_apps">一時停止されたアプリを隠す</string> + <string name="settings_list_layout">アプリ一覧のレイアウト</string> + <string name="settings_list_reverse_layout">アプリ一覧を反転</string> + <string name="settings_list_layout_item_default">デフォルト</string> + <string name="settings_list_layout_item_text">テキスト</string> + <string name="settings_list_layout_item_grid">グリッド</string> + <string name="settings_meta_show_tutorial">ランチャーのチュートリアルを見る</string> + <string name="settings_meta_reset">設定をリセット</string> + <string name="settings_meta_reset_confirm">すべての設定を破棄します。続行しますか?</string> + <string name="settings_meta_view_code">ソースコードを見る</string> + <string name="dialog_report_bug_title">バグを報告</string> + <string name="dialog_report_bug_button_clipboard">クリップボードにコピー</string> + <string name="dialog_report_bug_security_info">セキュリティ上の脆弱性をGitHubに公開しないでください。代わりに以下を使用してください。</string> + <string name="dialog_report_bug_button_security">セキュリティ上の脆弱性を報告</string> + <string name="dialog_report_bug_create_report">レポートを作成</string> + <string name="settings_meta_join_chat">µLauncherのチャットに入る</string> + <string name="settings_meta_privacy">プライバシーポリシー</string> + <string name="settings_meta_discord">Discordに参加してください!</string> + <string name="list_title_hidden">非表示のアプリ</string> + <string name="list_title_private_space">プライベートスペース</string> + <string name="list_title_pick">アプリを選択</string> + <string name="list_tab_app">アプリ</string> + <string name="list_tab_other">その他</string> + <string name="list_app_delete">アンインストール</string> + <string name="list_app_info">アプリ情報</string> + <string name="list_app_favorite_remove">お気に入りから削除</string> + <string name="list_app_hidden_add">隠す</string> + <string name="list_app_rename">名称を変更</string> + <string name="list_not_removed">アプリを削除できませんでした</string> + <string name="list_apps_search_hint">検索</string> + <string name="list_apps_search_hint_no_auto_launch">検索(自動起動なし)</string> + <string name="list_other_settings">µLauncherの設定</string> + <string name="list_other_list">すべてのアプリ</string> + <string name="list_other_toggle_private_space_lock">プライベートスペースのロックを切り替え</string> + <string name="list_other_volume_up">音楽: うるさい</string> + <string name="list_other_volume_down">音楽: ひっそり</string> + <string name="list_other_track_next">音楽: 次</string> + <string name="list_other_track_previous">音楽: 前</string> + <string name="list_other_expand_notifications_panel">通知パネルを表示</string> + <string name="list_other_nop">なにもしねぇ</string> + <string name="list_other_lock_screen">画面をロック</string> + <string name="list_other_torch">ライトを切り替え</string> + <string name="pin_shortcut_title">ショートカットを追加</string> + <string name="pin_shortcut_button_bind">ジェシュチャーに設定</string> + <string name="pin_shortcut_button_ok">Ok</string> + <string name="pin_shortcut_switch_visible">アプリ一覧に表示</string> + <string name="tutorial_title">チュートリアル</string> + <string name="tutorial_concept_title">コンセプト</string> + <string name="tutorial_usage_title">使い方</string> + <string name="tutorial_usage_text">ホーム画面には現地の日付と時刻が表示されます。邪魔されることはありません。</string> + <string name="tutorial_usage_text_2">1回のスワイプまたはボタンのタップでアプリを起動できます。次のスライドでいくつか選択してください。</string> + <string name="tutorial_setup_title">セットアップ</string> + <string name="tutorial_setup_text_2">選択内容は後で変更することもできます。</string> + <string name="tutorial_finish_title">さあ行きましょう!</string> + <string name="tutorial_finish_button">始める</string> + <string name="settings">設定</string> + <string name="settings_gesture_description_back">戻るボタン / 戻るジェスチャ</string> + <string name="settings_theme_color_theme_item_light">ライト</string> + <string name="settings_enabled_gestures_double_swipe">Doubleスワイプアクション</string> + <string name="settings_functionality_auto_launch">検索結果を起動</string> + <string name="list_title_favorite">お気に入りのアプリ</string> + <string name="settings_gesture_description_vol_up">音量アップボタンを押す</string> + <string name="settings_gesture_description_long_click">空白部分をロングタップ</string> + <string name="settings_launcher_section_functionality">機能性</string> + <string name="dialog_report_bug_info">µLauncherの改善にご協力いただきありがとうございます。\nバグレポートに次の情報を追加することを検討してください。</string> + <string name="list_app_favorite_add">お気に入りに追加</string> + <string name="settings_gesture_description_up_left_edge">画面の左端で上にスワイプ</string> + <string name="settings_gesture_description_down_right_edge">画面の右端で下にスワイプ</string> + <string name="settings_apps_install">アプリをインストール</string> + <string name="list_removed">選択されたアプリを削除しました</string> + <string name="tutorial_finish_text">始める準備はできました!これがあなたにとって大きな価値となることを願っています! \t- Finn(Launcherの作成者)とJosia(いくつかの改良を行い、フォーク μLauncher を保守)</string> + <string name="settings_gesture_tap_right">Tap + Right</string> + <string name="settings_gesture_description_double_right">2本指で右にスワイプ</string> + <string name="settings_apps_hidden">非表示のアプリ</string> + <string name="settings_general_choose_home_screen">μLauncherホーム画面に設定</string> + <string name="settings_meta_fork_contact">フォークの開発者に問い合わせ</string> + <string name="settings_meta_contact">オリジナルの開発者に問い合わせる</string> + <string name="list_other_list_favorites">お気に入りのアプリ</string> + <string name="list_other_track_play_pause">音楽: 再生 / 一時停止</string> + <string name="settings_theme_background_item_dim">薄暗い</string> + <string name="settings_launcher_sensitivity">感度</string> + <string name="settings_meta_cant_select_launcher">アプリ情報</string> + <string name="settings_gesture_vol_up">Volume Up</string> + <string name="list_title_view">すべてのアプリ</string> + <string name="list_app_hidden_remove">表示</string> + <string name="settings_gesture_description_swipe_smaller_reverse">右下 -> 左中 -> 右上</string> + <string name="settings_theme_background">背景(アプリ一覧と設定)</string> + <string name="settings_enabled_gestures_edge_swipe_edge_width">端の幅</string> + <string name="settings_functionality_auto_launch_summary">この機能を一時的に無効にするにはスペースキーを押します。</string> + <string name="list_other_list_private_space">プライベートスペース</string> + <string name="settings_apps_hide_private_space_apps">アプリ一覧からプライベートスペースを隠す</string> + <string name="settings_meta_cant_select_launcher_msg">この機能はあなたのデバイスでは動作しません。代わりにアプリケーションの詳細を管理しますか?</string> + <string name="settings_meta_report_bug">バグを報告</string> + <string name="tutorial_start_text">このランチャーの使い方を学ぶのにほんの数秒しかかかりません</string> + <string name="tutorial_concept_text">Launcherは、最小限かつ効率的で、邪魔にならないように設計されています。支払い、広告、追跡サービスは一切ありません。</string> + <string name="tutorial_concept_text_2">このアプリはオープンソース(MIT ライセンス)であり、GitHub で入手できます!リポジトリを必ずチェックしてください!</string> + <string name="tutorial_setup_text">デフォルトのアプリをいくつか選択しました。必要に応じて今すぐ変更できます。</string> +</resources> From ff108ee32354877f490e449c81162e62f1f13e3f Mon Sep 17 00:00:00 2001 From: toolatebot <toolate@othing.xyz> Date: Fri, 14 Mar 2025 00:07:18 +0000 Subject: [PATCH 31/73] Update translation files Updated by "Cleanup translation files" add-on in Weblate. Translation: jrpie-Launcher/Launcher Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/ --- app/src/main/res/values-de/strings.xml | 1 - app/src/main/res/values-es/strings.xml | 3 +-- app/src/main/res/values-fr/strings.xml | 3 +-- app/src/main/res/values-it/strings.xml | 3 +-- app/src/main/res/values-ja/strings.xml | 1 - app/src/main/res/values-pt-rBR/strings.xml | 1 - app/src/main/res/values-tr/strings.xml | 3 +-- app/src/main/res/values-zh-rCN/strings.xml | 1 - 8 files changed, 4 insertions(+), 12 deletions(-) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 349d730..b4bf65f 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -97,7 +97,6 @@ <string name="settings_launcher_change_wallpaper">Hintergrund ändern</string> <string name="settings_launcher_section_display">Bildschirm</string> <string name="settings_display_screen_timeout_disabled">Bildschirm nicht ausschalten</string> - <string name="settings_display_full_screen">Vollbild</string> <string name="settings_display_rotate_screen">Bildschirm drehen</string> <string name="settings_launcher_section_functionality">Funktionalität</string> <string name="settings_enabled_gestures_double_swipe">Doppelte Wischaktionen</string> diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index f0a80c6..df4a50a 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -63,7 +63,6 @@ <string name="settings_launcher_change_wallpaper">Cambiar fondo de pantalla</string> <string name="settings_launcher_section_display">Pantalla</string> <string name="settings_display_screen_timeout_disabled">Mantener encendida</string> - <string name="settings_display_full_screen">Pantalla completa</string> <string name="settings_launcher_section_functionality">Funciones</string> <string name="settings_enabled_gestures_double_swipe">Deslizar con dos dedos</string> <string name="settings_functionality_auto_launch">Auto-lanzar búsquedas</string> @@ -127,4 +126,4 @@ <string name="tutorial_finish_button">Iniciar</string> <string name="settings">Configuración</string> <string name="ic_menu_alt">Más opciones</string> -</resources> \ No newline at end of file +</resources> diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 388e089..86accb2 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -55,7 +55,6 @@ <string name="settings_launcher_change_wallpaper">Changer le fond d\'écran</string> <string name="settings_launcher_section_display">Écran</string> <string name="settings_display_screen_timeout_disabled">Garder l\'écran allumé</string> - <string name="settings_display_full_screen">Utiliser le plein écran</string> <string name="settings_launcher_section_functionality">Fonctions</string> <string name="settings_enabled_gestures_double_swipe">Actions de double balayage</string> <string name="settings_functionality_auto_launch">Lancer apps par recherche</string> @@ -231,4 +230,4 @@ <string name="settings_gesture_description_down_left_edge">Balayer vers le bas au bord gauche de l\'écran</string> <string name="settings_enabled_gestures_edge_swipe_summary">Balayer au bord de l\'écran</string> <string name="settings_clock_color">Couleur</string> -</resources> \ No newline at end of file +</resources> diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 320bfc6..fe30410 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -115,7 +115,6 @@ <string name="settings_launcher_change_wallpaper">Cambia immagine di sfondo</string> <string name="settings_launcher_section_display">Schermo</string> <string name="settings_display_screen_timeout_disabled">Mantieni lo schermo acceso</string> - <string name="settings_display_full_screen">Schermo intero</string> <string name="settings_display_rotate_screen">Ruota lo schermo</string> <string name="settings_launcher_section_functionality">Funzionalità</string> <string name="settings_functionality_auto_keyboard">Apri automaticamente la tastiera per cercare</string> @@ -237,4 +236,4 @@ <string name="toast_activity_not_found_browser">Impossibile aprire l\'URL: nessun browser trovato.</string> <string name="toast_activity_not_found_search_web">Non è stata trovata un\'applicazione per gestire la ricerca.</string> <string name="dialog_consent_accessibility_text"><![CDATA[Stai per arrivare il servizio di accessibilità. Questo garantirà <strong>privilegi più ampi</strong> a µLauncher.<br/>µLauncher utilizzerà questi privilegi <strong>solo per bloccare lo schermo</strong>. µLauncher <strong>non raccoglierà mai alcun dato</strong>. In particolare, µLauncher non usa il servizio di accessibilità per raccogliere nessun dato.]]></string> -</resources> \ No newline at end of file +</resources> diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 077bb7e..6cc844d 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -92,7 +92,6 @@ <string name="settings_launcher_change_wallpaper">壁紙を変更</string> <string name="settings_launcher_section_display">表示</string> <string name="settings_display_screen_timeout_disabled">画面オンを維持</string> - <string name="settings_display_full_screen">フルスクリーンを仕様</string> <string name="settings_display_rotate_screen">画面の回転</string> <string name="settings_enabled_gestures_double_swipe_summary">2本指でスワイプ</string> <string name="settings_enabled_gestures_edge_swipe">Edgeスワイプアクション</string> diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 6a6149c..857e454 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -66,7 +66,6 @@ <string name="settings_launcher_change_wallpaper">Alterar papel de parede</string> <string name="settings_launcher_section_display">Exibição</string> <string name="settings_display_screen_timeout_disabled">Manter a tela ligada</string> - <string name="settings_display_full_screen">Usar tela cheia</string> <string name="settings_launcher_section_functionality">Funcionalidades</string> <string name="settings_enabled_gestures_double_swipe">Gestos com 2 dedos</string> <string name="settings_enabled_gestures_edge_swipe">Ações de deslize nas bordas</string> diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index bfd0cfe..0c22e97 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -137,7 +137,6 @@ <string name="settings_launcher_change_wallpaper">Duvar kağıdını değiştir</string> <string name="settings_launcher_section_display">Ekran</string> <string name="settings_display_screen_timeout_disabled">Ekranı açık tut</string> - <string name="settings_display_full_screen">Tam ekran kullan</string> <string name="settings_display_rotate_screen">Ekranı döndür</string> <string name="settings_launcher_section_functionality">İşlevsellik</string> <string name="settings_enabled_gestures_edge_swipe_summary">Ekranın köşesinden kaydırın</string> @@ -209,4 +208,4 @@ <string name="dialog_select_color_ok">OK</string> <string name="dialog_select_color_color_hex">Renk</string> <string name="dialog_choose_color_title">Renk seçin</string> -</resources> \ No newline at end of file +</resources> diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 72acf81..c445a75 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -44,7 +44,6 @@ <string name="settings_theme_wallpaper">选择一个壁纸</string> <string name="settings_launcher_change_wallpaper">换壁纸</string> <string name="settings_display_screen_timeout_disabled">保持屏幕常亮</string> - <string name="settings_display_full_screen">使用全屏</string> <string name="settings_launcher_section_functionality">功能</string> <string name="settings_enabled_gestures_edge_swipe">边缘滑动动作</string> <string name="settings_functionality_auto_launch">直接启动匹配搜索内容的应用</string> From 232046e9867c824da3be01f3cf520fcd6ab506c9 Mon Sep 17 00:00:00 2001 From: toolatebot <toolate@othing.xyz> Date: Sat, 15 Mar 2025 00:07:18 +0000 Subject: [PATCH 32/73] Update translation files Updated by "Cleanup translation files" add-on in Weblate. Translation: jrpie-Launcher/Launcher Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/ --- app/src/main/res/values-de/strings.xml | 1 - app/src/main/res/values-es/strings.xml | 1 - app/src/main/res/values-fr/strings.xml | 1 - app/src/main/res/values-it/strings.xml | 1 - app/src/main/res/values-ja/strings.xml | 1 - app/src/main/res/values-pt-rBR/strings.xml | 1 - app/src/main/res/values-tr/strings.xml | 1 - app/src/main/res/values-zh-rCN/strings.xml | 1 - 8 files changed, 8 deletions(-) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index b4bf65f..e9f35b6 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -117,7 +117,6 @@ <string name="settings_list_layout_item_grid">Raster</string> <string name="settings_general_choose_home_screen">Launcher wählen</string> <string name="settings_meta_cant_select_launcher">App Info</string> - <string name="settings_meta_cant_select_launcher_msg">Das Gerät unterstützt diese Funktion nicht. Stattdessen die App Details bearbeiten?</string> <string name="settings_meta_show_tutorial">Zum Tutorial</string> <string name="settings_meta_reset">Einstellungen zurücksetzen</string> <string name="settings_meta_reset_confirm">Alle Einstellungen gehen verloren. Weitermachen?</string> diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index df4a50a..742c880 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -75,7 +75,6 @@ --> <string name="settings_general_choose_home_screen">Seleccionar Launcher</string> <string name="settings_meta_cant_select_launcher">Información de la aplicación</string> - <string name="settings_meta_cant_select_launcher_msg">Su dispositivo no posee esta caracrerística. Desea cambiar los detalles de la aplicación?</string> <string name="settings_meta_show_tutorial">Ver tutorial de Launcher</string> <string name="settings_meta_reset">Configuración por defecto</string> <string name="settings_meta_reset_confirm">Todas sus preferencias se eliminarán. Desea continuar?</string> diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 86accb2..5bfb096 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -67,7 +67,6 @@ --> <string name="settings_general_choose_home_screen">Choisir μLauncher comme application d\'écran d\'accueil par défaut</string> <string name="settings_meta_cant_select_launcher">Informations sur l\'application</string> - <string name="settings_meta_cant_select_launcher_msg">Votre appareil ne prend pas en charge cette fonctionnalité. Souhaitez-vous plutôt accéder aux détails de l\'application ?</string> <string name="settings_meta_show_tutorial">Regarder le tutoriel</string> <string name="settings_meta_reset">Réinitialiser</string> <string name="settings_meta_reset_confirm">Vous allez réinitialiser tous vos paramètres. Souhaitez-vous poursuivre ?</string> diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index fe30410..28a7133 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -34,7 +34,6 @@ <br/><br/><br/><br/> Puoi cambiare le tue scelte in seguito nelle impostazioni. ]]></string> - <string name="settings_meta_cant_select_launcher_msg">Il tuo dispositivo non supporta questa funzione. Vuoi aprire la pagina di dettaglio dell\'applicazione?</string> <string name="alert_cant_open_title">Impossibile aprire l\'applicazione</string> <string name="alert_cant_open_message">Desideri modificare le impostazioni?</string> <string name="toast_cant_open_message">Apri le impostazioni per abbinare un\'azione a questo gesto</string> diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 6cc844d..c453380 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -192,7 +192,6 @@ <string name="settings_functionality_auto_launch_summary">この機能を一時的に無効にするにはスペースキーを押します。</string> <string name="list_other_list_private_space">プライベートスペース</string> <string name="settings_apps_hide_private_space_apps">アプリ一覧からプライベートスペースを隠す</string> - <string name="settings_meta_cant_select_launcher_msg">この機能はあなたのデバイスでは動作しません。代わりにアプリケーションの詳細を管理しますか?</string> <string name="settings_meta_report_bug">バグを報告</string> <string name="tutorial_start_text">このランチャーの使い方を学ぶのにほんの数秒しかかかりません</string> <string name="tutorial_concept_text">Launcherは、最小限かつ効率的で、邪魔にならないように設計されています。支払い、広告、追跡サービスは一切ありません。</string> diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 857e454..3a0734f 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -79,7 +79,6 @@ --> <string name="settings_general_choose_home_screen">Definir o μLauncher como tela inicial</string> <string name="settings_meta_cant_select_launcher">Informações do aplicativo</string> - <string name="settings_meta_cant_select_launcher_msg">Seu dispositivo não é compatível com esse recurso. Gerenciar detalhes do app em vez disso?</string> <string name="settings_meta_show_tutorial">Ver tutorial do launcher</string> <string name="settings_meta_reset">Redefinir configuraçãos</string> <string name="settings_meta_reset_confirm">Você vai descartar todas as suas preferências. Continuar?</string> diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 0c22e97..a283fa9 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -164,7 +164,6 @@ <string name="settings_list_layout_item_text">Metin</string> <string name="settings_list_layout_item_grid">Izgara</string> <string name="settings_meta_cant_select_launcher">Uygulama Detayı</string> - <string name="settings_meta_cant_select_launcher_msg">Sizin cihazınız bu özelliği desteklemiyor. Onun yerine uygulama detaylarını düzenleyin?</string> <string name="settings_meta_reset">Ayarları Sıfırlayın</string> <string name="settings_meta_reset_confirm">Tüm tercihlerinizi bir kenara bırakacaksınız. Devam mı?</string> <string name="settings_theme_font_item_monospace">Tek uzay</string> diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index c445a75..08bc5b7 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -50,7 +50,6 @@ <string name="settings_functionality_auto_keyboard">搜索时呼出键盘</string> <string name="settings_launcher_sensitivity">灵敏度</string> <string name="settings_meta_cant_select_launcher">应用信息</string> - <string name="settings_meta_cant_select_launcher_msg">您的设备不支持此功能。要不打开应用程序详细?</string> <string name="settings_meta_show_tutorial">查看启动器教程</string> <string name="settings_meta_reset">重置设置</string> <string name="settings_meta_reset_confirm">你将放弃你所有的配置。继续吗?</string> From 47940811b4d8c6aece6ed8073044fd3c85db1db0 Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Sun, 16 Mar 2025 02:30:49 +0100 Subject: [PATCH 33/73] fix #126 --- .../jrpie/android/launcher/ui/HomeActivity.kt | 13 ++++ .../launcher/ui/TouchGestureDetector.kt | 65 +++++++++++++++---- 2 files changed, 67 insertions(+), 11 deletions(-) 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 7875473..14e04d5 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 @@ -69,10 +69,23 @@ class HomeActivity : UIObject, AppCompatActivity() { LauncherPreferences.enabled_gestures().edgeSwipeEdgeWidth() / 100f ) + + // Initialise layout binding = HomeBinding.inflate(layoutInflater) + setContentView(binding.root) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + binding.root.setOnApplyWindowInsetsListener { _, windowInsets -> + val insets = windowInsets.systemGestureInsets + touchGestureDetector.setSystemGestureInsets(insets) + + windowInsets + } + } + + // Handle back key / gesture on Android 13+, cf. onKeyDown() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/TouchGestureDetector.kt b/app/src/main/java/de/jrpie/android/launcher/ui/TouchGestureDetector.kt index 74b8351..9000fa8 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/TouchGestureDetector.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/TouchGestureDetector.kt @@ -1,10 +1,13 @@ package de.jrpie.android.launcher.ui import android.content.Context +import android.graphics.Insets +import android.os.Build import android.os.Handler import android.os.Looper import android.view.MotionEvent import android.view.ViewConfiguration +import androidx.annotation.RequiresApi import de.jrpie.android.launcher.actions.Gesture import de.jrpie.android.launcher.preferences.LauncherPreferences import kotlin.math.abs @@ -31,20 +34,29 @@ class TouchGestureDetector( private val longPressHandler = Handler(Looper.getMainLooper()) + private var systemGestureInsetTop = 100 + private var systemGestureInsetBottom = 0 + private var systemGestureInsetLeft = 0 + private var systemGestureInsetRight = 0 + data class Vector(val x: Float, val y: Float) { fun absSquared(): Float { return this.x * this.x + this.y * this.y } + fun plus(vector: Vector): Vector { return Vector(this.x + vector.x, this.y + vector.y) } + fun max(other: Vector): Vector { return Vector(max(this.x, other.x), max(this.y, other.y)) } + fun min(other: Vector): Vector { return Vector(min(this.x, other.x), min(this.y, other.y)) } + operator fun minus(vector: Vector): Vector { return Vector(this.x - vector.x, this.y - vector.y) } @@ -61,16 +73,35 @@ class TouchGestureDetector( fun sizeSquared(): Float { return (max - min).absSquared() } + fun getDirection(): Vector { return last - start } + fun update(vector: Vector) { min = min.min(vector) max = max.max(vector) last = vector } } + + private fun PointerPath.startIntersectsSystemGestureInsets(): Boolean { + // ignore x, since this makes edge swipes very hard to execute + return start.y < systemGestureInsetTop + || start.y > height - systemGestureInsetBottom + } + + private fun PointerPath.intersectsSystemGestureInsets(): Boolean { + return min.x < systemGestureInsetLeft + || min.y < systemGestureInsetTop + || max.x > width - systemGestureInsetRight + || max.y > height - systemGestureInsetBottom + } + private fun PointerPath.isTap(): Boolean { + if (intersectsSystemGestureInsets()) { + return false + } return sizeSquared() < TOUCH_SLOP_SQUARE } @@ -128,8 +159,8 @@ class TouchGestureDetector( } // add new pointers - for(i in 0..<event.pointerCount){ - if(paths.containsKey(event.getPointerId(i))) { + for (i in 0..<event.pointerCount) { + if (paths.containsKey(event.getPointerId(i))) { continue } val index = pointerIdToIndex[i] ?: continue @@ -192,9 +223,8 @@ class TouchGestureDetector( val mainPointerPath = paths.entries.firstOrNull { it.value.number == 0 }?.value ?: return - // Ignore swipes at the very top, since this interferes with the status bar. - // TODO: replace 100px by sensible dp value (e.g. twice the height of the status bar) - if (paths.entries.any { it.value.start.y < 100 }) { + // Ignore swipes starting at the very top and the very bottom + if (paths.entries.any { it.value.startIntersectsSystemGestureInsets() }) { return } @@ -204,7 +234,8 @@ class TouchGestureDetector( if (duration in 0..TAP_TIMEOUT) { if (timeStart - lastTappedTime < DOUBLE_TAP_TIMEOUT && lastTappedLocation?.let { - (mainPointerPath.last - it).absSquared() < DOUBLE_TAP_SLOP_SQUARE} == true + (mainPointerPath.last - it).absSquared() < DOUBLE_TAP_SLOP_SQUARE + } == true ) { Gesture.DOUBLE_CLICK.invoke(context) } else { @@ -233,34 +264,38 @@ class TouchGestureDetector( val startEndMax = mainPointerPath.start.max(mainPointerPath.last) when (gesture) { Gesture.SWIPE_DOWN -> { - if(startEndMax.x + MIN_TRIANGLE_HEIGHT < mainPointerPath.max.x) { + if (startEndMax.x + MIN_TRIANGLE_HEIGHT < mainPointerPath.max.x) { gesture = Gesture.SWIPE_LARGER } else if (startEndMin.x - MIN_TRIANGLE_HEIGHT > mainPointerPath.min.x) { gesture = Gesture.SWIPE_SMALLER } } + Gesture.SWIPE_UP -> { - if(startEndMax.x + MIN_TRIANGLE_HEIGHT < mainPointerPath.max.x) { + if (startEndMax.x + MIN_TRIANGLE_HEIGHT < mainPointerPath.max.x) { gesture = Gesture.SWIPE_LARGER_REVERSE } else if (startEndMin.x - MIN_TRIANGLE_HEIGHT > mainPointerPath.min.x) { gesture = Gesture.SWIPE_SMALLER_REVERSE } } + Gesture.SWIPE_RIGHT -> { - if(startEndMax.y + MIN_TRIANGLE_HEIGHT < mainPointerPath.max.y) { + if (startEndMax.y + MIN_TRIANGLE_HEIGHT < mainPointerPath.max.y) { gesture = Gesture.SWIPE_V } else if (startEndMin.y - MIN_TRIANGLE_HEIGHT > mainPointerPath.min.y) { gesture = Gesture.SWIPE_LAMBDA } } + Gesture.SWIPE_LEFT -> { - if(startEndMax.y + MIN_TRIANGLE_HEIGHT < mainPointerPath.max.y) { + if (startEndMax.y + MIN_TRIANGLE_HEIGHT < mainPointerPath.max.y) { gesture = Gesture.SWIPE_V_REVERSE } else if (startEndMin.y - MIN_TRIANGLE_HEIGHT > mainPointerPath.min.y) { gesture = Gesture.SWIPE_LAMBDA_REVERSE } } - else -> { } + + else -> {} } if (edgeActions) { @@ -283,4 +318,12 @@ class TouchGestureDetector( gesture?.invoke(context) } } + + @RequiresApi(Build.VERSION_CODES.Q) + fun setSystemGestureInsets(insets: Insets) { + systemGestureInsetTop = insets.top + systemGestureInsetBottom = insets.bottom + systemGestureInsetLeft = insets.left + systemGestureInsetRight = insets.right + } } \ No newline at end of file From 90434617e72f50bebee7c912d087a442618a450b Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Sun, 16 Mar 2025 04:12:34 +0100 Subject: [PATCH 34/73] replace (ViewPager, FragmentPagerAdapter) by (ViewPager2, FragmentStateAdapter) --- .../android/launcher/ui/list/ListActivity.kt | 29 +++++------ .../launcher/ui/settings/SettingsActivity.kt | 48 +++++++++---------- app/src/main/res/layout/list.xml | 2 +- app/src/main/res/layout/settings.xml | 2 +- 4 files changed, 40 insertions(+), 41 deletions(-) diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/list/ListActivity.kt b/app/src/main/java/de/jrpie/android/launcher/ui/list/ListActivity.kt index 64bd850..997d2b0 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/list/ListActivity.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/list/ListActivity.kt @@ -12,10 +12,8 @@ import android.window.OnBackInvokedDispatcher import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.content.res.AppCompatResources import androidx.fragment.app.Fragment -import androidx.fragment.app.FragmentManager -import androidx.fragment.app.FragmentPagerAdapter -import androidx.viewpager.widget.ViewPager -import com.google.android.material.tabs.TabLayout +import androidx.viewpager2.adapter.FragmentStateAdapter +import com.google.android.material.tabs.TabLayoutMediator import de.jrpie.android.launcher.Application import de.jrpie.android.launcher.R import de.jrpie.android.launcher.REQUEST_UNINSTALL @@ -241,11 +239,14 @@ class ListActivity : AppCompatActivity(), UIObject { updateTitle() - val sectionsPagerAdapter = ListSectionsPagerAdapter(this, supportFragmentManager) - val viewPager: ViewPager = findViewById(R.id.list_viewpager) - viewPager.adapter = sectionsPagerAdapter - val tabs: TabLayout = findViewById(R.id.list_tabs) - tabs.setupWithViewPager(viewPager) + val sectionsPagerAdapter = ListSectionsPagerAdapter(this) + binding.listViewpager.apply { + adapter = sectionsPagerAdapter + currentItem = 0 + } + TabLayoutMediator(binding.listTabs, binding.listViewpager) { tab, position -> + tab.text = sectionsPagerAdapter.getPageTitle(position) + }.attach() } } @@ -258,10 +259,10 @@ private val TAB_TITLES = arrayOf( * The [ListSectionsPagerAdapter] returns the fragment, * which corresponds to the selected tab in [ListActivity]. */ -class ListSectionsPagerAdapter(private val activity: ListActivity, fm: FragmentManager) : - FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { +class ListSectionsPagerAdapter(private val activity: ListActivity) : + FragmentStateAdapter(activity) { - override fun getItem(position: Int): Fragment { + override fun createFragment(position: Int): Fragment { return when (position) { 0 -> ListFragmentApps() 1 -> ListFragmentOther() @@ -269,11 +270,11 @@ class ListSectionsPagerAdapter(private val activity: ListActivity, fm: FragmentM } } - override fun getPageTitle(position: Int): CharSequence { + fun getPageTitle(position: Int): CharSequence { return activity.resources.getString(TAB_TITLES[position]) } - override fun getCount(): Int { + override fun getItemCount(): Int { return when (activity.intention) { ListActivity.ListActivityIntention.VIEW -> 1 else -> 2 diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/settings/SettingsActivity.kt b/app/src/main/java/de/jrpie/android/launcher/ui/settings/SettingsActivity.kt index fde61a7..2b3cdc6 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/settings/SettingsActivity.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/settings/SettingsActivity.kt @@ -1,6 +1,5 @@ package de.jrpie.android.launcher.ui.settings -import android.content.Context import android.content.Intent import android.content.SharedPreferences import android.content.res.Resources @@ -8,10 +7,9 @@ import android.os.Bundle import android.provider.Settings import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment -import androidx.fragment.app.FragmentManager -import androidx.fragment.app.FragmentPagerAdapter -import androidx.viewpager.widget.ViewPager -import com.google.android.material.tabs.TabLayout +import androidx.fragment.app.FragmentActivity +import androidx.viewpager2.adapter.FragmentStateAdapter +import com.google.android.material.tabs.TabLayoutMediator import de.jrpie.android.launcher.R import de.jrpie.android.launcher.REQUEST_CHOOSE_APP import de.jrpie.android.launcher.databinding.SettingsBinding @@ -34,6 +32,7 @@ import de.jrpie.android.launcher.ui.settings.meta.SettingsFragmentMeta * Settings are closed automatically if the activity goes `onPause` unexpectedly. */ class SettingsActivity : AppCompatActivity(), UIObject { + private val EXTRA_TAB = "tab" private val solidBackground = LauncherPreferences.theme().background() == Background.SOLID || LauncherPreferences.theme().colorTheme() == ColorTheme.LIGHT @@ -49,15 +48,15 @@ class SettingsActivity : AppCompatActivity(), UIObject { // This ugly workaround causes a jump to the top of the list, but at least // the text stays readable. val i = Intent(this, SettingsActivity::class.java) - .also { it.putExtra("tab", 1) } + .also { it.putExtra(EXTRA_TAB, 1) } finish() startActivity(i) } else - if (prefKey?.startsWith("theme.") == true || - prefKey?.startsWith("display.") == true - ) { - recreate() - } + if (prefKey?.startsWith("theme.") == true || + prefKey?.startsWith("display.") == true + ) { + recreate() + } } private lateinit var binding: SettingsBinding @@ -71,15 +70,14 @@ class SettingsActivity : AppCompatActivity(), UIObject { setContentView(binding.root) // set up tabs and swiping in settings - val sectionsPagerAdapter = SettingsSectionsPagerAdapter(this, supportFragmentManager) - val viewPager: ViewPager = findViewById(R.id.settings_viewpager) - viewPager.adapter = sectionsPagerAdapter - - val tabs: TabLayout = findViewById(R.id.settings_tabs) - tabs.setupWithViewPager(viewPager) - if (intent.hasExtra("tab")) { - tabs.getTabAt(intent.getIntExtra("tab", 0))?.select() + val sectionsPagerAdapter = SettingsSectionsPagerAdapter(this) + binding.settingsViewpager.apply { + adapter = sectionsPagerAdapter + setCurrentItem(intent.getIntExtra(EXTRA_TAB, 0), false) } + TabLayoutMediator(binding.settingsTabs, binding.settingsViewpager) { tab, position -> + tab.text = sectionsPagerAdapter.getPageTitle(position) + }.attach() } override fun onStart() { @@ -122,10 +120,10 @@ private val TAB_TITLES = arrayOf( R.string.settings_tab_meta ) -class SettingsSectionsPagerAdapter(private val context: Context, fm: FragmentManager) : - FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { +class SettingsSectionsPagerAdapter(private val activity: FragmentActivity) : + FragmentStateAdapter(activity) { - override fun getItem(position: Int): Fragment { + override fun createFragment(position: Int): Fragment { return when (position) { 0 -> SettingsFragmentActions() 1 -> SettingsFragmentLauncher() @@ -134,11 +132,11 @@ class SettingsSectionsPagerAdapter(private val context: Context, fm: FragmentMan } } - override fun getPageTitle(position: Int): CharSequence { - return context.resources.getString(TAB_TITLES[position]) + fun getPageTitle(position: Int): CharSequence { + return activity.resources.getString(TAB_TITLES[position]) } - override fun getCount(): Int { + override fun getItemCount(): Int { return 3 } } diff --git a/app/src/main/res/layout/list.xml b/app/src/main/res/layout/list.xml index 43c1f4c..45bcb85 100644 --- a/app/src/main/res/layout/list.xml +++ b/app/src/main/res/layout/list.xml @@ -95,7 +95,7 @@ </com.google.android.material.appbar.AppBarLayout> - <androidx.viewpager.widget.ViewPager + <androidx.viewpager2.widget.ViewPager2 android:id="@+id/list_viewpager" android:layout_width="0dp" android:layout_height="0dp" diff --git a/app/src/main/res/layout/settings.xml b/app/src/main/res/layout/settings.xml index f07402c..987e293 100644 --- a/app/src/main/res/layout/settings.xml +++ b/app/src/main/res/layout/settings.xml @@ -73,7 +73,7 @@ </com.google.android.material.appbar.AppBarLayout> - <androidx.viewpager.widget.ViewPager + <androidx.viewpager2.widget.ViewPager2 android:id="@+id/settings_viewpager" android:layout_width="match_parent" android:layout_height="match_parent" From da115bb2d980aef599917f0558c8f1b49a646a29 Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Sun, 16 Mar 2025 16:37:39 +0100 Subject: [PATCH 35/73] refactor: remove unused stuff, fix lint warnings --- app/build.gradle | 2 +- .../de/jrpie/android/launcher/Application.kt | 10 +- .../de/jrpie/android/launcher/Functions.kt | 24 +- .../jrpie/android/launcher/actions/Action.kt | 56 +- .../jrpie/android/launcher/actions/Gesture.kt | 2 +- .../launcher/actions/lock/LockMethod.kt | 1 - .../de/jrpie/android/launcher/apps/AppInfo.kt | 20 +- .../launcher/apps/PinnedShortcutInfo.kt | 23 +- .../android/launcher/apps/PrivateSpace.kt | 1 + .../launcher/preferences/ColorPreference.kt | 9 +- .../launcher/preferences/ListLayout.kt | 7 +- .../launcher/preferences/legacy/Version1.kt | 16 +- .../preferences/legacy/VersionUnknown.kt | 621 +++++++++--------- .../launcher/preferences/theme/ColorTheme.kt | 1 - .../jrpie/android/launcher/ui/HomeActivity.kt | 3 + .../launcher/ui/PinShortcutActivity.kt | 18 +- .../de/jrpie/android/launcher/ui/UIObject.kt | 2 + .../android/launcher/ui/list/ListActivity.kt | 21 +- .../ui/list/apps/AppsRecyclerAdapter.kt | 11 +- .../ui/list/apps/ContextMenuActions.kt | 15 +- .../ui/list/other/OtherRecyclerAdapter.kt | 17 +- .../launcher/ui/settings/SettingsActivity.kt | 10 +- .../SettingsFragmentActionsRecycler.kt | 6 +- .../ui/settings/meta/SettingsFragmentMeta.kt | 2 - .../launcher/ui/tutorial/TutorialActivity.kt | 13 +- .../android/launcher/ui/util/HtmlTextView.kt | 1 + .../tutorial_app_list.png | Bin .../tutorial_home_screen.png | Bin .../res/drawable/baseline_more_horiz_24.xml | 11 - .../res/drawable/ic_launcher_background.xml | 10 - app/src/main/res/drawable/round_outline.xml | 6 - .../main/res/layout/activity_pin_shortcut.xml | 2 +- app/src/main/res/layout/tutorial_4_setup.xml | 2 +- .../mipmap-hdpi/ic_launcher_foreground.webp | Bin 612 -> 0 bytes .../mipmap-mdpi/ic_launcher_foreground.webp | Bin 372 -> 0 bytes .../mipmap-xhdpi/ic_launcher_foreground.webp | Bin 880 -> 0 bytes .../mipmap-xxhdpi/ic_launcher_foreground.webp | Bin 1416 -> 0 bytes .../ic_launcher_foreground.webp | Bin 2046 -> 0 bytes app/src/main/res/values-de/strings.xml | 6 - app/src/main/res/values-es/strings.xml | 6 - app/src/main/res/values-fr/strings.xml | 6 - app/src/main/res/values-it/strings.xml | 6 - app/src/main/res/values-pt-rBR/strings.xml | 6 - app/src/main/res/values-tr/strings.xml | 6 - app/src/main/res/values-w820dp/dimens.xml | 6 - app/src/main/res/values-zh-rCN/strings.xml | 6 - .../res/values/ic_launcher_background.xml | 4 - app/src/main/res/values/strings.xml | 9 - app/src/main/res/values/styles.xml | 11 - docs/launcher.md | 1 + gradle.properties | 4 +- 51 files changed, 415 insertions(+), 605 deletions(-) rename app/src/main/res/{drawable => drawable-mdpi}/tutorial_app_list.png (100%) rename app/src/main/res/{drawable => drawable-mdpi}/tutorial_home_screen.png (100%) delete mode 100644 app/src/main/res/drawable/baseline_more_horiz_24.xml delete mode 100644 app/src/main/res/drawable/ic_launcher_background.xml delete mode 100644 app/src/main/res/drawable/round_outline.xml delete mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp delete mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp delete mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp delete mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp delete mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp delete mode 100644 app/src/main/res/values-w820dp/dimens.xml delete mode 100644 app/src/main/res/values/ic_launcher_background.xml diff --git a/app/build.gradle b/app/build.gradle index c75bb3d..8e6f551 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -95,7 +95,7 @@ android { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation 'androidx.activity:activity:1.8.0' + implementation 'androidx.activity:activity-ktx:1.8.0' implementation 'androidx.appcompat:appcompat:1.7.0' implementation 'androidx.core:core-ktx:1.15.0' implementation 'androidx.constraintlayout:constraintlayout:2.2.0' 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 e674e4e..e6cce23 100644 --- a/app/src/main/java/de/jrpie/android/launcher/Application.kt +++ b/app/src/main/java/de/jrpie/android/launcher/Application.kt @@ -7,11 +7,8 @@ import android.content.IntentFilter import android.content.SharedPreferences import android.content.pm.LauncherApps import android.content.pm.ShortcutInfo -import android.os.AsyncTask import android.os.Build import android.os.Build.VERSION_CODES -import android.os.Handler -import android.os.Looper import android.os.UserHandle import androidx.core.content.ContextCompat import androidx.lifecycle.MutableLiveData @@ -23,6 +20,9 @@ import de.jrpie.android.launcher.apps.isPrivateSpaceLocked import de.jrpie.android.launcher.preferences.LauncherPreferences import de.jrpie.android.launcher.preferences.migratePreferencesToNewVersion import de.jrpie.android.launcher.preferences.resetPreferences +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch class Application : android.app.Application() { val apps = MutableLiveData<List<AbstractDetailedAppInfo>>() @@ -153,6 +153,8 @@ class Application : android.app.Application() { private fun loadApps() { privateSpaceLocked.postValue(isPrivateSpaceLocked(this)) - AsyncTask.execute { apps.postValue(getApps(packageManager, applicationContext)) } + CoroutineScope(Dispatchers.Default).launch { + apps.postValue(getApps(packageManager, applicationContext)) + } } } 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 d5e8d13..7bbbdb5 100644 --- a/app/src/main/java/de/jrpie/android/launcher/Functions.kt +++ b/app/src/main/java/de/jrpie/android/launcher/Functions.kt @@ -12,7 +12,6 @@ import android.content.pm.LauncherApps import android.content.pm.LauncherApps.ShortcutQuery import android.content.pm.PackageManager import android.content.pm.ShortcutInfo -import android.net.Uri import android.os.Build import android.os.Bundle import android.os.UserHandle @@ -34,15 +33,9 @@ import de.jrpie.android.launcher.apps.getPrivateSpaceUser import de.jrpie.android.launcher.apps.isPrivateSpaceSupported import de.jrpie.android.launcher.preferences.LauncherPreferences import de.jrpie.android.launcher.ui.tutorial.TutorialActivity +import androidx.core.net.toUri -/* REQUEST CODES */ - -const val REQUEST_CHOOSE_APP = 1 -const val REQUEST_UNINSTALL = 2 - -const val REQUEST_SET_DEFAULT_HOME = 42 - const val LOG_TAG = "Launcher" fun isDefaultHomeScreen(context: Context): Boolean { @@ -69,9 +62,8 @@ fun setDefaultHomeScreen(context: Context, checkDefault: Boolean = false) { && !isDefault // 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 + context.startActivity( + roleManager.createRequestRoleIntent(RoleManager.ROLE_HOME) ) return } @@ -125,7 +117,7 @@ fun removeUnusedShortcuts(context: Context) { } fun openInBrowser(url: String, context: Context) { - val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) + val intent = Intent(Intent.ACTION_VIEW, url.toUri()) intent.putExtras(Bundle().apply { putBoolean("new_window", true) }) try { context.startActivity(intent) @@ -212,14 +204,6 @@ fun getApps( return loadList } - -// Used in Tutorial and Settings `ActivityOnResult` -fun saveListActivityChoice(data: Intent?) { - val forGesture = data?.getStringExtra("forGesture") ?: return - Gesture.byId(forGesture)?.let { Action.setActionForGesture(it, Action.fromIntent(data)) } -} - - // used for the bug report button fun getDeviceInfo(): String { return """ diff --git a/app/src/main/java/de/jrpie/android/launcher/actions/Action.kt b/app/src/main/java/de/jrpie/android/launcher/actions/Action.kt index ddef92a..9a2dc62 100644 --- a/app/src/main/java/de/jrpie/android/launcher/actions/Action.kt +++ b/app/src/main/java/de/jrpie/android/launcher/actions/Action.kt @@ -2,7 +2,6 @@ package de.jrpie.android.launcher.actions import android.app.Activity import android.content.Context -import android.content.Intent import android.content.SharedPreferences.Editor import android.graphics.Rect import android.graphics.drawable.Drawable @@ -12,6 +11,7 @@ import de.jrpie.android.launcher.preferences.LauncherPreferences import kotlinx.serialization.Serializable import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json +import androidx.core.content.edit @Serializable @@ -29,10 +29,6 @@ sealed interface Action { prefEditor.putString(id, Json.encodeToString(this)) } - fun writeToIntent(intent: Intent) { - intent.putExtra("action", Json.encodeToString(this)) - } - companion object { fun forGesture(gesture: Gesture): Action? { @@ -44,23 +40,23 @@ sealed interface Action { } fun resetToDefaultActions(context: Context) { - val editor = LauncherPreferences.getSharedPreferences().edit() - val boundActions = HashSet<String>() - Gesture.entries.forEach { gesture -> - context.resources - .getStringArray(gesture.defaultsResource) - .filterNot { boundActions.contains(it) } - .map { Pair(it, Json.decodeFromString<Action>(it)) } - .firstOrNull { it.second.isAvailable(context) } - ?.apply { - // allow to bind CHOOSE to multiple gestures - if (second != LauncherAction.CHOOSE) { - boundActions.add(first) + LauncherPreferences.getSharedPreferences().edit { + val boundActions = HashSet<String>() + Gesture.entries.forEach { gesture -> + context.resources + .getStringArray(gesture.defaultsResource) + .filterNot { boundActions.contains(it) } + .map { Pair(it, Json.decodeFromString<Action>(it)) } + .firstOrNull { it.second.isAvailable(context) } + ?.apply { + // allow to bind CHOOSE to multiple gestures + if (second != LauncherAction.CHOOSE) { + boundActions.add(first) + } + second.bindToGesture(this@edit, gesture.id) } - second.bindToGesture(editor, gesture.id) - } + } } - editor.apply() } fun setActionForGesture(gesture: Gesture, action: Action?) { @@ -68,15 +64,15 @@ sealed interface Action { clearActionForGesture(gesture) return } - val editor = LauncherPreferences.getSharedPreferences().edit() - action.bindToGesture(editor, gesture.id) - editor.apply() + LauncherPreferences.getSharedPreferences().edit { + action.bindToGesture(this, gesture.id) + } } fun clearActionForGesture(gesture: Gesture) { - LauncherPreferences.getSharedPreferences().edit() - .remove(gesture.id) - .apply() + LauncherPreferences.getSharedPreferences().edit { + remove(gesture.id) + } } fun launch( @@ -87,6 +83,9 @@ sealed interface Action { ) { if (action != null && action.invoke(context)) { if (context is Activity) { + // There does not seem to be a good alternative to overridePendingTransition. + // Note that we can't use overrideActivityTransition here. + @Suppress("deprecation") context.overridePendingTransition(animationIn, animationOut) } } else { @@ -97,10 +96,5 @@ sealed interface Action { ).show() } } - - fun fromIntent(data: Intent): Action? { - val json = data.getStringExtra("action") ?: return null - return Json.decodeFromString(json) - } } } \ No newline at end of file diff --git a/app/src/main/java/de/jrpie/android/launcher/actions/Gesture.kt b/app/src/main/java/de/jrpie/android/launcher/actions/Gesture.kt index 110e4f8..a2434e1 100644 --- a/app/src/main/java/de/jrpie/android/launcher/actions/Gesture.kt +++ b/app/src/main/java/de/jrpie/android/launcher/actions/Gesture.kt @@ -250,7 +250,7 @@ enum class Gesture( "action.back", R.string.settings_gesture_back, R.string.settings_gesture_description_back, - R.array.default_up + R.array.default_back ); enum class Edge { diff --git a/app/src/main/java/de/jrpie/android/launcher/actions/lock/LockMethod.kt b/app/src/main/java/de/jrpie/android/launcher/actions/lock/LockMethod.kt index 8ae2415..541510a 100644 --- a/app/src/main/java/de/jrpie/android/launcher/actions/lock/LockMethod.kt +++ b/app/src/main/java/de/jrpie/android/launcher/actions/lock/LockMethod.kt @@ -9,7 +9,6 @@ import de.jrpie.android.launcher.R import de.jrpie.android.launcher.preferences.LauncherPreferences -@Suppress("unused") enum class LockMethod( private val lock: (Context) -> Unit, private val isEnabled: (Context) -> Boolean, diff --git a/app/src/main/java/de/jrpie/android/launcher/apps/AppInfo.kt b/app/src/main/java/de/jrpie/android/launcher/apps/AppInfo.kt index 944cfaa..9534431 100644 --- a/app/src/main/java/de/jrpie/android/launcher/apps/AppInfo.kt +++ b/app/src/main/java/de/jrpie/android/launcher/apps/AppInfo.kt @@ -15,19 +15,7 @@ import kotlinx.serialization.Serializable */ @Serializable @SerialName("app") -class AppInfo(val packageName: String, val activityName: String?, val user: Int = INVALID_USER): AbstractAppInfo { - - override fun equals(other: Any?): Boolean { - if(other is AppInfo) { - return other.user == user && other.packageName == packageName - && other.activityName == activityName - } - return super.equals(other) - } - - override fun hashCode(): Int { - return packageName.hashCode() - } +data class AppInfo(val packageName: String, val activityName: String?, val user: Int = INVALID_USER): AbstractAppInfo { fun getLauncherActivityInfo( context: Context @@ -38,10 +26,4 @@ class AppInfo(val packageName: String, val activityName: String?, val user: Int return activityList.firstOrNull { app -> app.name == activityName } ?: activityList.firstOrNull() } - - - override fun toString(): String { - return "AppInfo {package=$packageName, activity=$activityName, user=$user}" - } - } \ No newline at end of file diff --git a/app/src/main/java/de/jrpie/android/launcher/apps/PinnedShortcutInfo.kt b/app/src/main/java/de/jrpie/android/launcher/apps/PinnedShortcutInfo.kt index 1dc1e1f..54230ae 100644 --- a/app/src/main/java/de/jrpie/android/launcher/apps/PinnedShortcutInfo.kt +++ b/app/src/main/java/de/jrpie/android/launcher/apps/PinnedShortcutInfo.kt @@ -16,7 +16,7 @@ import kotlinx.serialization.Serializable @RequiresApi(Build.VERSION_CODES.N_MR1) @Serializable @SerialName("shortcut") -class PinnedShortcutInfo( +data class PinnedShortcutInfo( val id: String, val packageName: String, val activityName: String, @@ -43,25 +43,4 @@ class PinnedShortcutInfo( null } } - - override fun equals(other: Any?): Boolean { - return (other as? PinnedShortcutInfo)?.let { - packageName == this.packageName && - activityName == this.activityName && - id == this.id && - user == this.user - } ?: false - } - - override fun hashCode(): Int { - var result = id.hashCode() - result = 31 * result + packageName.hashCode() - result = 31 * result + activityName.hashCode() - result = 31 * result + user - return result - } - - override fun toString(): String { - return "PinnedShortcutInfo { package=$packageName, activity=$activityName, user=$user, id=$id}" - } } \ No newline at end of file diff --git a/app/src/main/java/de/jrpie/android/launcher/apps/PrivateSpace.kt b/app/src/main/java/de/jrpie/android/launcher/apps/PrivateSpace.kt index e44ff1c..24665d7 100644 --- a/app/src/main/java/de/jrpie/android/launcher/apps/PrivateSpace.kt +++ b/app/src/main/java/de/jrpie/android/launcher/apps/PrivateSpace.kt @@ -123,6 +123,7 @@ fun togglePrivateSpaceLock(context: Context) { } } +@Suppress("SameReturnValue") fun hidePrivateSpaceWhenLocked(context: Context): Boolean { // Trying to access the setting as a 3rd party launcher raises a security exception. // This is an Android bug: https://issuetracker.google.com/issues/352276244#comment5 diff --git a/app/src/main/java/de/jrpie/android/launcher/preferences/ColorPreference.kt b/app/src/main/java/de/jrpie/android/launcher/preferences/ColorPreference.kt index a21d458..0f95efd 100644 --- a/app/src/main/java/de/jrpie/android/launcher/preferences/ColorPreference.kt +++ b/app/src/main/java/de/jrpie/android/launcher/preferences/ColorPreference.kt @@ -17,6 +17,7 @@ import androidx.core.graphics.green import androidx.core.graphics.red import androidx.preference.Preference import de.jrpie.android.launcher.R +import androidx.core.graphics.toColorInt class ColorPreference(context: Context, attrs: AttributeSet?) : Preference(context, attrs) { @@ -52,7 +53,7 @@ class ColorPreference(context: Context, attrs: AttributeSet?) : AlertDialog.Builder(context, R.style.AlertDialogCustom).apply { setView(R.layout.dialog_choose_color) setTitle(R.string.dialog_choose_color_title) - setPositiveButton(R.string.dialog_select_color_ok) { _, _ -> + setPositiveButton(android.R.string.ok) { _, _ -> persistInt(currentColor) summary = currentColor.getHex() } @@ -83,10 +84,10 @@ class ColorPreference(context: Context, attrs: AttributeSet?) : override fun onTextChanged(text: CharSequence?, p1: Int, p2: Int, p3: Int) {} override fun afterTextChanged(editable: Editable?) { preview.hasFocus() || return - val newText = editable?.toString() - newText.isNullOrBlank() && return + val newText = editable?.toString() ?: return + newText.isBlank() && return try { - val newColor = Color.parseColor(newText.toString()) + val newColor = newText.toColorInt() currentColor = newColor updateColor(false) } catch (_: IllegalArgumentException) { diff --git a/app/src/main/java/de/jrpie/android/launcher/preferences/ListLayout.kt b/app/src/main/java/de/jrpie/android/launcher/preferences/ListLayout.kt index e20945a..5f7b9d6 100644 --- a/app/src/main/java/de/jrpie/android/launcher/preferences/ListLayout.kt +++ b/app/src/main/java/de/jrpie/android/launcher/preferences/ListLayout.kt @@ -1,6 +1,7 @@ package de.jrpie.android.launcher.preferences import android.content.Context +import android.util.TypedValue import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView @@ -27,8 +28,10 @@ enum class ListLayout( GRID( { c -> val displayMetrics = c.resources.displayMetrics - val widthSp = displayMetrics.widthPixels / displayMetrics.scaledDensity - GridLayoutManager(c, (widthSp / 90).toInt()) + val widthColumnPx = + TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 90f, displayMetrics) + val numColumns = (displayMetrics.widthPixels / widthColumnPx).toInt() + GridLayoutManager(c, numColumns) }, R.layout.list_apps_row_variant_grid, false diff --git a/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version1.kt b/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version1.kt index 6252811..a1cb022 100644 --- a/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version1.kt +++ b/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version1.kt @@ -13,9 +13,11 @@ import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json import org.json.JSONException import org.json.JSONObject +import androidx.core.content.edit @Serializable +@Suppress("unused") private class LegacyMapEntry(val key: AppInfo, val value: String) private fun serializeMapAppInfo(value: Map<AppInfo, String>?): Set<String>? { @@ -100,7 +102,7 @@ private fun migrateAppInfoStringMap(key: String) { } }?.toMap(HashMap()) )?.let { - preferences.edit().putStringSet(key, it).apply() + preferences.edit { putStringSet(key, it) } } } @@ -109,16 +111,16 @@ private fun migrateAppInfoSet(key: String) { .map(AppInfo.Companion::legacyDeserialize) .map(AppInfo::serialize) .toSet() - .let { LauncherPreferences.getSharedPreferences().edit().putStringSet(key, it).apply() } + .let { LauncherPreferences.getSharedPreferences().edit { putStringSet(key, it) } } } private fun migrateAction(key: String) { Action.legacyFromPreference(key)?.let { action -> - LauncherPreferences.getSharedPreferences().edit() - .putString(key, Json.encodeToString(action)) - .remove("$key.app") - .remove("$key.user") - .apply() + LauncherPreferences.getSharedPreferences().edit { + putString(key, Json.encodeToString(action)) + .remove("$key.app") + .remove("$key.user") + } } } diff --git a/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/VersionUnknown.kt b/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/VersionUnknown.kt index a33670b..2d1152d 100644 --- a/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/VersionUnknown.kt +++ b/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/VersionUnknown.kt @@ -6,7 +6,7 @@ import android.util.Log import de.jrpie.android.launcher.preferences.LauncherPreferences import de.jrpie.android.launcher.preferences.theme.Background import de.jrpie.android.launcher.preferences.theme.ColorTheme - +import androidx.core.content.edit private fun migrateStringPreference( @@ -64,318 +64,317 @@ fun migratePreferencesFromVersionUnknown(context: Context) { return } - val newPrefs = LauncherPreferences.getSharedPreferences().edit() + LauncherPreferences.getSharedPreferences().edit { - migrateBooleanPreference( - oldPrefs, - newPrefs, - "startedBefore", - "internal.started_before", - false - ) + migrateBooleanPreference( + oldPrefs, + this, + "startedBefore", + "internal.started_before", + false + ) - migrateStringPreference( - oldPrefs, - newPrefs, - "action_volumeUpApp", - "action.volume_up.app", - "" - ) - migrateIntPreference( - oldPrefs, - newPrefs, - "action_volumeUpApp_user", - "action.volume_up.user", - -1 - ) - migrateStringPreference( - oldPrefs, - newPrefs, - "action_volumeDownApp", - "action.volume_down.app", - "" - ) - migrateIntPreference( - oldPrefs, - newPrefs, - "action_volumeDownApp_user", - "action.volume_down.user", - -1 - ) - migrateStringPreference(oldPrefs, newPrefs, "action_timeApp", "action.time.app", "") - migrateIntPreference(oldPrefs, newPrefs, "action_timeApp_user", "action.time.user", -1) - migrateStringPreference(oldPrefs, newPrefs, "action_dateApp", "action.date.app", "") - migrateIntPreference(oldPrefs, newPrefs, "action_dateApp_user", "action.date.user", -1) - migrateStringPreference( - oldPrefs, - newPrefs, - "action_longClickApp", - "action.long_click.app", - "" - ) - migrateIntPreference( - oldPrefs, - newPrefs, - "action_longClickApp_user", - "action.long_click.user", - -1 - ) - migrateStringPreference( - oldPrefs, - newPrefs, - "action_doubleClickApp", - "action.double_click.app", - "" - ) - migrateIntPreference( - oldPrefs, - newPrefs, - "action_doubleClickApp_user", - "action.double_click.user", - -1 - ) - migrateStringPreference(oldPrefs, newPrefs, "action_upApp", "action.up.app", "") - migrateIntPreference(oldPrefs, newPrefs, "action_upApp_user", "action.up.user", -1) - migrateStringPreference( - oldPrefs, - newPrefs, - "action_up_leftApp", - "action.up_left.app", - "" - ) - migrateIntPreference( - oldPrefs, - newPrefs, - "action_up_leftApp_user", - "action.up_left.user", - -1 - ) - migrateStringPreference( - oldPrefs, - newPrefs, - "action_up_rightApp", - "action.up_right.app", - "" - ) - migrateIntPreference( - oldPrefs, - newPrefs, - "action_up_rightApp_user", - "action.up_right.user", - -1 - ) - migrateStringPreference( - oldPrefs, - newPrefs, - "action_doubleUpApp", - "action.double_up.app", - "" - ) - migrateIntPreference( - oldPrefs, - newPrefs, - "action_doubleUpApp_user", - "action.double_up.user", - -1 - ) - migrateStringPreference(oldPrefs, newPrefs, "action_downApp", "action.down.app", "") - migrateIntPreference(oldPrefs, newPrefs, "action_downApp_user", "action.down.user", -1) - migrateStringPreference( - oldPrefs, - newPrefs, - "action_down_leftApp", - "action.down_left.app", - "" - ) - migrateIntPreference( - oldPrefs, - newPrefs, - "action_down_leftApp_user", - "action.down_left.user", - -1 - ) - migrateStringPreference( - oldPrefs, - newPrefs, - "action_down_rightApp", - "action.down_right.app", - "" - ) - migrateIntPreference( - oldPrefs, - newPrefs, - "action_down_rightApp_user", - "action.down_right.user", - -1 - ) - migrateStringPreference( - oldPrefs, - newPrefs, - "action_doubleDownApp", - "action.double_down.app", - "" - ) - migrateIntPreference( - oldPrefs, - newPrefs, - "action_doubleDownApp_user", - "action.double_down.user", - -1 - ) - migrateStringPreference(oldPrefs, newPrefs, "action_leftApp", "action.left.app", "") - migrateIntPreference(oldPrefs, newPrefs, "action_leftApp_user", "action.left.user", -1) - migrateStringPreference( - oldPrefs, - newPrefs, - "action_left_topApp", - "action.left_top.app", - "" - ) - migrateIntPreference( - oldPrefs, - newPrefs, - "action_left_topApp_user", - "action.left_top.user", - -1 - ) - migrateStringPreference( - oldPrefs, - newPrefs, - "action_left_bottomApp", - "action.left_bottom.app", - "" - ) - migrateIntPreference( - oldPrefs, - newPrefs, - "action_left_bottomApp_user", - "action.left_bottom.user", - -1 - ) - migrateStringPreference( - oldPrefs, - newPrefs, - "action_doubleLeftApp", - "action.double_left.app", - "" - ) - migrateIntPreference( - oldPrefs, - newPrefs, - "action_doubleLeftApp_user", - "action.double_left.user", - -1 - ) - migrateStringPreference(oldPrefs, newPrefs, "action_rightApp", "action.right.app", "") - migrateIntPreference( - oldPrefs, - newPrefs, - "action_rightApp_user", - "action.right.user", - -1 - ) - migrateStringPreference( - oldPrefs, - newPrefs, - "action_right_topApp", - "action.right_top.app", - "" - ) - migrateIntPreference( - oldPrefs, - newPrefs, - "action_right_topApp_user", - "action.right_top.user", - -1 - ) - migrateStringPreference( - oldPrefs, - newPrefs, - "action_right_bottomApp", - "action.right_bottom.app", - "" - ) - migrateIntPreference( - oldPrefs, - newPrefs, - "action_right_bottomApp_user", - "action.right_bottom.user", - -1 - ) - migrateStringPreference( - oldPrefs, - newPrefs, - "action_doubleRightApp", - "action.double_right.app", - "" - ) - migrateIntPreference( - oldPrefs, - newPrefs, - "action_doubleRightApp_user", - "action.double_right.user", - -1 - ) - migrateBooleanPreference(oldPrefs, newPrefs, "timeVisible", "clock.time_visible", true) - migrateBooleanPreference(oldPrefs, newPrefs, "dateVisible", "clock.date_visible", true) - migrateBooleanPreference( - oldPrefs, - newPrefs, - "dateLocalized", - "clock.date_localized", - false - ) - migrateBooleanPreference( - oldPrefs, - newPrefs, - "dateTimeFlip", - "clock.date_time_flip", - false - ) - migrateBooleanPreference( - oldPrefs, - newPrefs, - "disableTimeout", - "display.disable_timeout", - false - ) - migrateBooleanPreference( - oldPrefs, - newPrefs, - "useFullScreen", - "display.use_full_screen", - true - ) - migrateBooleanPreference( - oldPrefs, - newPrefs, - "enableDoubleActions", - "enabled_gestures.double_actions", - true - ) - migrateBooleanPreference( - oldPrefs, - newPrefs, - "enableEdgeActions", - "enabled_gestures.edge_actions", - true - ) - migrateBooleanPreference( - oldPrefs, - newPrefs, - "searchAutoLaunch", - "functionality.search_auto_launch", - true - ) - migrateBooleanPreference( - oldPrefs, - newPrefs, - "searchAutoKeyboard", - "functionality.search_auto_keyboard", - true - ) - - newPrefs.apply() + migrateStringPreference( + oldPrefs, + this, + "action_volumeUpApp", + "action.volume_up.app", + "" + ) + migrateIntPreference( + oldPrefs, + this, + "action_volumeUpApp_user", + "action.volume_up.user", + -1 + ) + migrateStringPreference( + oldPrefs, + this, + "action_volumeDownApp", + "action.volume_down.app", + "" + ) + migrateIntPreference( + oldPrefs, + this, + "action_volumeDownApp_user", + "action.volume_down.user", + -1 + ) + migrateStringPreference(oldPrefs, this, "action_timeApp", "action.time.app", "") + migrateIntPreference(oldPrefs, this, "action_timeApp_user", "action.time.user", -1) + migrateStringPreference(oldPrefs, this, "action_dateApp", "action.date.app", "") + migrateIntPreference(oldPrefs, this, "action_dateApp_user", "action.date.user", -1) + migrateStringPreference( + oldPrefs, + this, + "action_longClickApp", + "action.long_click.app", + "" + ) + migrateIntPreference( + oldPrefs, + this, + "action_longClickApp_user", + "action.long_click.user", + -1 + ) + migrateStringPreference( + oldPrefs, + this, + "action_doubleClickApp", + "action.double_click.app", + "" + ) + migrateIntPreference( + oldPrefs, + this, + "action_doubleClickApp_user", + "action.double_click.user", + -1 + ) + migrateStringPreference(oldPrefs, this, "action_upApp", "action.up.app", "") + migrateIntPreference(oldPrefs, this, "action_upApp_user", "action.up.user", -1) + migrateStringPreference( + oldPrefs, + this, + "action_up_leftApp", + "action.up_left.app", + "" + ) + migrateIntPreference( + oldPrefs, + this, + "action_up_leftApp_user", + "action.up_left.user", + -1 + ) + migrateStringPreference( + oldPrefs, + this, + "action_up_rightApp", + "action.up_right.app", + "" + ) + migrateIntPreference( + oldPrefs, + this, + "action_up_rightApp_user", + "action.up_right.user", + -1 + ) + migrateStringPreference( + oldPrefs, + this, + "action_doubleUpApp", + "action.double_up.app", + "" + ) + migrateIntPreference( + oldPrefs, + this, + "action_doubleUpApp_user", + "action.double_up.user", + -1 + ) + migrateStringPreference(oldPrefs, this, "action_downApp", "action.down.app", "") + migrateIntPreference(oldPrefs, this, "action_downApp_user", "action.down.user", -1) + migrateStringPreference( + oldPrefs, + this, + "action_down_leftApp", + "action.down_left.app", + "" + ) + migrateIntPreference( + oldPrefs, + this, + "action_down_leftApp_user", + "action.down_left.user", + -1 + ) + migrateStringPreference( + oldPrefs, + this, + "action_down_rightApp", + "action.down_right.app", + "" + ) + migrateIntPreference( + oldPrefs, + this, + "action_down_rightApp_user", + "action.down_right.user", + -1 + ) + migrateStringPreference( + oldPrefs, + this, + "action_doubleDownApp", + "action.double_down.app", + "" + ) + migrateIntPreference( + oldPrefs, + this, + "action_doubleDownApp_user", + "action.double_down.user", + -1 + ) + migrateStringPreference(oldPrefs, this, "action_leftApp", "action.left.app", "") + migrateIntPreference(oldPrefs, this, "action_leftApp_user", "action.left.user", -1) + migrateStringPreference( + oldPrefs, + this, + "action_left_topApp", + "action.left_top.app", + "" + ) + migrateIntPreference( + oldPrefs, + this, + "action_left_topApp_user", + "action.left_top.user", + -1 + ) + migrateStringPreference( + oldPrefs, + this, + "action_left_bottomApp", + "action.left_bottom.app", + "" + ) + migrateIntPreference( + oldPrefs, + this, + "action_left_bottomApp_user", + "action.left_bottom.user", + -1 + ) + migrateStringPreference( + oldPrefs, + this, + "action_doubleLeftApp", + "action.double_left.app", + "" + ) + migrateIntPreference( + oldPrefs, + this, + "action_doubleLeftApp_user", + "action.double_left.user", + -1 + ) + migrateStringPreference(oldPrefs, this, "action_rightApp", "action.right.app", "") + migrateIntPreference( + oldPrefs, + this, + "action_rightApp_user", + "action.right.user", + -1 + ) + migrateStringPreference( + oldPrefs, + this, + "action_right_topApp", + "action.right_top.app", + "" + ) + migrateIntPreference( + oldPrefs, + this, + "action_right_topApp_user", + "action.right_top.user", + -1 + ) + migrateStringPreference( + oldPrefs, + this, + "action_right_bottomApp", + "action.right_bottom.app", + "" + ) + migrateIntPreference( + oldPrefs, + this, + "action_right_bottomApp_user", + "action.right_bottom.user", + -1 + ) + migrateStringPreference( + oldPrefs, + this, + "action_doubleRightApp", + "action.double_right.app", + "" + ) + migrateIntPreference( + oldPrefs, + this, + "action_doubleRightApp_user", + "action.double_right.user", + -1 + ) + migrateBooleanPreference(oldPrefs, this, "timeVisible", "clock.time_visible", true) + migrateBooleanPreference(oldPrefs, this, "dateVisible", "clock.date_visible", true) + migrateBooleanPreference( + oldPrefs, + this, + "dateLocalized", + "clock.date_localized", + false + ) + migrateBooleanPreference( + oldPrefs, + this, + "dateTimeFlip", + "clock.date_time_flip", + false + ) + migrateBooleanPreference( + oldPrefs, + this, + "disableTimeout", + "display.disable_timeout", + false + ) + migrateBooleanPreference( + oldPrefs, + this, + "useFullScreen", + "display.use_full_screen", + true + ) + migrateBooleanPreference( + oldPrefs, + this, + "enableDoubleActions", + "enabled_gestures.double_actions", + true + ) + migrateBooleanPreference( + oldPrefs, + this, + "enableEdgeActions", + "enabled_gestures.edge_actions", + true + ) + migrateBooleanPreference( + oldPrefs, + this, + "searchAutoLaunch", + "functionality.search_auto_launch", + true + ) + migrateBooleanPreference( + oldPrefs, + this, + "searchAutoKeyboard", + "functionality.search_auto_keyboard", + true + ) + } when (oldPrefs.getString("theme", "finn")) { "finn" -> { 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 816d94f..d3088f4 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 @@ -5,7 +5,6 @@ import android.content.res.Resources import com.google.android.material.color.DynamicColors import de.jrpie.android.launcher.R -@Suppress("unused") enum class ColorTheme( private val id: Int, private val labelResource: Int, 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 14e04d5..a658cd1 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 @@ -57,6 +57,8 @@ class HomeActivity : UIObject, AppCompatActivity() { super<UIObject>.onCreate() val displayMetrics = DisplayMetrics() + + @Suppress("deprecation") // required to support API < 30 windowManager.defaultDisplay.getMetrics(displayMetrics) val width = displayMetrics.widthPixels @@ -78,6 +80,7 @@ class HomeActivity : UIObject, AppCompatActivity() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { binding.root.setOnApplyWindowInsetsListener { _, windowInsets -> + @Suppress("deprecation") // required to support API 29 val insets = windowInsets.systemGestureInsets touchGestureDetector.setSystemGestureInsets(insets) diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/PinShortcutActivity.kt b/app/src/main/java/de/jrpie/android/launcher/ui/PinShortcutActivity.kt index 4d5d700..71908ba 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/PinShortcutActivity.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/PinShortcutActivity.kt @@ -24,6 +24,7 @@ import de.jrpie.android.launcher.actions.ShortcutAction import de.jrpie.android.launcher.apps.PinnedShortcutInfo import de.jrpie.android.launcher.databinding.ActivityPinShortcutBinding import de.jrpie.android.launcher.preferences.LauncherPreferences +import androidx.core.content.edit class PinShortcutActivity : AppCompatActivity(), UIObject { private lateinit var binding: ActivityPinShortcutBinding @@ -72,9 +73,12 @@ class PinShortcutActivity : AppCompatActivity(), UIObject { isBound = true request.accept() } - val editor = LauncherPreferences.getSharedPreferences().edit() - ShortcutAction(PinnedShortcutInfo(request.shortcutInfo!!)).bindToGesture(editor, gesture.id) - editor.apply() + LauncherPreferences.getSharedPreferences().edit { + ShortcutAction(PinnedShortcutInfo(request.shortcutInfo!!)).bindToGesture( + this, + gesture.id + ) + } dialog.dismiss() } dialog.findViewById<RecyclerView>(R.id.dialog_select_gesture_recycler).apply { @@ -117,11 +121,11 @@ class PinShortcutActivity : AppCompatActivity(), UIObject { } inner class GestureRecyclerAdapter(val context: Context, val onClick: (Gesture) -> Unit): RecyclerView.Adapter<GestureRecyclerAdapter.ViewHolder>() { - val gestures = Gesture.entries.filter { it.isEnabled() }.toList() + private val gestures = Gesture.entries.filter { it.isEnabled() }.toList() inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - val label = itemView.findViewById<TextView>(R.id.dialog_select_gesture_row_name) - val description = itemView.findViewById<TextView>(R.id.dialog_select_gesture_row_description) - val icon = itemView.findViewById<ImageView>(R.id.dialog_select_gesture_row_icon) + val label: TextView = itemView.findViewById(R.id.dialog_select_gesture_row_name) + val description: TextView = itemView.findViewById(R.id.dialog_select_gesture_row_description) + val icon: ImageView = itemView.findViewById(R.id.dialog_select_gesture_row_icon) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/UIObject.kt b/app/src/main/java/de/jrpie/android/launcher/ui/UIObject.kt index d97388f..51324f4 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/UIObject.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/UIObject.kt @@ -15,8 +15,10 @@ import de.jrpie.android.launcher.preferences.LauncherPreferences * An interface implemented by every [Activity], Fragment etc. in Launcher. * It handles themes and window flags - a useful abstraction as it is the same everywhere. */ +@Suppress("deprecation") // FLAG_FULLSCREEN is required to support API level < 30 fun setWindowFlags(window: Window, homeScreen: Boolean) { window.setFlags(0, 0) // clear flags + // Display notification bar if (LauncherPreferences.display().hideStatusBar()) window.setFlags( diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/list/ListActivity.kt b/app/src/main/java/de/jrpie/android/launcher/ui/list/ListActivity.kt index 997d2b0..59d83e5 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/list/ListActivity.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/list/ListActivity.kt @@ -1,13 +1,10 @@ package de.jrpie.android.launcher.ui.list -import android.app.Activity -import android.content.Intent import android.content.res.Resources import android.graphics.Rect import android.os.Build import android.os.Bundle import android.view.View -import android.widget.Toast import android.window.OnBackInvokedDispatcher import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.content.res.AppCompatResources @@ -16,7 +13,6 @@ import androidx.viewpager2.adapter.FragmentStateAdapter import com.google.android.material.tabs.TabLayoutMediator import de.jrpie.android.launcher.Application import de.jrpie.android.launcher.R -import de.jrpie.android.launcher.REQUEST_UNINSTALL import de.jrpie.android.launcher.actions.LauncherAction import de.jrpie.android.launcher.apps.AppFilter import de.jrpie.android.launcher.apps.hidePrivateSpaceWhenLocked @@ -113,10 +109,13 @@ class ListActivity : AppCompatActivity(), UIObject { ?.let { ListActivityIntention.valueOf(it) } ?: ListActivityIntention.VIEW + @Suppress("deprecation") // required to support API level < 33 favoritesVisibility = bundle.getSerializable("favoritesVisibility") as? AppFilter.Companion.AppSetVisibility ?: favoritesVisibility + @Suppress("deprecation") // required to support API level < 33 privateSpaceVisibility = bundle.getSerializable("privateSpaceVisibility") as? AppFilter.Companion.AppSetVisibility ?: privateSpaceVisibility + @Suppress("deprecation") // required to support API level < 33 hiddenVisibility = bundle.getSerializable("hiddenVisibility") as? AppFilter.Companion.AppSetVisibility ?: hiddenVisibility @@ -183,20 +182,6 @@ class ListActivity : AppCompatActivity(), UIObject { finish() } - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - super.onActivityResult(requestCode, resultCode, data) - if (requestCode == REQUEST_UNINSTALL) { - if (resultCode == Activity.RESULT_OK) { - Toast.makeText(this, getString(R.string.list_removed), Toast.LENGTH_LONG).show() - finish() - } else if (resultCode == Activity.RESULT_FIRST_USER) { - Toast.makeText(this, getString(R.string.list_not_removed), Toast.LENGTH_LONG).show() - finish() - } - } - } - - fun updateTitle() { var titleResource = intention.titleResource if (intention == ListActivityIntention.VIEW) { diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/AppsRecyclerAdapter.kt b/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/AppsRecyclerAdapter.kt index c4428b7..65278ce 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/AppsRecyclerAdapter.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/AppsRecyclerAdapter.kt @@ -2,7 +2,6 @@ package de.jrpie.android.launcher.ui.list.apps import android.annotation.SuppressLint import android.app.Activity -import android.content.Intent import android.graphics.Rect import android.view.LayoutInflater import android.view.View @@ -15,7 +14,8 @@ import androidx.appcompat.app.AppCompatActivity import androidx.recyclerview.widget.RecyclerView import de.jrpie.android.launcher.Application import de.jrpie.android.launcher.R -import de.jrpie.android.launcher.REQUEST_CHOOSE_APP +import de.jrpie.android.launcher.actions.Action +import de.jrpie.android.launcher.actions.Gesture import de.jrpie.android.launcher.apps.AbstractDetailedAppInfo import de.jrpie.android.launcher.apps.AppFilter import de.jrpie.android.launcher.apps.AppInfo @@ -195,11 +195,10 @@ class AppsRecyclerAdapter( } ListActivity.ListActivityIntention.PICK -> { - val returnIntent = Intent() - appInfo.getAction().writeToIntent(returnIntent) - returnIntent.putExtra("forGesture", forGesture) - activity.setResult(REQUEST_CHOOSE_APP, returnIntent) activity.finish() + forGesture ?: return + val gesture = Gesture.byId(forGesture) ?: return + Action.setActionForGesture(gesture, appInfo.getAction()) } } } diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/ContextMenuActions.kt b/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/ContextMenuActions.kt index 8b681b9..22dff02 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/ContextMenuActions.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/ContextMenuActions.kt @@ -6,7 +6,6 @@ import android.content.Context import android.content.Intent import android.content.pm.LauncherApps import android.graphics.Rect -import android.net.Uri import android.os.Bundle import android.util.Log import android.view.View @@ -14,11 +13,9 @@ import android.widget.EditText import androidx.appcompat.app.AlertDialog import com.google.android.material.snackbar.Snackbar import de.jrpie.android.launcher.R -import de.jrpie.android.launcher.REQUEST_UNINSTALL import de.jrpie.android.launcher.apps.AppInfo import de.jrpie.android.launcher.apps.AbstractAppInfo import de.jrpie.android.launcher.apps.AbstractDetailedAppInfo -import de.jrpie.android.launcher.apps.DetailedAppInfo import de.jrpie.android.launcher.apps.PinnedShortcutInfo import de.jrpie.android.launcher.getUserFromId import de.jrpie.android.launcher.preferences.LauncherPreferences @@ -44,17 +41,13 @@ fun AbstractAppInfo.uninstall(activity: Activity) { Log.i(LOG_TAG, "uninstalling $this") - val intent = Intent(Intent.ACTION_UNINSTALL_PACKAGE) + val intent = Intent(Intent.ACTION_DELETE) intent.data = "package:$packageName".toUri() getUserFromId(userId, activity).let { user -> intent.putExtra(Intent.EXTRA_USER, user) } + activity.startActivity(intent) - intent.putExtra(Intent.EXTRA_RETURN_RESULT, true) - activity.startActivityForResult( - intent, - REQUEST_UNINSTALL - ) } else if(this is PinnedShortcutInfo) { val pinned = LauncherPreferences.apps().pinnedShortcuts() ?: mutableSetOf() pinned.remove(this) @@ -102,8 +95,8 @@ fun AbstractDetailedAppInfo.showRenameDialog(context: Context) { AlertDialog.Builder(context, R.style.AlertDialogCustom).apply { setTitle(context.getString(R.string.dialog_rename_title, getLabel())) setView(R.layout.dialog_rename_app) - setNegativeButton(R.string.dialog_cancel) { d, _ -> d.cancel() } - setPositiveButton(R.string.dialog_rename_ok) { d, _ -> + setNegativeButton(android.R.string.cancel) { d, _ -> d.cancel() } + setPositiveButton(android.R.string.ok) { d, _ -> setCustomLabel( (d as? AlertDialog) ?.findViewById<EditText>(R.id.dialog_rename_app_edit_text) 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 70d5376..f176469 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 @@ -1,7 +1,6 @@ package de.jrpie.android.launcher.ui.list.other import android.app.Activity -import android.content.Intent import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -9,7 +8,8 @@ import android.widget.ImageView import android.widget.TextView import androidx.recyclerview.widget.RecyclerView import de.jrpie.android.launcher.R -import de.jrpie.android.launcher.REQUEST_CHOOSE_APP +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.ui.list.ListActivity @@ -36,7 +36,10 @@ class OtherRecyclerAdapter(val activity: Activity) : val pos = bindingAdapterPosition val content = othersList[pos] - (activity as? ListActivity)?.forGesture?.let { returnChoiceIntent(it, content) } + activity.finish() + val gestureId = (activity as? ListActivity)?.forGesture ?: return + val gesture = Gesture.byId(gestureId) ?: return + Action.setActionForGesture(gesture, content) } init { @@ -61,12 +64,4 @@ class OtherRecyclerAdapter(val activity: Activity) : val view: View = inflater.inflate(R.layout.list_other_row, parent, false) return ViewHolder(view) } - - private fun returnChoiceIntent(forGesture: String, action: LauncherAction) { - val returnIntent = Intent() - returnIntent.putExtra("forGesture", forGesture) - action.writeToIntent(returnIntent) - activity.setResult(REQUEST_CHOOSE_APP, returnIntent) - activity.finish() - } } \ No newline at end of file diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/settings/SettingsActivity.kt b/app/src/main/java/de/jrpie/android/launcher/ui/settings/SettingsActivity.kt index 2b3cdc6..4c464e5 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/settings/SettingsActivity.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/settings/SettingsActivity.kt @@ -11,12 +11,10 @@ import androidx.fragment.app.FragmentActivity import androidx.viewpager2.adapter.FragmentStateAdapter import com.google.android.material.tabs.TabLayoutMediator import de.jrpie.android.launcher.R -import de.jrpie.android.launcher.REQUEST_CHOOSE_APP import de.jrpie.android.launcher.databinding.SettingsBinding import de.jrpie.android.launcher.preferences.LauncherPreferences import de.jrpie.android.launcher.preferences.theme.Background import de.jrpie.android.launcher.preferences.theme.ColorTheme -import de.jrpie.android.launcher.saveListActivityChoice import de.jrpie.android.launcher.ui.UIObject import de.jrpie.android.launcher.ui.settings.actions.SettingsFragmentActions import de.jrpie.android.launcher.ui.settings.launcher.SettingsFragmentLauncher @@ -32,7 +30,6 @@ import de.jrpie.android.launcher.ui.settings.meta.SettingsFragmentMeta * Settings are closed automatically if the activity goes `onPause` unexpectedly. */ class SettingsActivity : AppCompatActivity(), UIObject { - private val EXTRA_TAB = "tab" private val solidBackground = LauncherPreferences.theme().background() == Background.SOLID || LauncherPreferences.theme().colorTheme() == ColorTheme.LIGHT @@ -106,11 +103,8 @@ class SettingsActivity : AppCompatActivity(), UIObject { } } - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - when (requestCode) { - REQUEST_CHOOSE_APP -> saveListActivityChoice(data) - else -> super.onActivityResult(requestCode, resultCode, data) - } + companion object { + private const val EXTRA_TAB = "tab" } } diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/settings/actions/SettingsFragmentActionsRecycler.kt b/app/src/main/java/de/jrpie/android/launcher/ui/settings/actions/SettingsFragmentActionsRecycler.kt index 630b5b0..ae47ce2 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/settings/actions/SettingsFragmentActionsRecycler.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/settings/actions/SettingsFragmentActionsRecycler.kt @@ -16,7 +16,6 @@ import androidx.fragment.app.Fragment import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import de.jrpie.android.launcher.R -import de.jrpie.android.launcher.REQUEST_CHOOSE_APP import de.jrpie.android.launcher.actions.Action import de.jrpie.android.launcher.actions.Gesture import de.jrpie.android.launcher.apps.AppFilter @@ -179,9 +178,6 @@ class ActionsRecyclerAdapter(val activity: Activity) : intent.putExtra("intention", ListActivity.ListActivityIntention.PICK.toString()) intent.putExtra("hiddenVisibility", AppFilter.Companion.AppSetVisibility.VISIBLE) intent.putExtra("forGesture", gesture.id) // for which action we choose the app - activity.startActivityForResult( - intent, - REQUEST_CHOOSE_APP - ) + activity.startActivity(intent) } } diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/settings/meta/SettingsFragmentMeta.kt b/app/src/main/java/de/jrpie/android/launcher/ui/settings/meta/SettingsFragmentMeta.kt index 26f276a..dea0bcf 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/settings/meta/SettingsFragmentMeta.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/settings/meta/SettingsFragmentMeta.kt @@ -2,7 +2,6 @@ package de.jrpie.android.launcher.ui.settings.meta import android.app.AlertDialog import android.content.Intent -import android.net.Uri import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -20,7 +19,6 @@ import de.jrpie.android.launcher.openTutorial import de.jrpie.android.launcher.preferences.resetPreferences import de.jrpie.android.launcher.ui.LegalInfoActivity import de.jrpie.android.launcher.ui.UIObject -import de.jrpie.android.launcher.ui.tutorial.TutorialActivity /** * The [SettingsFragmentMeta] is a used as a tab in the SettingsActivity. diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/TutorialActivity.kt b/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/TutorialActivity.kt index 12c6c8a..847639c 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/TutorialActivity.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/TutorialActivity.kt @@ -1,6 +1,5 @@ package de.jrpie.android.launcher.ui.tutorial -import android.content.Intent import android.content.res.Resources import android.os.Build import android.os.Bundle @@ -12,10 +11,8 @@ import androidx.fragment.app.FragmentActivity import androidx.viewpager2.adapter.FragmentStateAdapter import androidx.viewpager2.widget.ViewPager2 import com.google.android.material.tabs.TabLayoutMediator -import de.jrpie.android.launcher.REQUEST_CHOOSE_APP import de.jrpie.android.launcher.databinding.TutorialBinding import de.jrpie.android.launcher.preferences.LauncherPreferences -import de.jrpie.android.launcher.saveListActivityChoice import de.jrpie.android.launcher.ui.UIObject import de.jrpie.android.launcher.ui.blink import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragment0Start @@ -36,6 +33,7 @@ class TutorialActivity : AppCompatActivity(), UIObject { private lateinit var binding: TutorialBinding + override fun onCreate(savedInstanceState: Bundle?) { super<AppCompatActivity>.onCreate(savedInstanceState) super<UIObject>.onCreate() @@ -113,14 +111,9 @@ class TutorialActivity : AppCompatActivity(), UIObject { super<UIObject>.onStart() } - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - when (requestCode) { - REQUEST_CHOOSE_APP -> saveListActivityChoice(data) - else -> super.onActivityResult(requestCode, resultCode, data) - } - } - // prevent going back when the tutorial is shown for the first time + @Deprecated("Deprecated in Java", ReplaceWith("use anyway")) + @Suppress("deprecation") // support API level < 33 override fun onBackPressed() { if (LauncherPreferences.internal().started()) super.onBackPressed() diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/util/HtmlTextView.kt b/app/src/main/java/de/jrpie/android/launcher/ui/util/HtmlTextView.kt index 549f10f..5e38b9f 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/util/HtmlTextView.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/util/HtmlTextView.kt @@ -12,6 +12,7 @@ class HtmlTextView(context: Context, attr: AttributeSet?, int: Int) : constructor(context: Context) : this(context, null, 0) init { + @Suppress("deprecation") // required to support API level < 24 text = Html.fromHtml(text.toString()) movementMethod = LinkMovementMethod.getInstance() } diff --git a/app/src/main/res/drawable/tutorial_app_list.png b/app/src/main/res/drawable-mdpi/tutorial_app_list.png similarity index 100% rename from app/src/main/res/drawable/tutorial_app_list.png rename to app/src/main/res/drawable-mdpi/tutorial_app_list.png diff --git a/app/src/main/res/drawable/tutorial_home_screen.png b/app/src/main/res/drawable-mdpi/tutorial_home_screen.png similarity index 100% rename from app/src/main/res/drawable/tutorial_home_screen.png rename to app/src/main/res/drawable-mdpi/tutorial_home_screen.png diff --git a/app/src/main/res/drawable/baseline_more_horiz_24.xml b/app/src/main/res/drawable/baseline_more_horiz_24.xml deleted file mode 100644 index 061fae2..0000000 --- a/app/src/main/res/drawable/baseline_more_horiz_24.xml +++ /dev/null @@ -1,11 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:height="24dp" - android:viewportHeight="24" - android:viewportWidth="24" - android:width="24dp"> - - <path - android:fillColor="?android:textColor" - android:pathData="M6,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM18,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z" /> - -</vector> diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml deleted file mode 100644 index 4f1c4ab..0000000 --- a/app/src/main/res/drawable/ic_launcher_background.xml +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="108dp" - android:height="108dp" - android:viewportWidth="108" - android:viewportHeight="108"> - <path - android:fillColor="#252827" - android:pathData="M0,0h108v108h-108z" /> -</vector> diff --git a/app/src/main/res/drawable/round_outline.xml b/app/src/main/res/drawable/round_outline.xml deleted file mode 100644 index 3650338..0000000 --- a/app/src/main/res/drawable/round_outline.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- https://stackoverflow.com/a/30692466 --> -<shape xmlns:android="http://schemas.android.com/apk/res/android" - android:shape="rectangle"> - <corners android:radius="10dp" /> -</shape> \ No newline at end of file diff --git a/app/src/main/res/layout/activity_pin_shortcut.xml b/app/src/main/res/layout/activity_pin_shortcut.xml index 5e10118..2519374 100644 --- a/app/src/main/res/layout/activity_pin_shortcut.xml +++ b/app/src/main/res/layout/activity_pin_shortcut.xml @@ -116,7 +116,7 @@ android:layout_margin="10dp" android:layout_width="match_parent" android:layout_height="wrap_content" - android:text="@string/pin_shortcut_button_ok" + android:text="@android:string/ok" app:layout_constraintBottom_toBottomOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/tutorial_4_setup.xml b/app/src/main/res/layout/tutorial_4_setup.xml index bf62261..9650c57 100644 --- a/app/src/main/res/layout/tutorial_4_setup.xml +++ b/app/src/main/res/layout/tutorial_4_setup.xml @@ -33,7 +33,7 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/tutorial_setup_title" /> - <fragment + <androidx.fragment.app.FragmentContainerView android:id="@+id/tutorial_setup_actions_rview_fragment" android:name="de.jrpie.android.launcher.ui.settings.actions.SettingsFragmentActionsRecycler" android:layout_width="0dp" diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp deleted file mode 100644 index 9944fb2dadd599a43fcb996955e19c413af1ab56..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 612 zcmV-q0-OC(Nk&Fo0ssJ4MM6+kP&iCb0ssInp+G1QbwH9NNmA4Qf3*BC%|6nV0MtW- z1ONcbMoQ-GY}>YN+qP}nwr%@u+qP|E$^`WE|I`0ZecR*NaVU8R3$Fbh+(gKMv_6ER zKK~v?@=pavo(oT!@EZhtNY&?yQm}*$7@EB3tr;S{7kdIH2yx|zYlh5}_iAzwf`y^V zlPTg}(e`}#@9*+}WyKv5F+kB?%8EFo!Z!M6*@EBj@_hM+>c5JKIKNSs_cS+ryvFnw z!%Geu2@pfu-?bdxE9QD$_;J5H@CENhe&{Df+UgQGK(R-2gEbz4g0*Z=U84UIi*D}# z#Rk<mdbp@L=_l!lOAfH3$Wg;y%|$I97r6spWS4;ff^o_3{{br44aBfOr~Lc|I^#Qm ziY&Uui7SZh?>WdE<f&0>0TO$WkqQCBN)dY5>9nK%!c^uUln9{OPwY4jlHNKrk=~xs z@&wJTmjf=Z&qdlRcyy~pXX!e}=PEM`Yc$tM7baZy40O>Kx?u4*hwep`myxSbStiL$ ziA*@{5fMz?6L>UhRjMG##Q~CB@wo`aH@9J~fz3B31~_x4ki2yrVFT-v8{Z=49i(u8 z$Shmn0B{aol>Q~90%=~50Sx{dA{6#31<P$~Rtc3l$T`)zyg$$l4-n|+53*0Ii$8lV z!|4)+gX*-nZ21zL&Z66;R+EGNOV}}xpDAlELIoqqNq6lL0;*F{;Wz5G^Kx+*<~l&Q yU;HarLlUcyWjf@pO9p8SP;zx{#27}b{w3S*t{c{*;2EHp8>YHTPyavt|70~PRwr)& diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp deleted file mode 100644 index 7cfdde1db49d496c0c3f2adf905097bcc19c581d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 372 zcmV-)0gL`pNk&F&0RRA3MM6+kP&iCr0RR9mYrq;1mB5lD$yKxWzjOlfT0Uh8?}-RF zkZhZ_&a?f#ZTqLTjmWlb+qP}n_Rnlvp=$#A_x}&E2JL!+`38dJuZb}D{|;i+tQR<L z%2acODxNrt1L4RsWUfXm+yF&e@qrs;V%4&H2!9qFe|6IFRf4hH)pDMQfK*!445%+> zl*%TvxO)~)+q$$8;)oUH2bOl8_|vm5FmOv6sBm|Kd4Rl`KQI?PQDC@9vv&U;+r`d8 z&^{^lQmnDM=!~ul@Y2Djwp^R^H4^srs`Yw*kD+2^Ej)gaUsF@O3?#^>?fc!n;POUp z7Ign`m3pZ~(?>a>R`%b4<eSL**jpXob#J6+Il5tk4xM6cP&-q;ju}+|$!PzMv>3zy zMj7QTH23VE(6sQ+6b0ipSPg(#uTyh04dLo(^CDF?#qLsyisFJhJ8-BQVF0#5iizYR SvUTiGC!R8Zf0}>)|MUw1+Pb~~ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp deleted file mode 100644 index 68b43ba9113735c1998b0d9e54d7376cac7be60b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 880 zcmV-$1CRVtNk&F!0{{S5MM6+kP&iCn0{{Ro*T6Lpbx3j>Ns^@e|DPK?L}XPq&@uZ= zS}isiAprouvXMHRZQHhO+qTWOZQJ(Qwr$%#Z+ExDnhD71|I`1c|4;v){{L0p2V>WD z8O8A>VApZc`Ihj_+<z+o8lEo!7i^h*OC+K4vj+m}1^qebalUTD{6u#frYGc0m~cJr zfq4I4)KiRK=HU@-D&q$|aY+IHi3A0*2G5?9Dfnpz(TW>bb_ls<1P;-b3PI?17^{In zH0K2L45MUSu!y!4Fxl}=8JV{;rV-$@@m!LKf>F#Eg}pAH(GTkD!o-XEJ{YYNHc>4h z0QG6c!bTlGjaYYFhO>{0D9D!V7VPu{j|KqErcoF$s<@d2fQza+wD+#&B?<PKE#?gh zdLbx)$b(Q75D6xC>WI=n5(dys4`PEJw3RcOp}K`NxD^2~*fuD6yZ{@Vp*9GEEXSx+ zcXXgQNfHBoJ{~OzGIP(W<RB~9lc2W+NE*DWCEOXIG0rqVB_V4cV6s68D>TPUGx`L0 zyYu3m5n@SG2*^u94IkuLMzwV_304?D?grh83$~Jy1f7)%N#Zr2F;i|ei+-jBYO>Bd zu!-_TmvNI18-TfkWK9&*!z9#OI`^<0Vj2*eKpLz+T&B_hWLz^BvoJcAT3FM@YaMtV zBx&N`ge`zd>>g%2;x;H4t@cKTcxU1khQ(~P(!~f3Rk8PYc?|11B=I@EirW>7aVBat zly6}PAQ9W3(b-xY)YZkw`xtWIGXDff19dicE{GIbiSG!mdFTOBeXR|O>gfP!@EDAi z>h>qZ^J-omR+|;Q!@fvF2ab-51hGMh+cl0c30p_U#FZjZo#4Q81YJjH{AU<QttuZ+ z3L}jJdnOPY6r45zP4w{*lMHVG%>mvd%)x+9R7eW8Y2zTA#sOOw8T_P0nPPlI+y&cn zjT!;Mj9fAA=CW{U2e&l|orEV!(GXFqk37P~W`hzaUw}Rwf_-!8ppeoIt|MeeMWuZR zdN<xhL$=pCa(Y?8$lG-f;uPctC86YjR^5II!L&hwoM4<J=q0Ptt4J6$O((bwqMe{M z;rV1U2|8ZhY0<6RMJgMV1fz5(h)%>kX$%QvmsIH0;g@V`5EBVbbUmm4Pye6(KmC9D G|94f_z>CoU diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp deleted file mode 100644 index 337c6cc9f7b4bd0d4faf8f5fed0ace1c244aa28b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1416 zcmV;31$X*VNk&G11pok7MM6+kP&iC;1pojqL%~oGb<mP*+iu%n{$ut<f8gFLf+<6J z<ABsAA|%k-b~aM}q}sY27GvAC?U}W0+qP}nwr$%sI$JmS|8D~7^#AGq)BmUcPye6( zKmC9D|MdUq|I`2fgV``=`%ZEBU1*!MP2UgeKp#i{yD%<UUwuDJ_3XMXAO7s=%KmpG za^Z@#)>$*DG*kFQFM<)~^&;$rtVkBBii;d=byP(EB{c817CLDzgAV!%#9Ofr+REnq z6?~z}w9`?A5P~@pvcfD>6{R#SKPm+0Xi;cwyVs0J609%lZt2j-6fe>?jx=}?*U35( zy!mk)A~M=L7zFXPO(dQ|t8&V(D+$&&`{bghxVN=_As{$!b%$m!TDz+82Fc4+b?6xf zz42OB5gFnY79<Q#N<LWTWfnGDlY!OAdUm8!;wME%M&do4gBjX}H$h_;0>-!68G)Xs zk24S&(R?z7ts$FmC()Y1u?%fGUJO5NmVSB|VFv>U&Ls41ez#39tAlOA%OMUBMD>W= z<s{4w7^kOxZIP!p&~##b<3fC~%9u9GO$5X*fdfkClK5hU{(7|;o+pUKa|T&@hs6~; z?RAU&aGAND)tmxdRRz&GoiGa84Y@rNg|51lFn~CF_b}Fhzz*@btEvc8dpU#Lwo_FV zp0RN9?m?C%*tUY=sw!eraNw<Y$~hLsHkBLZx<X@;`3H+0f1$<#{74MgEzFV@s%tTb zAM`z$uf#F3g&NZHpNRX^3$-P28^k%NBl?xtKv-Qo`#_v{&mdT>uj*4Btm(_K#HRgh z$Mj@@uuJWrZA_T?E!5XHx>n!B#4k+85)glAYA6K`gP@tT6_`52J5^hjIJKX))#sK( zMTg4g#7^{scnq{i5aJD`=ZQ5nrt~3EKf@@t4ji!nHToHCLK4?N*6X{mOBs;h63sfI z5fEJ#>M;z^K-mq#Wh0y|(PDzoRS=_QJR~}9v?h28gUQcsj3Nib?1>f~4GApeLEhF- zF`RJUC{N;y9b-HFNX(mA_tasN;8l{mIks@(?rs`|JwVrlS@?t2R}auWUvEoiEIVxc zeN5OK)Kv;U+9X!}LG(x%g+7h03F4hs^KHV61xF1sH(}KVZ=w2a*@JZ1O`8NO?rF46 zU{O@_#NPk{&yuzRT|<W_tV*048MK?UB$_^rEF_Uok3CXSlAG5QF-xM=LJcXs1o5zE zF^HQZi+AI$F|inW7C!zYdL2Fy>>yI7NZ>^MND(&ivS)naGjWf|o!#)ANPMMw7JO$x zT*DkaZayT&P7(Q$w21>k=acx^(=uU|)l<f{TWNz!+H~{?k7Sq99u7{ssm~EZue%f9 zg+mh<M?riN(jjRJksHK+(hg5t;yA^IpJyxVN3vc^SPdcSak5m+J});Czct|X@CBIU z2z0<o25aJHTWO>bpAWxHspkOk(E#xRL}~3Z0<U|pVHMngoJiuL=8|Ro_yn)#_A60- zgCH*GB3Y<NMP~RAP4_8Lz9cvYw3Q%4gj@rhU<K|Rva3zRrLUwz*j6J+So~u`0=LyP zKY=xLN~(WJ5H@UXdw!KZLCN(oN!T<p!pUxs6t9zn^~H!w61NUnVYKs*W2*4m1i!LH zJl7LlPJvhtbxMT~*)p|dr2L+t=&kk}bP-=Iq}i#8Yg^z8=;OS#QO-ggvMO>hD%8K< z@2gi3Up=gGzz)-uQ7=>#t*A@Dpy+hB&H-DD5QAALJW-dhbVx*9!iffGk=I2zQ8yp0 z&9%*bo7)uCbT#BA>JmI66M0>Dqk?GFwQ06GXpdzEO6LqM)L5XXi|$CB{y+VH`v3I* W>HpLJr~gm?pZ-7nfBOG_g988tudbQ^ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp deleted file mode 100644 index ba69e326f6bce4fd0505d3b0d04e5effcd427263..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2046 zcmaKt`#;kQ1AwubNLCYZ%KdAS<6bc)VX-fBSweEZoZN2-ix{F@Rymu_aUUI-id^Pi z49Q%gHBn4L<ZeX`bJ=@-em|f0eSUgA&p+^71}!YO!U6)$m(1*)><zF>|GHLnXYkPm zd{d}v7(0Z0bDvt+7|S>Hxs$?5aZ_m=NliZ!=s27vipB^CBt<+PdnPx=Rc1Gavg6p- z8$&m_gqVcJMyc@Nf~58>!Vmro{|!Hje}b>I@3~9=pMl?mjDK=JvxXlX(L)<v?B<1w zI_sQ#pS~Nd5O4+r_w;o-8wk}cgd(vUyC%v>iY4A!otjKhk&T`GQ){KgTAd$XCr=oE zNtRn#UEAIqiL<3>z59DpFL+O3@FmKr(&MGYtryy6S1osAc*}>ET?h6){tF{p&(6+{ z9><ZdpKva9q`6HSB*SXEw6nRDP6cska|re3Uq{uY*5-b-HO5!BD9Q?@=0tEDgNJ{% zxlsw{#2LfG5-UUDjdQhDRZD+}Dhr?}HIX<ko%=CXQi~1XHIm_-rZgc1kpaawB6pkh znEl<9m8Ru0y9PpX?A{2KfpQ_;r6#=V7@y3j(059F>|ZmK$va;jqjHin>7D92n8@hQ z7*xSXTE6A3n*RQ?Y^IMIz?QKfL-d6*>1i5OCq*ebwvR{@84F2)iMzB}BzD=Z2oP5& z^>v2!e*ZQe!pe6~iq=C6Du#pW&nHszb9A{ea8;NSt_g^|`333_Ha4Kyk;yODXMjp! z=oXyEKdSUfw!zwLvY&)t=tnT6vCVC~2UE9w$?r<PG5!*@zV+NcwoX9>0CY$qLCH3c zE-nn((-DsGHVluduh?YNkw^=2**;@bNNLQQ6ik-WLu`_@T`cB`)qdiBy>u6gdclgC zOgphy4PKr!J*)8SGwGAsrI6lZ2rFFr7uUMLlv671v(+Jg1>Zj&R(K$O8rDx_U1hxa z6S{gwTWMAGsi!yfN?z?7`E{{+YYYM25qwx<7FbYu=q2CnvNkS99)!&#oXAzZ0naix zStdxz^?}Af$Fm&Yt08|}V=Po|v}ok9$74%nf}=t;lUZq;!Ob}w+~{n1PPzaRvP$Kg z&M17R7(pQ$sBvDzsT(`_z9p^fB)5TZsQFeXPz$!hUh}fi{0(W<7Re*5d!=FDSa_iY z@DEYS2gr;}z;~KBfJ}kubYW&xZ-xuYDYwHMEJ3AcuV{ibbF1peo+NT?;Xc@JTyw!+ z72>W+!W*g`>oEV!1|Eqb1#s)6i8{``N#C?95KVK?YN+E$9uO_v+SIjOREE07knZ`& z7so%PkaHe`$4nsSGOgj2kfD66kM!d0+vt#_bz}y#CLxF9)y!fKuz~Tgp5`OEU)PS+ zepNviqTzMzUWkT7tBNU&U2W2oOoX5@*tamhAvjSp$^{HHH#6)~%)(PEfV+{zPZd8~ zpfh52dF?I{_IbJY?HqJB#=15PMLGpFL8Ym}{-VieiWy;_j7#dsR{`kQkZQ(=r*epI zK`_4m`Ag#HxhIAZ22Vi&u_180bgF)?BPQcPMcelcvD~|XL}K-4hi3`*)Hg{JIAba) z?lj;Dn@id{WUReGEKCDxIhK9o?gH6m&KElE;|>*9jHoqV^zr)TuQXobFO$*=EVS#I zUfW4LR7Ch~&K7=U=>#N;0=~^MF2Ph1gzY1<(ZUZV54q4OuqVT*00Q~hLk#Z@iY0KP ziXus51qUNYgGYWaIlo)1U8*&Y=}Ss)mOg4ldZj#c;XGJ)RMuIPyp>!fVq!t!MPkh0 z19loHDq1wVEXSR=W(6-eeqDZV85nvvoQpQ{BX<BTzrhO+JVIOFGE@oSk+&W$`!K;2 z#BDCl)TZl}TPXJNe9J*o_Je&zC$OttFzbthkor5afmEDMu?FIYaL}4@9_I4ood;)J zK%zu|!1ehE#zb~j1=t^zttied|DYy7%IzBAiXi`NKy_f4sVPK3Pyf-PZ-7+qLwMc+ zn<+!|ctA|3nfTQCoNlo`!IcJmvXEne-*X#`MtF!kf+cd*+9yjYVpuY8@sQs0C>uCI zjkt{l*LxF_ifg-dEK-Q^Q&qD7xY|RzcX98Pd$_|=S*0qtXBH@{a79-(v%u=a^y!RH zokQlB36E3rXPat9i-CeYo@GNO0Pol|?eD<OT!g^#kMo(+RYQqB^P3JgtbI#7jj(kt z>q&>zCt0D;wlV_t8T~OJ5)>-&Iz?*mBrXWogcYuPg;GIoa}LJxKJb~|$`((e>-`d= zMV(j`&>&BS|LK<jy^Z!vGU|J$w?0xtw)OYL+;~B8JJ2fQ@b&V8np2b&9|L?s+XM+) zq5Q~SoVGLkLN>?Kl{=*6We8=$YDhmea;C|hmNg?3p#P$9E6t>EWu-XioZLzrb%Z0s z6UQt!EQSv+YVX>3P;b$k*i+Y?InCX?^?)5;XT{lzoKFMMeAy7twxXwOdbur&=C>Vi zAhE*8q1Z*x3nBgYzBMlf$}3;OqjXQLf5W3j#iyjWQV$u*ljW1OB2P_BPK6s;&W@`; z>NQM#r$4~(%?KgIqU0Pq>VHbo&q8{Wj2F07ffDnmPcjt^f4N?elQbVJnREuafSAbY zBW=FkXWnNKCM2xBzL1wTiEVoI3k#=Jc{24c7nb2?2dg=5eRsHh=Gk=ex4c-7R>kyo PTJZmy?0;?eVCjDVRon>g diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 349d730..33e6c3d 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -67,7 +67,6 @@ <string name="settings_gesture_time">Uhr</string> <string name="settings_gesture_description_time">Auf die Uhrzeit klicken</string> <string name="settings_apps_choose">App wählen</string> - <string name="settings_apps_view_all">Alle Anwendungen</string> <string name="settings_apps_install">Apps installieren</string> <string name="settings_apps_toast_store_not_found">Store nicht gefunden</string> <!-- @@ -94,10 +93,8 @@ <string name="settings_theme_color_theme_item_dark">Dunkel</string> <string name="settings_theme_color_theme_item_light">Hell</string> <string name="settings_theme_wallpaper">Hintergrund auswählen</string> - <string name="settings_launcher_change_wallpaper">Hintergrund ändern</string> <string name="settings_launcher_section_display">Bildschirm</string> <string name="settings_display_screen_timeout_disabled">Bildschirm nicht ausschalten</string> - <string name="settings_display_full_screen">Vollbild</string> <string name="settings_display_rotate_screen">Bildschirm drehen</string> <string name="settings_launcher_section_functionality">Funktionalität</string> <string name="settings_enabled_gestures_double_swipe">Doppelte Wischaktionen</string> @@ -118,7 +115,6 @@ <string name="settings_list_layout_item_grid">Raster</string> <string name="settings_general_choose_home_screen">Launcher wählen</string> <string name="settings_meta_cant_select_launcher">App Info</string> - <string name="settings_meta_cant_select_launcher_msg">Das Gerät unterstützt diese Funktion nicht. Stattdessen die App Details bearbeiten?</string> <string name="settings_meta_show_tutorial">Zum Tutorial</string> <string name="settings_meta_reset">Einstellungen zurücksetzen</string> <string name="settings_meta_reset_confirm">Alle Einstellungen gehen verloren. Weitermachen?</string> @@ -145,8 +141,6 @@ <string name="list_app_info">App Info</string> <string name="list_app_hidden_remove">Sichtbar machen</string> <string name="list_app_rename">Umbenennen</string> - <string name="list_removed">Die App wurde entfernt</string> - <string name="list_not_removed">Die App konnte nicht entfernt werden</string> <string name="list_apps_search_hint">Anwendungen suchen</string> <string name="list_apps_search_hint_no_auto_launch">Suchen (kein Schnellstart)</string> <string name="list_other_settings">µLauncher Einstellungen</string> diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index f0a80c6..dd2f9e2 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -46,7 +46,6 @@ <string name="settings_gesture_date">Toca la fecha</string> <string name="settings_gesture_time">Toca el reloj</string> <string name="settings_apps_choose">Elegir Aplicación</string> - <string name="settings_apps_view_all">Todas las aplicaciones</string> <string name="settings_apps_install">Instalar aplicaciones</string> <string name="settings_apps_toast_store_not_found">No se encontró la Store</string> <!-- @@ -60,10 +59,8 @@ <string name="settings_theme_color_theme_item_dark">Oscuro</string> <string name="settings_theme_color_theme_item_light">Luminoso</string> <string name="settings_theme_wallpaper">Seleccionar fondo de pantalla</string> - <string name="settings_launcher_change_wallpaper">Cambiar fondo de pantalla</string> <string name="settings_launcher_section_display">Pantalla</string> <string name="settings_display_screen_timeout_disabled">Mantener encendida</string> - <string name="settings_display_full_screen">Pantalla completa</string> <string name="settings_launcher_section_functionality">Funciones</string> <string name="settings_enabled_gestures_double_swipe">Deslizar con dos dedos</string> <string name="settings_functionality_auto_launch">Auto-lanzar búsquedas</string> @@ -76,7 +73,6 @@ --> <string name="settings_general_choose_home_screen">Seleccionar Launcher</string> <string name="settings_meta_cant_select_launcher">Información de la aplicación</string> - <string name="settings_meta_cant_select_launcher_msg">Su dispositivo no posee esta caracrerística. Desea cambiar los detalles de la aplicación?</string> <string name="settings_meta_show_tutorial">Ver tutorial de Launcher</string> <string name="settings_meta_reset">Configuración por defecto</string> <string name="settings_meta_reset_confirm">Todas sus preferencias se eliminarán. Desea continuar?</string> @@ -96,8 +92,6 @@ <string name="list_tab_other">Otros</string> <string name="list_app_delete">Desinstalar</string> <string name="list_app_info">Información</string> - <string name="list_removed">Se eliminó la aplicación</string> - <string name="list_not_removed">No se pudo eliminar la aplicación</string> <string name="list_apps_search_hint">Buscar Aplicaciones</string> <string name="list_other_settings">Configuración de Launcher</string> <string name="list_other_list">Aplicaciones</string> diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 388e089..0487823 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -37,7 +37,6 @@ <string name="settings_gesture_date">Date</string> <string name="settings_gesture_time">Horloge</string> <string name="settings_apps_choose">Choisir une application</string> - <string name="settings_apps_view_all">Voir toutes les applications</string> <string name="settings_apps_install">Installer des applications</string> <string name="settings_apps_toast_store_not_found">Magasin d\'applications introuvable</string> <!-- @@ -52,10 +51,8 @@ <string name="settings_theme_color_theme_item_dark">Sombre</string> <string name="settings_theme_color_theme_item_light">Clair</string> <string name="settings_theme_wallpaper">Choisir un fond d\'écran</string> - <string name="settings_launcher_change_wallpaper">Changer le fond d\'écran</string> <string name="settings_launcher_section_display">Écran</string> <string name="settings_display_screen_timeout_disabled">Garder l\'écran allumé</string> - <string name="settings_display_full_screen">Utiliser le plein écran</string> <string name="settings_launcher_section_functionality">Fonctions</string> <string name="settings_enabled_gestures_double_swipe">Actions de double balayage</string> <string name="settings_functionality_auto_launch">Lancer apps par recherche</string> @@ -68,7 +65,6 @@ --> <string name="settings_general_choose_home_screen">Choisir μLauncher comme application d\'écran d\'accueil par défaut</string> <string name="settings_meta_cant_select_launcher">Informations sur l\'application</string> - <string name="settings_meta_cant_select_launcher_msg">Votre appareil ne prend pas en charge cette fonctionnalité. Souhaitez-vous plutôt accéder aux détails de l\'application ?</string> <string name="settings_meta_show_tutorial">Regarder le tutoriel</string> <string name="settings_meta_reset">Réinitialiser</string> <string name="settings_meta_reset_confirm">Vous allez réinitialiser tous vos paramètres. Souhaitez-vous poursuivre ?</string> @@ -88,8 +84,6 @@ <string name="list_tab_other">Autre</string> <string name="list_app_delete">Désinstaller</string> <string name="list_app_info">Informations</string> - <string name="list_removed">Application supprimée</string> - <string name="list_not_removed">Impossible de désinstaller l\'application</string> <string name="list_apps_search_hint">Chercher des applications</string> <string name="list_other_settings">Réglages d\'µLauncher</string> <string name="list_other_list">Toutes les Applications</string> diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 320bfc6..5a4b16a 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -34,7 +34,6 @@ <br/><br/><br/><br/> Puoi cambiare le tue scelte in seguito nelle impostazioni. ]]></string> - <string name="settings_meta_cant_select_launcher_msg">Il tuo dispositivo non supporta questa funzione. Vuoi aprire la pagina di dettaglio dell\'applicazione?</string> <string name="alert_cant_open_title">Impossibile aprire l\'applicazione</string> <string name="alert_cant_open_message">Desideri modificare le impostazioni?</string> <string name="toast_cant_open_message">Apri le impostazioni per abbinare un\'azione a questo gesto</string> @@ -83,7 +82,6 @@ <string name="settings_gesture_description_vol_up">Premi il pulsante di aumento del volume</string> <string name="settings_gesture_vol_down">Riduci il volume</string> <string name="settings_gesture_description_vol_down">Premi il pulsante per ridurre il volume</string> - <string name="settings_apps_view_all">Vedi tutte le applicazioni</string> <string name="settings_apps_install">Installa le applicazioni</string> <string name="settings_theme_monochrome_icons">Icone monocromatiche</string> <string name="settings_clock_time_visible">Mostra l\'ora</string> @@ -112,10 +110,8 @@ <string name="settings_theme_font">Font</string> <string name="settings_clock_flip_date_time">Inverti data e ora</string> <string name="settings_theme_wallpaper">Scegli uno sfondo</string> - <string name="settings_launcher_change_wallpaper">Cambia immagine di sfondo</string> <string name="settings_launcher_section_display">Schermo</string> <string name="settings_display_screen_timeout_disabled">Mantieni lo schermo acceso</string> - <string name="settings_display_full_screen">Schermo intero</string> <string name="settings_display_rotate_screen">Ruota lo schermo</string> <string name="settings_launcher_section_functionality">Funzionalità</string> <string name="settings_functionality_auto_keyboard">Apri automaticamente la tastiera per cercare</string> @@ -181,7 +177,6 @@ <string name="list_app_hidden_add">Nascondi</string> <string name="list_app_hidden_remove">Mostra</string> <string name="list_app_rename">Rinomina</string> - <string name="list_removed">Le applicazioni selezionate sono state rimosse</string> <string name="list_apps_search_hint">Cerca</string> <string name="list_other_settings">Impostazioni μLauncher</string> <string name="list_other_expand_notifications_panel">Espandi il pannello notifiche</string> @@ -197,7 +192,6 @@ <string name="alert_requires_android_m">Questa funzione richiede Android 6 o successivi.</string> <string name="dialog_rename_ok">Ok</string> <string name="dialog_rename_title">Rinomina %1$s</string> - <string name="list_not_removed">Impossibile rimuovere l\'applicazione</string> <string name="settings_theme_color_theme_item_dynamic">Dinamico</string> <string name="settings_clock_color">Colore</string> <string name="settings_gesture_double_up">Due dita verso l\'alto</string> diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 6a6149c..9a0544f 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -45,7 +45,6 @@ <string name="settings_gesture_date">Data</string> <string name="settings_gesture_time">Hora</string> <string name="settings_apps_choose">Selecione um app</string> - <string name="settings_apps_view_all">Ver todos os apps</string> <string name="settings_apps_install">Instalar aplicativos</string> <string name="settings_apps_toast_store_not_found">Loja não encontrada</string> <!-- @@ -63,10 +62,8 @@ <string name="settings_clock_localized">Use formato de data localizado</string> <string name="settings_clock_flip_date_time">Inverter data e hora</string> <string name="settings_theme_wallpaper">Escolha papel de parede</string> - <string name="settings_launcher_change_wallpaper">Alterar papel de parede</string> <string name="settings_launcher_section_display">Exibição</string> <string name="settings_display_screen_timeout_disabled">Manter a tela ligada</string> - <string name="settings_display_full_screen">Usar tela cheia</string> <string name="settings_launcher_section_functionality">Funcionalidades</string> <string name="settings_enabled_gestures_double_swipe">Gestos com 2 dedos</string> <string name="settings_enabled_gestures_edge_swipe">Ações de deslize nas bordas</string> @@ -80,7 +77,6 @@ --> <string name="settings_general_choose_home_screen">Definir o μLauncher como tela inicial</string> <string name="settings_meta_cant_select_launcher">Informações do aplicativo</string> - <string name="settings_meta_cant_select_launcher_msg">Seu dispositivo não é compatível com esse recurso. Gerenciar detalhes do app em vez disso?</string> <string name="settings_meta_show_tutorial">Ver tutorial do launcher</string> <string name="settings_meta_reset">Redefinir configuraçãos</string> <string name="settings_meta_reset_confirm">Você vai descartar todas as suas preferências. Continuar?</string> @@ -100,8 +96,6 @@ <string name="list_tab_other">Outros</string> <string name="list_app_delete">Desinstalar</string> <string name="list_app_info">Informações do aplicativo</string> - <string name="list_removed">O app selecionado foi removido</string> - <string name="list_not_removed">Não foi possível remover o app</string> <string name="list_apps_search_hint">Busque</string> <string name="list_other_settings">Configurações do µLauncher</string> <string name="list_other_list">Todos os apps</string> diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index bfd0cfe..e6fc115 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -105,7 +105,6 @@ <string name="settings_gesture_time">Saat</string> <string name="settings_gesture_description_time">Saate tıklayın</string> <string name="settings_apps_choose">Uygulama Seçin</string> - <string name="settings_apps_view_all">Tüm uygulamaları göster</string> <string name="settings_apps_install">Uygulamaları yükle</string> <string name="settings_apps_toast_store_not_found">Mağaza bulunamadı</string> <string name="settings_launcher_section_appearance">Görünüş</string> @@ -120,8 +119,6 @@ <string name="list_other_nop">Hiçbir şey yapma</string> <string name="settings_meta_view_code">Kaynak kodunu göster</string> <string name="settings_meta_report_bug">Hatayı bildirin</string> - <string name="list_removed">Seçilen uygulama kaldırıldı</string> - <string name="list_not_removed">Uygulama kaldırılamadı</string> <string name="list_apps_search_hint">Uygulamaları Ara</string> <string name="list_other_list">Tüm Uygulamalar</string> <string name="list_other_list_favorites">Favori Uygulamalar</string> @@ -134,10 +131,8 @@ <string name="settings_clock_show_seconds">Saniyeleri gösteri</string> <string name="settings_clock_flip_date_time">Tarih ile zamanı yer değiştir</string> <string name="settings_theme_wallpaper">Duvar kağıdı seç</string> - <string name="settings_launcher_change_wallpaper">Duvar kağıdını değiştir</string> <string name="settings_launcher_section_display">Ekran</string> <string name="settings_display_screen_timeout_disabled">Ekranı açık tut</string> - <string name="settings_display_full_screen">Tam ekran kullan</string> <string name="settings_display_rotate_screen">Ekranı döndür</string> <string name="settings_launcher_section_functionality">İşlevsellik</string> <string name="settings_enabled_gestures_edge_swipe_summary">Ekranın köşesinden kaydırın</string> @@ -165,7 +160,6 @@ <string name="settings_list_layout_item_text">Metin</string> <string name="settings_list_layout_item_grid">Izgara</string> <string name="settings_meta_cant_select_launcher">Uygulama Detayı</string> - <string name="settings_meta_cant_select_launcher_msg">Sizin cihazınız bu özelliği desteklemiyor. Onun yerine uygulama detaylarını düzenleyin?</string> <string name="settings_meta_reset">Ayarları Sıfırlayın</string> <string name="settings_meta_reset_confirm">Tüm tercihlerinizi bir kenara bırakacaksınız. Devam mı?</string> <string name="settings_theme_font_item_monospace">Tek uzay</string> diff --git a/app/src/main/res/values-w820dp/dimens.xml b/app/src/main/res/values-w820dp/dimens.xml deleted file mode 100644 index 63fc816..0000000 --- a/app/src/main/res/values-w820dp/dimens.xml +++ /dev/null @@ -1,6 +0,0 @@ -<resources> - <!-- Example customization of dimensions originally defined in res/values/dimens.xml - (such as screen margins) for screens with more than 820dp of available width. This - would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). --> - <dimen name="activity_horizontal_margin">64dp</dimen> -</resources> diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 793ef9d..07b411d 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -37,21 +37,17 @@ <string name="settings_gesture_date">日期</string> <string name="settings_gesture_time">时间</string> <string name="settings_apps_choose">选择应用</string> - <string name="settings_apps_view_all">浏览全部应用</string> <string name="settings_apps_install">安装应用</string> <string name="settings_apps_toast_store_not_found">没有找到应用市场</string> <string name="settings_launcher_section_date_time"><![CDATA[日期和时间]]></string> <string name="settings_theme_wallpaper">选择一个壁纸</string> - <string name="settings_launcher_change_wallpaper">换壁纸</string> <string name="settings_display_screen_timeout_disabled">保持屏幕常亮</string> - <string name="settings_display_full_screen">使用全屏</string> <string name="settings_launcher_section_functionality">功能</string> <string name="settings_enabled_gestures_edge_swipe">边缘滑动动作</string> <string name="settings_functionality_auto_launch">零点击启动唯一搜索结果</string> <string name="settings_functionality_auto_keyboard">搜索时呼出键盘</string> <string name="settings_launcher_sensitivity">灵敏度</string> <string name="settings_meta_cant_select_launcher">应用信息</string> - <string name="settings_meta_cant_select_launcher_msg">您的设备不支持此功能。要不打开应用程序详细?</string> <string name="settings_meta_show_tutorial">查看启动器教程</string> <string name="settings_meta_reset">重置设置</string> <string name="settings_meta_reset_confirm">你将放弃你所有的配置。继续吗?</string> @@ -74,8 +70,6 @@ <string name="list_tab_app">应用</string> <string name="list_app_delete">卸载</string> <string name="list_app_info">应用信息</string> - <string name="list_not_removed">无法移除应用</string> - <string name="list_removed">移除了选定的应用</string> <string name="list_apps_search_hint">搜索</string> <string name="list_other_settings">启动器设置</string> <string name="list_other_list">全部应用</string> diff --git a/app/src/main/res/values/ic_launcher_background.xml b/app/src/main/res/values/ic_launcher_background.xml deleted file mode 100644 index beab31f..0000000 --- a/app/src/main/res/values/ic_launcher_background.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <color name="ic_launcher_background">#000000</color> -</resources> \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b94a92b..6205281 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -101,8 +101,6 @@ <string name="settings_apps_choose">Choose App</string> - <string name="settings_apps_view_all">View all apps</string> - <string name="settings_apps_install">Install apps</string> <string name="settings_apps_toast_store_not_found">Store not found</string> @@ -148,7 +146,6 @@ <string name="settings_clock_flip_date_time">Flip date and time</string> <string name="settings_theme_wallpaper">Choose a wallpaper</string> - <string name="settings_launcher_change_wallpaper">Change wallpaper</string> <string name="settings_launcher_section_display">Display</string> @@ -240,9 +237,6 @@ <string name="list_app_hidden_remove">Show</string> <string name="list_app_rename">Rename</string> - <string name="list_removed">Removed the selected application</string> - <string name="list_not_removed">Unable to remove application</string> - <string name="list_apps_search_hint">Search</string> <string name="list_apps_search_hint_no_auto_launch">Search (no auto launch)</string> @@ -265,7 +259,6 @@ <!-- Pin shortcuts --> <string name="pin_shortcut_title">Add Shortcut</string> <string name="pin_shortcut_button_bind">Bind to gesture</string> - <string name="pin_shortcut_button_ok">Ok</string> <string name="pin_shortcut_switch_visible">Show in app list</string> <!-- @@ -361,13 +354,11 @@ <string name="screen_lock_method_use_accessibility">Use Accessibility Service</string> <string name="screen_lock_method_use_device_admin">Use Device Admin</string> <string name="settings_actions_lock_method">Choose method for locking the screen</string> - <string name="dialog_rename_ok">Ok</string> <string name="dialog_rename_title">Rename %1$s</string> <string name="dialog_select_color_red">Red</string> <string name="dialog_select_color_alpha">Alpha</string> <string name="dialog_select_color_blue">Blue</string> <string name="dialog_select_color_green">Green</string> - <string name="dialog_select_color_ok">Ok</string> <string name="dialog_select_color_color_hex">Color</string> <string name="dialog_choose_color_title">Choose color</string> <string name="dialog_consent_accessibility_privileges">I am aware that this will grant far-reaching privileges to μLauncher.</string> diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 5ca2a9e..20ccb67 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -105,17 +105,6 @@ <item name="android:fontFamily">serif</item> </style> - <style name="textColorWhite"> - <item name="android:textColor">@color/finnmglasTheme_text_color</item> - </style> - - <style name="textColorWhiteAndShadow"> - <item name="android:textColor">@color/finnmglasTheme_text_color</item> - </style> - <style name="textColorBlack"> - <item name="android:textColor">#000</item> - </style> - <style name="PopupMenuCustom" parent="@android:style/Widget.PopupMenu" tools:keep="@style/PopupMenuCustom"> <item name="android:popupBackground">#252827</item> </style> diff --git a/docs/launcher.md b/docs/launcher.md index 37b24a4..cb290a0 100644 --- a/docs/launcher.md +++ b/docs/launcher.md @@ -47,3 +47,4 @@ The complete list of changes can be viewed [here](https://github.com/jrpie/launc --- [original-repo]: https://github.com/finnmglas/Launcher + [hack-font]: https://sourcefoundry.org/hack/ diff --git a/gradle.properties b/gradle.properties index 519dc7f..4093087 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,6 +19,6 @@ android.useAndroidX=true android.enableJetifier=true # Kotlin code style for this project: "official" or "obsolete": kotlin.code.style=official -android.nonTransitiveRClass=false -android.nonFinalResIds=false +android.nonTransitiveRClass=true +android.nonFinalResIds=true org.gradle.configuration-cache=true From c783a516585e0f28578623114c30ca8c39fe3862 Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Sun, 16 Mar 2025 16:52:46 +0100 Subject: [PATCH 36/73] upgrade AGP --- app/build.gradle | 4 ++-- build.gradle | 4 ++-- gradle/wrapper/gradle-wrapper.properties | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 8e6f551..2ca3729 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -85,11 +85,11 @@ android { // Disables dependency metadata when building Android App Bundles. includeInBundle = false } - - lintOptions { + lint { abortOnError false } + } dependencies { diff --git a/build.gradle b/build.gradle index 1697c36..2bb501f 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ buildscript { ext.kotlin_version = '2.0.0' - ext.android_plugin_version = '8.8.1' + ext.android_plugin_version = '8.9.0' repositories { google() mavenCentral() @@ -10,7 +10,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:8.8.1' + classpath 'com.android.tools.build:gradle:8.9.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "com.android.tools.build:gradle:$android_plugin_version" classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version" diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index df97d72..e2847c8 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From 00350d4c3a694349df06535d57339ba5be2d3df5 Mon Sep 17 00:00:00 2001 From: Josia <git@jrpie.de> Date: Sun, 16 Mar 2025 16:16:58 +0000 Subject: [PATCH 37/73] Translated using Weblate (German) Currently translated at 92.7% (242 of 261 strings) Translation: jrpie-Launcher/Launcher Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/de/ --- app/src/main/res/values-de/strings.xml | 46 ++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 33e6c3d..2a45fb9 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -273,4 +273,50 @@ <string name="dialog_consent_accessibility_consent">Ich willige ein, dass µLauncher eine Bedienungshilfe für Zwecke verwendet, die nicht unter Barrierefreiheit fallen.</string> <string name="dialog_consent_accessibility_data_collection">Ich willige ein, dass µLauncher keine Daten sammelt.</string> <string name="dialog_consent_accessibility_title">Bedienungshilfe aktivieren</string> + <string name="dialog_report_bug_info">Danke für die Mithilfe, μLauncher zu verbessern!\nEs wird darum gebeten, Bug Reports die folgenden Informationen anzufügen, um diese besser nachvollziehen zu können:</string> + <string name="settings_gesture_back">Zurück</string> + <string name="settings_gesture_description_back">Zurück-Taste oder -Geste</string> + <string name="settings_gesture_swipe_larger_reverse"><![CDATA[> (Rückwärts)]]></string> + <string name="settings_gesture_description_swipe_larger_reverse">Unten links -> mitte rechts -> oben links</string> + <string name="settings_gesture_swipe_smaller"><![CDATA[<]]></string> + <string name="settings_gesture_swipe_smaller_reverse"><![CDATA[< (Rückwärts)]]></string> + <string name="settings_gesture_swipe_v">V</string> + <string name="settings_gesture_description_swipe_v">Oben links -> unten mitte -> oben rechts</string> + <string name="settings_gesture_swipe_v_reverse">V (Rückwärts)</string> + <string name="settings_gesture_description_swipe_smaller_reverse">Unten rechts -> mitte links -> oben rechts</string> + <string name="settings_gesture_swipe_lambda">Λ</string> + <string name="settings_gesture_description_swipe_lambda">Unten links -> oben mitte -> unten rechts</string> + <string name="settings_gesture_description_swipe_v_reverse">Oben rechts -> unten mitte -> oben links</string> + <string name="settings_gesture_swipe_lambda_reverse">Λ (Rückwärts)</string> + <string name="settings_gesture_description_swipe_lambda_reverse">Unten rechts -> oben mtte -> unten links</string> + <string name="dialog_report_bug_button_security">Sicherheitslücke melden</string> + <string name="settings_apps_hide_private_space_apps">Privaten Bereich nicht in der App Liste anzeigen</string> + <string name="list_title_private_space">Privater Bereich</string> + <string name="pin_shortcut_title">Shortcut hinzufügen</string> + <string name="pin_shortcut_button_bind">An Geste binden</string> + <string name="pin_shortcut_switch_visible">In Appliste anzeigen</string> + <string name="tooltip_unlock_private_space">Privaten Bereich entsperren</string> + <string name="settings_display_hide_status_bar">Statusleiste verstecken</string> + <string name="settings_display_hide_navigation_bar">Navigationsleiste verstecken</string> + <string name="tooltip_lock_private_space">Privaten Bereich sperren</string> + <string name="tutorial_concept_label_version">Version</string> + <string name="tutorial_app_list_title">Alle Apps</string> + <string name="tutorial_app_list_text_2">Sobald nur noch eine App passt, wird diese automatisch gestartet.\nDas lässt sich unterdrücken, indem der Suche ein Leerzeichen vorangestellt wird.</string> + <string name="settings_gesture_swipe_larger"><![CDATA[>]]></string> + <string name="settings_gesture_description_swipe_smaller">Oben rechts -> mitte links -> unten rechts</string> + <string name="settings_gesture_description_swipe_larger">Oben links -> mitte rechts -> unten links</string> + <string name="tutorial_app_list_text">In der Appliste kann effizient nach Apps gesucht werden.\n\nDie Liste wird standardmäßig durch Wischen nach oben geöffnet (auch das lässt sich einstellen).</string> + <string name="dialog_consent_accessibility_text"><![CDATA[Das Aktivieren der Bedienungshilfe erteilt μLauncher <strong>weitreichende Zugriffsrechte</strong> .<br/>μLauncher wird diese <strong>ausschließlich zum Sperren des Bildschirms</strong> verwenden. μLauncher wird <strong>niemals irgendwelche Daten sammeln</strong>. Insbesondere werden mittels der Bedienungshilfe keine Daten gesammelt.]]></string> + <string name="settings_gesture_tap_up">Tippen und hoch</string> + <string name="settings_gesture_description_tap_up">Tippen, dann nach oben wischen</string> + <string name="settings_gesture_tap_down">Tippen und nach unten</string> + <string name="settings_gesture_description_tap_down">Tippen, dann nach unten wischen</string> + <string name="settings_gesture_tap_left">Tippen und links</string> + <string name="settings_gesture_description_tap_left">Tippen, dann nach links wischen</string> + <string name="settings_gesture_tap_right">Tippen und rechts</string> + <string name="settings_gesture_description_tap_right">Tippen, dann nach rechts wischen</string> + <string name="dialog_report_bug_security_info">Sicherheitslücken bitte nicht öffentlich bei GitHub melden, sondern auf dem folgenden Weg:</string> + <string name="list_other_list_private_space">Privater Bereich</string> + <string name="list_other_track_play_pause">Musik: Wiedergabe / Pause</string> + <string name="settings_list_reverse_layout">Appliste umkehren</string> </resources> From 3cec2c36c6688100ef9716fc2b9b0181dced8ad7 Mon Sep 17 00:00:00 2001 From: Anonymous <toolate@othing.xyz> Date: Sun, 16 Mar 2025 00:07:19 +0000 Subject: [PATCH 38/73] Translated using Weblate (German) Currently translated at 92.7% (242 of 261 strings) Translation: jrpie-Launcher/Launcher Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/de/ --- app/src/main/res/values-de/strings.xml | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 2a45fb9..edbecfa 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -206,15 +206,7 @@ <string name="screen_lock_method_dialog_title">Methode zum Sperren wählen</string> <string name="screen_lock_method_use_accessibility">Bedienungshilfe verwenden</string> <string name="screen_lock_method_use_device_admin">Geräteadministrator verwenden</string> - <string name="accessibility_service_description"> - µLauncher als Bedienungshilfe zu aktivieren ermöglicht es µLauncher, den Bildschirm zu sperren. - Achtung: Hierfür sind weitgehende Berechtigungen erforderlich. - Solche Berechtigungen sollten niemals leichtfertig vergeben werden. - µLauncher wird diese Berechtigungen ausschließlich zum Sperren des Bildschirms verwenden. - - Alternativ kann der Bildschirm auch mithilfe von Geräteadministratorberechtigungen gesperrt werden. - Dann ist jedoch ein Entsperren mit Fingerabdruck oder Gesichtserkennung nicht möglich. - </string> + <string name="accessibility_service_description">µLauncher als Bedienungshilfe zu aktivieren ermöglicht es µLauncher, den Bildschirm zu sperren. Achtung: Hierfür sind weitgehende Berechtigungen erforderlich. Solche Berechtigungen sollten niemals leichtfertig vergeben werden. µLauncher wird diese Berechtigungen ausschließlich zum Sperren des Bildschirms verwenden. Alternativ kann der Bildschirm auch mithilfe von Geräteadministratorberechtigungen gesperrt werden. Dann ist jedoch ein Entsperren mit Fingerabdruck oder Gesichtserkennung nicht möglich.</string> <string name="screen_lock_method_dialog_text"><![CDATA[ <h1>Methode zum Sperren auswählen</h1> Es gibt zwei Möglichkeiten, wie µLauncher den Bildschirm sperren kann. From 65034bf2fb3dd977dfcb878b639aed40739149af Mon Sep 17 00:00:00 2001 From: toolatebot <toolate@othing.xyz> Date: Sun, 16 Mar 2025 16:28:08 +0000 Subject: [PATCH 39/73] Update translation files Updated by "Cleanup translation files" add-on in Weblate. Translation: jrpie-Launcher/Launcher Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/ --- app/src/main/res/values-de/strings.xml | 2 -- app/src/main/res/values-fr/strings.xml | 2 -- app/src/main/res/values-it/strings.xml | 2 -- app/src/main/res/values-ja/strings.xml | 4 ---- app/src/main/res/values-pt-rBR/strings.xml | 3 --- app/src/main/res/values-tr/strings.xml | 2 -- app/src/main/res/values-zh-rCN/strings.xml | 2 -- 7 files changed, 17 deletions(-) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index edbecfa..b4c3ad6 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -196,7 +196,6 @@ <string name="alert_no_torch_found">Es wurde keine geeignete Kamera gefunden.</string> <string name="alert_torch_access_exception">Fehler: Kein Zugriff auf die Kamera möglich.</string> <string name="settings_actions_lock_method">Methode zum Sperren des Bildschirms wählen</string> - <string name="dialog_rename_ok">Ok</string> <string name="dialog_rename_title">%1$s umbenennen</string> <string name="toast_private_space_default_home_screen">µLauncher muss als Standardlauncher eingerichtet sein um auf den privaten Bereich zugreifen zu können.</string> <string name="toast_lock_screen_not_supported">Fehler: Auf diesem Gerät kann der Bildschirm nicht mittels Bedienungshilfe gesperrt werden. Bitte stattdessen Geräteadministrator verwenden.</string> @@ -253,7 +252,6 @@ <string name="dialog_select_color_alpha">Transparenz</string> <string name="dialog_select_color_blue">Blau</string> <string name="dialog_select_color_green">Grün</string> - <string name="dialog_select_color_ok">Ok</string> <string name="dialog_select_color_color_hex">Farbe</string> <string name="dialog_choose_color_title">Farbe wählen</string> <string name="settings_meta_licenses">Open Source Lizenzen</string> diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 6109094..e84d6ae 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -169,7 +169,6 @@ <string name="dialog_consent_accessibility_privileges">Je suis conscient que cela accordera des privilèges importants à µLauncher.</string> <string name="dialog_choose_color_title">Choisir une couleur</string> <string name="dialog_consent_accessibility_title">Activation du service d\'accessibilité</string> - <string name="dialog_select_color_ok">Ok</string> <string name="dialog_select_color_color_hex">Couleur</string> <string name="dialog_consent_accessibility_consent">Je consent à µLauncher utilisation du service d’accessibilité pour fournir une fonction non liée à l’accessibilité.</string> <string name="dialog_consent_accessibility_data_collection">Je consent à la non-collecte de données par µLauncher.</string> @@ -216,7 +215,6 @@ <string name="settings_theme_background_item_solid">Plein</string> <string name="dialog_rename_title">Renommer %1$s</string> <string name="screen_lock_method_use_accessibility">Utiliser le service d’accessibilité</string> - <string name="dialog_rename_ok">Ok</string> <string name="settings_functionality_search_web">Chercher sur le web</string> <string name="settings_functionality_search_web_summary">Appuyer sur entrée en cherchant une application pour lancer une recherche web.</string> <string name="dialog_cancel">Annuler</string> diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 1a9445d..a01b8e7 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -190,7 +190,6 @@ <string name="tutorial_usage_title">Utilizzo</string> <string name="tutorial_usage_text">La schermata principale contiene solo data e ora. Nessuna distrazione.</string> <string name="alert_requires_android_m">Questa funzione richiede Android 6 o successivi.</string> - <string name="dialog_rename_ok">Ok</string> <string name="dialog_rename_title">Rinomina %1$s</string> <string name="settings_theme_color_theme_item_dynamic">Dinamico</string> <string name="settings_clock_color">Colore</string> @@ -205,7 +204,6 @@ <string name="dialog_select_color_alpha">Trasparente</string> <string name="dialog_select_color_blue">Blu</string> <string name="dialog_select_color_green">Verde</string> - <string name="dialog_select_color_ok">Ok</string> <string name="dialog_select_color_color_hex">Colore</string> <string name="dialog_choose_color_title">Scegli colore</string> <string name="dialog_consent_accessibility_ok">Attiva Servizi di Accessibilità</string> diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index c453380..050d750 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -89,7 +89,6 @@ <string name="settings_clock_show_seconds">秒を表示</string> <string name="settings_clock_flip_date_time">日付と時刻を反転</string> <string name="settings_theme_wallpaper">壁紙を選択</string> - <string name="settings_launcher_change_wallpaper">壁紙を変更</string> <string name="settings_launcher_section_display">表示</string> <string name="settings_display_screen_timeout_disabled">画面オンを維持</string> <string name="settings_display_rotate_screen">画面の回転</string> @@ -129,7 +128,6 @@ <string name="list_app_favorite_remove">お気に入りから削除</string> <string name="list_app_hidden_add">隠す</string> <string name="list_app_rename">名称を変更</string> - <string name="list_not_removed">アプリを削除できませんでした</string> <string name="list_apps_search_hint">検索</string> <string name="list_apps_search_hint_no_auto_launch">検索(自動起動なし)</string> <string name="list_other_settings">µLauncherの設定</string> @@ -145,7 +143,6 @@ <string name="list_other_torch">ライトを切り替え</string> <string name="pin_shortcut_title">ショートカットを追加</string> <string name="pin_shortcut_button_bind">ジェシュチャーに設定</string> - <string name="pin_shortcut_button_ok">Ok</string> <string name="pin_shortcut_switch_visible">アプリ一覧に表示</string> <string name="tutorial_title">チュートリアル</string> <string name="tutorial_concept_title">コンセプト</string> @@ -170,7 +167,6 @@ <string name="settings_gesture_description_up_left_edge">画面の左端で上にスワイプ</string> <string name="settings_gesture_description_down_right_edge">画面の右端で下にスワイプ</string> <string name="settings_apps_install">アプリをインストール</string> - <string name="list_removed">選択されたアプリを削除しました</string> <string name="tutorial_finish_text">始める準備はできました!これがあなたにとって大きな価値となることを願っています! \t- Finn(Launcherの作成者)とJosia(いくつかの改良を行い、フォーク μLauncher を保守)</string> <string name="settings_gesture_tap_right">Tap + Right</string> <string name="settings_gesture_description_double_right">2本指で右にスワイプ</string> diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 9a0544f..f0c0295 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -226,7 +226,6 @@ <string name="settings_list_layout_item_text">Texto</string> <string name="settings_list_layout_item_grid">Grade</string> <string name="list_app_rename">Renomear</string> - <string name="dialog_rename_ok">beleza</string> <string name="dialog_rename_title">Renomear %1$s</string> <string name="settings_theme_font_item_serif_monospace">Serif monospace</string> <string name="settings_theme_font_item_serif">Serif</string> @@ -244,7 +243,6 @@ <string name="dialog_consent_accessibility_ok">Ativar o Serviço de acessibilidade</string> <string name="dialog_cancel">Cancelar</string> <string name="dialog_consent_accessibility_text"><![CDATA[Você está prestes a ativar o Serviço de acessibilidade. Isto concederá <strong>permissões elevadas</strong> ao µLauncher.<br/>µLauncher usará estas permissões <strong>apenas para bloquear a tela</strong>. µLauncher <strong>nunca coletará nenhum dado</strong>. Sobretudo, o µLauncher não implementa o Serviço de acessibilidade para coletar dados.]]></string> - <string name="dialog_select_color_ok">beleza</string> <string name="dialog_consent_accessibility_privileges">Estou ciente de que isto concederá permissões elevadas ao µLauncher.</string> <string name="dialog_consent_accessibility_other_options">Estou ciente de que existem outras opções (permissões de Administrador do aparelho ou o botão de ligar).</string> <string name="settings_functionality_search_web">Pesquise na internet</string> @@ -304,5 +302,4 @@ <string name="settings_gesture_description_swipe_smaller_reverse">Canto inferior direito -> centro esquerdo -> canto superior direito</string> <string name="settings_gesture_description_swipe_lambda_reverse">Inferior direito -> superior médio -> inferior esquerdo</string> <string name="settings_list_reverse_layout">Lista de apps inversa</string> - <string name="pin_shortcut_button_ok">Ok</string> </resources> diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 320ea10..0cc240e 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -192,7 +192,6 @@ <string name="alert_torch_access_exception">Hata: Fenere erişilemiyor.</string> <string name="settings_actions_lock_method">Ekranı kilitleme yöntemini seçin</string> <string name="dialog_cancel">İptal</string> - <string name="dialog_rename_ok">OK</string> <string name="dialog_rename_title">Yeniden Adlandır %1$s</string> <string name="settings_theme_color_theme_item_dynamic">Dinamik</string> <string name="settings_clock_color">Renk</string> @@ -200,7 +199,6 @@ <string name="dialog_select_color_alpha">Alfa</string> <string name="dialog_select_color_blue">Mavi</string> <string name="dialog_select_color_green">Yeşil</string> - <string name="dialog_select_color_ok">OK</string> <string name="dialog_select_color_color_hex">Renk</string> <string name="dialog_choose_color_title">Renk seçin</string> </resources> diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 2e1a221..873ba6a 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -143,7 +143,6 @@ <string name="list_other_lock_screen">锁屏</string> <string name="settings_theme_text_shadow">文本阴影</string> <string name="settings_enabled_gestures_double_swipe_summary">双指滑动</string> - <string name="dialog_rename_ok">确定</string> <string name="dialog_rename_title">重命名 %1$s</string> <string name="settings_theme_color_theme_item_default">默认</string> <string name="settings_theme_color_theme_item_dark">深色</string> @@ -174,7 +173,6 @@ <string name="dialog_select_color_blue">蓝色</string> <string name="dialog_select_color_alpha">透明度</string> <string name="dialog_select_color_green">绿色</string> - <string name="dialog_select_color_ok">确定</string> <string name="settings_theme_color_theme_item_dynamic">动态</string> <string name="list_title_private_space">私人空间</string> <string name="list_other_list_private_space">私人空间</string> From 008d0242ee4a39fec4021cd77a3094771722d214 Mon Sep 17 00:00:00 2001 From: Josia <git@jrpie.de> Date: Sun, 16 Mar 2025 16:28:18 +0000 Subject: [PATCH 40/73] Translated using Weblate (German) Currently translated at 96.8% (246 of 254 strings) Translation: jrpie-Launcher/Launcher Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/de/ --- app/src/main/res/values-de/strings.xml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index b4c3ad6..c45e625 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -102,7 +102,7 @@ <string name="settings_enabled_gestures_edge_swipe">Kantenaktionen</string> <string name="settings_enabled_gestures_edge_swipe_edge_width">Kantenbreite</string> <string name="settings_functionality_auto_launch">Suchergebnis starten</string> - <string name="settings_functionality_search_web_summary">Beim Durchsuchen der Apps Enter drücken um stattdessen im Internet zu suchen</string> + <string name="settings_functionality_search_web_summary">Beim Durchsuchen der Apps Enter drücken, um stattdessen im Internet zu suchen.</string> <string name="settings_functionality_auto_keyboard">Tastatur automatisch öffnen</string> <string name="settings_launcher_sensitivity">Empfindlichkeit</string> <!-- @@ -124,7 +124,7 @@ <string name="settings_meta_contact">Entwickler kontaktieren</string> <string name="dialog_report_bug_create_report">Report erstellen</string> <string name="settings_meta_fork_contact">Entwickler des Fork kontaktieren</string> - <string name="settings_meta_join_chat">Dem µLauncher-Chat beitreten</string> + <string name="settings_meta_join_chat">Dem μLauncher-Chat beitreten</string> <string name="settings_meta_donate">Spenden</string> <string name="settings_meta_privacy">Datenschutzerklärung</string> <!-- @@ -141,9 +141,9 @@ <string name="list_app_info">App Info</string> <string name="list_app_hidden_remove">Sichtbar machen</string> <string name="list_app_rename">Umbenennen</string> - <string name="list_apps_search_hint">Anwendungen suchen</string> + <string name="list_apps_search_hint">Suchen</string> <string name="list_apps_search_hint_no_auto_launch">Suchen (kein Schnellstart)</string> - <string name="list_other_settings">µLauncher Einstellungen</string> + <string name="list_other_settings">μLauncher Einstellungen</string> <string name="list_other_list">Alle Anwendungen</string> <string name="list_other_list_favorites">Favoriten</string> <string name="list_other_toggle_private_space_lock">Privaten Bereich (ent)sperren</string> @@ -160,18 +160,18 @@ --> <string name="list_other_torch">Taschenlampe umschalten</string> <string name="tutorial_title">Tutorial</string> - <string name="tutorial_start_text">Hier eine kurze Erklärung, wie dieser Launcher funktioniert.</string> + <string name="tutorial_start_text">👋\n\nHier eine kurze Erklärung, wie dieser Launcher funktioniert.</string> <string name="tutorial_concept_title">Konzept</string> - <string name="tutorial_concept_text">µLauncher bietet eine minimalistische, effiziente und ablenkungsfreie digitale Umgebung.\n\nDie App ist freie Software, enthält keine Werbung und sammelt keinerlei Daten.</string> + <string name="tutorial_concept_text">µLauncher bietet eine minimalistische, effiziente und ablenkungsfreie Umgebung.\n\nDie App ist freie Software, enthält keine Werbung und sammelt keinerlei Daten.</string> <string name="tutorial_concept_text_2">Der Quellcode ist bei GitHub zu finden.</string> <string name="tutorial_usage_title">Benutzung</string> <string name="tutorial_usage_text">Der Homescreen zeigt nur das Datum und die Uhrzeit. Keine Ablenkung.</string> - <string name="tutorial_usage_text_2">Häufig verwendete Apps können mittels Gesten, z.B. Wischen oder den Lautstärketasten geöffnet werden. Gleich können die Apps ausgewählt werden.</string> + <string name="tutorial_usage_text_2">Häufig verwendete Apps können mittels Gesten, z.B. Wischen oder den Lautstärketasten geöffnet werden.</string> <string name="tutorial_setup_title">Einrichtung</string> <string name="tutorial_setup_text">Es wurden Standardapps ausgewählt, die Zuordnung kann hier angepasst werden:</string> <string name="tutorial_setup_text_2">Die Auswahl kann in den Einstellungen später jederzeit geändert werden.</string> <string name="tutorial_finish_title">Los gehts!</string> - <string name="tutorial_finish_text">Es kann losgehen!\n\nWir hoffen, dass diese App hilfreich ist!\n\n- Finn (der Entwickler)\n\tund Josia (der einige Änderungen vorgenommen hat und den Fork μLauncher entwickelt)</string> + <string name="tutorial_finish_text">Es kann losgehen!\n\nWir hoffen, dass diese App hilfreich ist!\n\n- Finn (der Entwickler)\nund Josia (der einige Änderungen vorgenommen hat und den Fork μLauncher entwickelt)</string> <string name="tutorial_finish_button">Starten</string> <string name="settings">Einstellungen</string> <string name="ic_menu_alt">Mehr Optionen</string> From 7094d55484cd2d52fad806f7e4cfc5557b448074 Mon Sep 17 00:00:00 2001 From: Josia <git@jrpie.de> Date: Mon, 17 Mar 2025 23:42:33 +0000 Subject: [PATCH 41/73] Translated using Weblate (German) Currently translated at 100.0% (254 of 254 strings) Translation: jrpie-Launcher/Launcher Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/de/ --- app/src/main/res/values-de/strings.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index c45e625..735aa9d 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -197,18 +197,18 @@ <string name="alert_torch_access_exception">Fehler: Kein Zugriff auf die Kamera möglich.</string> <string name="settings_actions_lock_method">Methode zum Sperren des Bildschirms wählen</string> <string name="dialog_rename_title">%1$s umbenennen</string> - <string name="toast_private_space_default_home_screen">µLauncher muss als Standardlauncher eingerichtet sein um auf den privaten Bereich zugreifen zu können.</string> + <string name="toast_private_space_default_home_screen">μLauncher muss als Standardlauncher eingerichtet sein um auf den privaten Bereich zugreifen zu können.</string> <string name="toast_lock_screen_not_supported">Fehler: Auf diesem Gerät kann der Bildschirm nicht mittels Bedienungshilfe gesperrt werden. Bitte stattdessen Geräteadministrator verwenden.</string> - <string name="accessibility_service_name">µLauncher - Bildschirm sperren</string> + <string name="accessibility_service_name">μLauncher - Bildschirm sperren</string> <string name="alert_lock_screen_failed">Fehler: Bildschirm konnte nicht gesperrt werden.</string> <string name="toast_accessibility_service_not_enabled">Die Bedienungshilfe ist nicht aktiviert. Bitte in den Einstellungen aktivieren</string> <string name="screen_lock_method_dialog_title">Methode zum Sperren wählen</string> <string name="screen_lock_method_use_accessibility">Bedienungshilfe verwenden</string> <string name="screen_lock_method_use_device_admin">Geräteadministrator verwenden</string> - <string name="accessibility_service_description">µLauncher als Bedienungshilfe zu aktivieren ermöglicht es µLauncher, den Bildschirm zu sperren. Achtung: Hierfür sind weitgehende Berechtigungen erforderlich. Solche Berechtigungen sollten niemals leichtfertig vergeben werden. µLauncher wird diese Berechtigungen ausschließlich zum Sperren des Bildschirms verwenden. Alternativ kann der Bildschirm auch mithilfe von Geräteadministratorberechtigungen gesperrt werden. Dann ist jedoch ein Entsperren mit Fingerabdruck oder Gesichtserkennung nicht möglich.</string> + <string name="accessibility_service_description">μLauncher als Bedienungshilfe zu aktivieren ermöglicht es μLauncher, den Bildschirm zu sperren. Achtung: Hierfür sind weitgehende Berechtigungen erforderlich. Solche Berechtigungen sollten niemals leichtfertig vergeben werden. μLauncher wird diese Berechtigungen ausschließlich zum Sperren des Bildschirms verwenden. Alternativ kann der Bildschirm auch mithilfe von Geräteadministratorberechtigungen gesperrt werden. Dann ist jedoch ein Entsperren mit Fingerabdruck oder Gesichtserkennung nicht möglich.</string> <string name="screen_lock_method_dialog_text"><![CDATA[ <h1>Methode zum Sperren auswählen</h1> - Es gibt zwei Möglichkeiten, wie µLauncher den Bildschirm sperren kann. + Es gibt zwei Möglichkeiten, wie μLauncher den Bildschirm sperren kann. Leider haben beide Nachteile:<br/><br/> @@ -258,9 +258,9 @@ <string name="legal_info_title">Open Source Lizenzen</string> <string name="toast_activity_not_found_search_web">Keine App gefunden um die Suche durchzuführen.</string> <string name="toast_activity_not_found_browser">URL kann nicht geöffnet werden: kein Browser gefunden.</string> - <string name="dialog_consent_accessibility_privileges">Mir ist bewusst, dass µLauncher hierdurch weitreichende Berechtigungen erhält.</string> + <string name="dialog_consent_accessibility_privileges">Mir ist bewusst, dass μLauncher hierdurch weitreichende Berechtigungen erhält.</string> <string name="dialog_consent_accessibility_other_options">Mir ist bewusst, dass Alternativen existieren (Geräteadministrator oder der Power-Button).</string> - <string name="dialog_consent_accessibility_consent">Ich willige ein, dass µLauncher eine Bedienungshilfe für Zwecke verwendet, die nicht unter Barrierefreiheit fallen.</string> + <string name="dialog_consent_accessibility_consent">Ich willige ein, dass μLauncher eine Bedienungshilfe für Zwecke verwendet, die nicht unter Barrierefreiheit fallen.</string> <string name="dialog_consent_accessibility_data_collection">Ich willige ein, dass µLauncher keine Daten sammelt.</string> <string name="dialog_consent_accessibility_title">Bedienungshilfe aktivieren</string> <string name="dialog_report_bug_info">Danke für die Mithilfe, μLauncher zu verbessern!\nEs wird darum gebeten, Bug Reports die folgenden Informationen anzufügen, um diese besser nachvollziehen zu können:</string> From c8d7a1cc3e51d063e430e35563b3352710dc706e Mon Sep 17 00:00:00 2001 From: class0068 <monkeyotw@proton.me> Date: Mon, 17 Mar 2025 22:02:58 +0000 Subject: [PATCH 42/73] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (254 of 254 strings) Translation: jrpie-Launcher/Launcher Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/zh_Hans/ --- app/src/main/res/values-zh-rCN/strings.xml | 91 ++++++++++++---------- 1 file changed, 51 insertions(+), 40 deletions(-) diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 873ba6a..566d67d 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -5,7 +5,7 @@ <string name="ic_menu_alt">更多选项</string> <string name="settings_title">设置</string> <string name="settings_launcher_section_appearance">外观</string> - <string name="settings_theme_color_theme">主题</string> + <string name="settings_theme_color_theme">主题风格</string> <string name="settings_launcher_section_display">显示</string> <string name="list_tab_other">其他</string> <string name="settings_gesture_up">上</string> @@ -40,49 +40,49 @@ <string name="settings_apps_install">安装应用</string> <string name="settings_apps_toast_store_not_found">没有找到应用市场</string> <string name="settings_launcher_section_date_time"><![CDATA[日期和时间]]></string> - <string name="settings_theme_wallpaper">选择一个壁纸</string> + <string name="settings_theme_wallpaper">选择壁纸</string> <string name="settings_display_screen_timeout_disabled">保持屏幕常亮</string> <string name="settings_launcher_section_functionality">功能</string> <string name="settings_enabled_gestures_edge_swipe">边缘滑动动作</string> - <string name="settings_functionality_auto_launch">直接启动匹配搜索内容的应用</string> + <string name="settings_functionality_auto_launch">启动搜索匹配项</string> <string name="settings_functionality_auto_keyboard">搜索时呼出键盘</string> <string name="settings_launcher_sensitivity">灵敏度</string> <string name="settings_meta_cant_select_launcher">应用信息</string> - <string name="settings_meta_show_tutorial">查看启动器教程</string> + <string name="settings_meta_show_tutorial">查看 µLauncher 的使用教程</string> <string name="settings_meta_reset">重置设置</string> - <string name="settings_meta_reset_confirm">你将放弃你所有的配置。继续吗?</string> - <string name="settings_meta_report_bug">反馈 BUG</string> + <string name="settings_meta_reset_confirm">该操作将丢弃您的所有配置。是否继续?</string> + <string name="settings_meta_report_bug">错误反馈</string> <string name="settings_meta_fork_contact">联系该 fork 版本的作者</string> <string name="settings_meta_privacy">隐私政策</string> <string name="settings_meta_contact">联系原作者</string> - <string name="settings_meta_discord">加入 Discord!</string> + <string name="settings_meta_discord">加入我们的 Discord 社区!</string> <string name="list_title_view">全部应用</string> <string name="list_title_pick">选择应用</string> - <string name="tutorial_start_text">花几秒时间学下咋用这个启动器吧!</string> + <string name="tutorial_start_text">👋\n\n花几秒钟时间,了解一下如何用这个启动器吧!</string> <string name="tutorial_concept_title">概念</string> - <string name="tutorial_concept_text_2">该应用是开源的(MIT许可),并在 GitHub 上可用!一定要来看看代码仓库!</string> + <string name="tutorial_concept_text_2">这是一款自由软件(遵循 MIT 许可)!\n欢迎查看项目仓库!</string> <string name="tutorial_usage_title">使用方法</string> - <string name="tutorial_usage_text">您的主屏幕仅包含本地日期和时间,没有其它纷纷扰扰。</string> + <string name="tutorial_usage_text">您的主屏幕仅包含本地日期和时间,没有多余项目。</string> <string name="tutorial_setup_title">设置</string> - <string name="tutorial_setup_text">我们为您选择了一些默认应用。如果您愿意,现在可以更改它们:</string> - <string name="tutorial_setup_text_2">您也可以稍后更改选择。</string> + <string name="tutorial_setup_text">我们为您选择了一些默认应用。如果您希望进行更改,现在就可以:</string> + <string name="tutorial_setup_text_2">您也可以稍后对您的选择进行更改。</string> <string name="tutorial_finish_title">开始!</string> <string name="list_tab_app">应用</string> <string name="list_app_delete">卸载</string> <string name="list_app_info">应用信息</string> <string name="list_apps_search_hint">搜索</string> - <string name="list_other_settings">启动器设置</string> + <string name="list_other_settings">μLauncher 设置</string> <string name="list_other_list">全部应用</string> - <string name="list_other_volume_up">音乐:大声</string> - <string name="list_other_volume_down">音乐:小声</string> + <string name="list_other_volume_up">增大音量</string> + <string name="list_other_volume_down">降低音量</string> <string name="list_other_track_previous">音乐:上一首</string> <string name="list_other_track_next">音乐:下一首</string> <string name="list_other_nop">啥也不干</string> <string name="tutorial_title">教程</string> - <string name="tutorial_concept_text">μLauncher 的设计是最小、高效且无干扰。它不付费、无广告、不追踪。</string> - <string name="tutorial_usage_text_2">您只需滑动屏幕或按下按钮即可启动应用程序。在下一步向导中选择一些应用程序。</string> + <string name="tutorial_concept_text">μLauncher 的设计理念是简约、高效,无干扰。\n\n不含广告、且不收集任何数据。</string> + <string name="tutorial_usage_text_2">您可以通过手势或按键来启动最重要的应用程序。</string> <string name="settings_general_choose_home_screen">将 μLauncher 设为默认桌面</string> - <string name="tutorial_finish_text">您已经准备好开始了!我希望这对您很有价值!——Finn(Launcher 作者)和 Josia(做了一些改进并维护了 μLauncher 分支)</string> + <string name="tutorial_finish_text">您已经准备好开始使用本启动器了!\n\n希望这对你有帮助!\n\n- Finn(Launcher 的作者)和 Josia(对 μLauncher 进行了改进和维护)</string> <string name="settings_enabled_gestures_double_swipe">双滑动作</string> <string name="settings_clock_localized">使用本地日期格式</string> <string name="settings_clock_time_visible">显示时间</string> @@ -104,9 +104,9 @@ <string name="settings_apps_hide_bound_apps">不要在应用抽屉中显示被绑定到手势的应用</string> <string name="alert_requires_android_m">此功能需要 Android 6 或更高版本。</string> <string name="snackbar_app_hidden">应用程序已隐藏。您可在设置中让它再次显示。</string> - <string name="toast_device_admin_not_enabled">µLauncher 需要是设备管理员才能够锁定屏幕。</string> - <string name="device_admin_explanation">这是锁屏动作所必需的。</string> - <string name="accessibility_service_name">µLauncher -锁屏</string> + <string name="toast_device_admin_not_enabled">µLauncher 需要获得设备管理员权限才能够锁定屏幕。</string> + <string name="device_admin_explanation">这是执行锁屏操作所必需的。</string> + <string name="accessibility_service_name">µLauncher - 锁屏</string> <string name="list_title_favorite">收藏的应用</string> <string name="list_app_favorite_add">添加到收藏夹</string> <string name="list_app_favorite_remove">从收藏夹中移除</string> @@ -138,18 +138,18 @@ <string name="settings_gesture_description_date">点击日期</string> <string name="settings_gesture_description_time">点击时间</string> <string name="settings_meta_view_code">查看源代码</string> - <string name="settings_meta_join_chat">加入 µLauncher 聊天群</string> + <string name="settings_meta_join_chat">加入 μLauncher 的聊天群</string> <string name="list_other_list_favorites">收藏的应用</string> <string name="list_other_lock_screen">锁屏</string> <string name="settings_theme_text_shadow">文本阴影</string> <string name="settings_enabled_gestures_double_swipe_summary">双指滑动</string> <string name="dialog_rename_title">重命名 %1$s</string> <string name="settings_theme_color_theme_item_default">默认</string> - <string name="settings_theme_color_theme_item_dark">深色</string> + <string name="settings_theme_color_theme_item_dark">暗色</string> <string name="settings_theme_background_item_transparent">透明</string> - <string name="settings_theme_background_item_dim">昏暗</string> + <string name="settings_theme_background_item_dim">变暗</string> <string name="settings_theme_background_item_blur">模糊</string> - <string name="settings_theme_background_item_solid">固实</string> + <string name="settings_theme_background_item_solid">纯色</string> <string name="settings_theme_font_item_system_default">系统默认</string> <string name="settings_theme_font_item_monospace">等宽</string> <string name="settings_theme_font_item_serif">衬线</string> @@ -158,16 +158,16 @@ <string name="settings_enabled_gestures_edge_swipe_edge_width">边缘宽度</string> <string name="list_app_rename">重命名</string> <string name="device_admin_description">启用锁屏动作</string> - <string name="toast_accessibility_service_not_enabled">μLauncher 的无障碍服务未启用。请在设置中启用它</string> - <string name="toast_lock_screen_not_supported">错误:此设备不支持使用无障碍功能锁定屏幕。请改用设备管理员。</string> + <string name="toast_accessibility_service_not_enabled">μLauncher 的无障碍服务未启用,请在设置中启用它。</string> + <string name="toast_lock_screen_not_supported">错误:此设备不支持使用无障碍功能锁定屏幕。请改用设备管理员模式。</string> <string name="screen_lock_method_use_accessibility">使用无障碍服务</string> - <string name="screen_lock_method_use_device_admin">使用设备管理员</string> + <string name="screen_lock_method_use_device_admin">使用设备管理员模式</string> <string name="dialog_cancel">取消</string> - <string name="settings_theme_color_theme_item_light">浅色</string> + <string name="settings_theme_color_theme_item_light">亮色</string> <string name="list_other_expand_settings_panel">快速设置</string> - <string name="alert_lock_screen_failed">错误:锁定屏幕失败。(如果您刚刚升级了应用程序,请尝试在手机设置中手动禁用并重新启用无障碍服务)</string> + <string name="alert_lock_screen_failed">错误:锁定屏幕失败。(如果您刚刚升级了本启动器,请尝试在手机设置中手动禁用并重新启用无障碍服务)</string> <string name="settings_enabled_gestures_edge_swipe_summary">在屏幕边缘滑动</string> - <string name="accessibility_service_description">将 µLauncher 设为无障碍服务允许其锁定屏幕。请注意,这需要过多的权限。你永远不应该轻易地授予任何应用程序这样的权限。µLauncher 将仅使用无障碍服务功能锁屏。您可以审计源代码。请注意,锁屏也可以通过授予 µLauncher 设备管理员权限来实现,然而,这种方法不适用于以指纹和面部解锁。</string> + <string name="accessibility_service_description">将 µLauncher 设为无障碍服务允许其锁定屏幕。请注意,这需要过多的权限。你永远不应该轻易地授予任何应用程序这样的权限。µLauncher 将仅使用无障碍服务功能锁屏。您可以审核源代码。请注意,锁屏也可以通过授予 µLauncher 设备管理员权限来实现,然而,这种方法不适用于以指纹和面部解锁。</string> <string name="settings_gesture_back">返回</string> <string name="dialog_select_color_red">红色</string> <string name="dialog_select_color_blue">蓝色</string> @@ -178,7 +178,7 @@ <string name="list_other_list_private_space">私人空间</string> <string name="dialog_choose_color_title">选择颜色</string> <string name="dialog_select_color_color_hex">颜色</string> - <string name="dialog_report_bug_title">报告错误</string> + <string name="dialog_report_bug_title">错误反馈</string> <string name="settings_gesture_swipe_larger"><![CDATA[>]]></string> <string name="tooltip_lock_private_space">锁定私人空间</string> <string name="settings_gesture_swipe_v">V</string> @@ -202,7 +202,7 @@ <string name="toast_private_space_locked">私人空间已锁定</string> <string name="toast_private_space_unlocked">私人空间已解锁</string> <string name="toast_private_space_not_available">私人空间不可用</string> - <string name="toast_private_space_default_home_screen">µLauncher 需要作为默认的主屏幕来访问私人空间。</string> + <string name="toast_private_space_default_home_screen">µLauncher 需要作为默认主屏幕才能访问私人空间。</string> <string name="toast_activity_not_found_search_web">没有找到处理搜索的应用。</string> <string name="toast_activity_not_found_browser">无法打开 URL:找不到浏览器。</string> <string name="dialog_consent_accessibility_privileges">我已知晓,这将赋予 µLauncher 广泛且重要的权限。</string> @@ -237,7 +237,7 @@ <br/><br/><br/><br/> 你可以在设置中随时更改这个选项。 ]]></string> - <string name="list_apps_search_hint_no_auto_launch">搜索(不触发自动启动应用程序)</string> + <string name="list_apps_search_hint_no_auto_launch">搜索(不触发自动启动匹配项)</string> <string name="dialog_consent_accessibility_text"><![CDATA[您即将激活“无障碍”服务。这将授予 µLauncher <strong>广泛且重要的权限</strong>。<br/>µLauncher 将这些权限<strong>仅用于锁定屏幕</strong>。µLauncher <strong>绝不会收集任何数据</strong>。尤其是,µLauncher 不会使用“无障碍”服务来收集任何数据。]]></string> <string name="settings_gesture_description_swipe_larger">(从)左上 (滑向)中右(滑向)左下</string> <string name="settings_gesture_tap_up">单击 + 上滑</string> @@ -254,14 +254,25 @@ <string name="settings_gesture_description_swipe_lambda_reverse">(从)右下 (滑向)中上(滑向)左下</string> <string name="settings_gesture_swipe_lambda_reverse">Λ (反向)</string> <string name="settings_gesture_swipe_v_reverse">V(反向)</string> - <string name="settings_gesture_swipe_larger_reverse"><![CDATA[> (反向)]]></string> - <string name="settings_gesture_swipe_smaller_reverse"><![CDATA[< (反向)]]></string> - <string name="settings_functionality_auto_launch_summary">按空格键临时暂停该功能。</string> + <string name="settings_gesture_swipe_larger_reverse"><![CDATA[>(反向)]]></string> + <string name="settings_gesture_swipe_smaller_reverse"><![CDATA[<(反向)]]></string> + <string name="settings_functionality_auto_launch_summary">开启后将直接启动匹配搜索内容的应用,可以通过按空格键临时暂停该功能。</string> <string name="settings_list_layout">应用程序列表样式</string> <string name="pin_shortcut_button_bind">绑定到手势</string> <string name="list_other_track_play_pause">音乐:播放 / 暂停</string> <string name="dialog_report_bug_button_security">报告安全漏洞</string> - <string name="dialog_report_bug_security_info">安全漏洞请不要在 Github 上以公开的方式提交,而是使用以下方式进行报告:</string> - <string name="dialog_report_bug_info">感谢您帮助改进 µLauncher!\n请考虑在您的应用程序错误报告中添加以下信息:</string> - <string name="dialog_consent_accessibility_other_options">我已知晓,还有其他替代方法(使用设备管理员权限或电源按键)。</string> + <string name="dialog_report_bug_security_info">请不要在 Github 上以公开的方式报告安全漏洞,请使用以下方式进行报告:</string> + <string name="dialog_report_bug_info">感谢您帮助改进 µLauncher!\n请考虑在您的应用程序错误反馈中添加以下信息:</string> + <string name="dialog_consent_accessibility_other_options">我已知晓,还有其他替代方法(使用设备管理员模式或电源按键)。</string> + <string name="dialog_consent_accessibility_data_collection">我同意 μLauncher 不收集任何数据。</string> + <string name="settings_meta_donate">捐赠</string> + <string name="list_other_volume_adjust">调整音量</string> + <string name="tutorial_concept_label_version">版本</string> + <string name="tutorial_app_list_title">所有应用</string> + <string name="tutorial_app_list_text">您可以在应用程序列表中快速所搜所有应用。\n\n您可以通过上滑打开应用程序列表,也可以通过绑定其他手势操作来打开应用程序列表。</string> + <string name="tutorial_app_list_text_2">当匹配到唯一的应用程序后,该应用将自动启动。\n如果你不想触发自动启动,在查询内容前加上空格即可禁用。</string> + <string name="settings_display_hide_status_bar">隐藏状态栏</string> + <string name="settings_display_hide_navigation_bar">隐藏导航栏</string> + <string name="settings_list_reverse_layout">倒序排列应用程序</string> + <string name="dialog_consent_accessibility_consent">我同意 μLauncher 使用无障碍服务来提供与无障碍服务无关的其他功能。</string> </resources> From 7ac09bd465cb65de9a0da52f997cc579b2e1766f Mon Sep 17 00:00:00 2001 From: Josia <git@jrpie.de> Date: Mon, 17 Mar 2025 23:39:00 +0000 Subject: [PATCH 43/73] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (254 of 254 strings) Translation: jrpie-Launcher/Launcher Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/zh_Hans/ --- app/src/main/res/values-zh-rCN/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 566d67d..55376c3 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -205,7 +205,7 @@ <string name="toast_private_space_default_home_screen">µLauncher 需要作为默认主屏幕才能访问私人空间。</string> <string name="toast_activity_not_found_search_web">没有找到处理搜索的应用。</string> <string name="toast_activity_not_found_browser">无法打开 URL:找不到浏览器。</string> - <string name="dialog_consent_accessibility_privileges">我已知晓,这将赋予 µLauncher 广泛且重要的权限。</string> + <string name="dialog_consent_accessibility_privileges">我已知晓,这将赋予 μLauncher 广泛且重要的权限。</string> <string name="settings_apps_hide_private_space_apps">在应用程序列表中隐藏私人空间</string> <string name="settings_apps_hide_paused_apps">隐藏已被暂停的应用</string> <string name="settings_gesture_description_back">返回按键 / 返回手势</string> @@ -227,7 +227,7 @@ <h3>通过“无障碍”功能</h3> 需要更多的权限。 - µLauncher 将这些权限仅用于锁定屏幕。 + μLauncher 将这些权限仅用于锁定屏幕。 <br/> (对于任何一个从网上下载的应用所做的类似声明,你都不应该抱持“默认为可信”的态度,你可以并应该检查一下它的<a href=\"https://github.com/jrpie/Launcher\">源代码</a>.) <br/> @@ -238,7 +238,7 @@ 你可以在设置中随时更改这个选项。 ]]></string> <string name="list_apps_search_hint_no_auto_launch">搜索(不触发自动启动匹配项)</string> - <string name="dialog_consent_accessibility_text"><![CDATA[您即将激活“无障碍”服务。这将授予 µLauncher <strong>广泛且重要的权限</strong>。<br/>µLauncher 将这些权限<strong>仅用于锁定屏幕</strong>。µLauncher <strong>绝不会收集任何数据</strong>。尤其是,µLauncher 不会使用“无障碍”服务来收集任何数据。]]></string> + <string name="dialog_consent_accessibility_text"><![CDATA[您即将激活“无障碍”服务。这将授予 μLauncher <strong>广泛且重要的权限</strong>。<br/>μLauncher 将这些权限<strong>仅用于锁定屏幕</strong>。µLauncher <strong>绝不会收集任何数据</strong>。尤其是,μLauncher 不会使用“无障碍”服务来收集任何数据。]]></string> <string name="settings_gesture_description_swipe_larger">(从)左上 (滑向)中右(滑向)左下</string> <string name="settings_gesture_tap_up">单击 + 上滑</string> <string name="settings_gesture_tap_down">单击 + 下滑</string> From 0baa889de5fdd577a076e71d6935c62cac384d2d Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Wed, 19 Mar 2025 17:55:35 +0100 Subject: [PATCH 44/73] 0.1.1 --- app/build.gradle | 4 ++-- fastlane/metadata/android/en-US/changelogs/41.txt | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 fastlane/metadata/android/en-US/changelogs/41.txt diff --git a/app/build.gradle b/app/build.gradle index 2ca3729..9c779e1 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -23,8 +23,8 @@ android { minSdkVersion 21 targetSdkVersion 35 compileSdk 35 - versionCode 40 - versionName "0.1.0" + versionCode 41 + versionName "0.1.1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/fastlane/metadata/android/en-US/changelogs/41.txt b/fastlane/metadata/android/en-US/changelogs/41.txt new file mode 100644 index 0000000..4458a89 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/41.txt @@ -0,0 +1,5 @@ + * Improved tutorial (thank you, wassupluke!) + * Added Japanese translation (thank you, anmoti!) + * Improved Chinese translation (thank you, nobody!) + * Fixed bug where gesture navigation triggered long click + * Fixed bug: switching from grayscale icons back to normal now works as expected From 58ddd3c8cc8c428708fb1a76a9fe090b59c038bf Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Thu, 20 Mar 2025 14:08:21 +0100 Subject: [PATCH 45/73] fix #130 - revert part of 9043461 as ViewPager2 causes an issue with opening the keyboard --- .../android/launcher/ui/list/ListActivity.kt | 26 ++++++++++--------- app/src/main/res/layout/list.xml | 7 ++++- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/list/ListActivity.kt b/app/src/main/java/de/jrpie/android/launcher/ui/list/ListActivity.kt index 59d83e5..fe27f0f 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/list/ListActivity.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/list/ListActivity.kt @@ -9,8 +9,7 @@ import android.window.OnBackInvokedDispatcher import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.content.res.AppCompatResources import androidx.fragment.app.Fragment -import androidx.viewpager2.adapter.FragmentStateAdapter -import com.google.android.material.tabs.TabLayoutMediator +import androidx.fragment.app.FragmentPagerAdapter import de.jrpie.android.launcher.Application import de.jrpie.android.launcher.R import de.jrpie.android.launcher.actions.LauncherAction @@ -225,13 +224,10 @@ class ListActivity : AppCompatActivity(), UIObject { updateTitle() val sectionsPagerAdapter = ListSectionsPagerAdapter(this) - binding.listViewpager.apply { - adapter = sectionsPagerAdapter - currentItem = 0 + binding.listViewpager.let { + it.adapter = sectionsPagerAdapter + binding.listTabs.setupWithViewPager(it) } - TabLayoutMediator(binding.listTabs, binding.listViewpager) { tab, position -> - tab.text = sectionsPagerAdapter.getPageTitle(position) - }.attach() } } @@ -243,11 +239,17 @@ private val TAB_TITLES = arrayOf( /** * The [ListSectionsPagerAdapter] returns the fragment, * which corresponds to the selected tab in [ListActivity]. + * + * This should eventually be replaced by a [FragmentStateAdapter] + * However this keyboard does not open when using [ViewPager2] + * so currently [ViewPager] is used here. + * https://github.com/jrpie/launcher/issues/130 */ +@Suppress("deprecation") class ListSectionsPagerAdapter(private val activity: ListActivity) : - FragmentStateAdapter(activity) { + FragmentPagerAdapter(activity.supportFragmentManager) { - override fun createFragment(position: Int): Fragment { + override fun getItem(position: Int): Fragment { return when (position) { 0 -> ListFragmentApps() 1 -> ListFragmentOther() @@ -255,11 +257,11 @@ class ListSectionsPagerAdapter(private val activity: ListActivity) : } } - fun getPageTitle(position: Int): CharSequence { + override fun getPageTitle(position: Int): CharSequence { return activity.resources.getString(TAB_TITLES[position]) } - override fun getItemCount(): Int { + override fun getCount(): Int { return when (activity.intention) { ListActivity.ListActivityIntention.VIEW -> 1 else -> 2 diff --git a/app/src/main/res/layout/list.xml b/app/src/main/res/layout/list.xml index 45bcb85..8a3b5d9 100644 --- a/app/src/main/res/layout/list.xml +++ b/app/src/main/res/layout/list.xml @@ -95,7 +95,12 @@ </com.google.android.material.appbar.AppBarLayout> - <androidx.viewpager2.widget.ViewPager2 + <!-- + Should be replaced by androidx.viewpager2.widget.ViewPager2 + but there is an issue with opening the keyboard: + https://github.com/jrpie/launcher/issues/130 + --> + <androidx.viewpager.widget.ViewPager android:id="@+id/list_viewpager" android:layout_width="0dp" android:layout_height="0dp" From 865cd47583a289b24a09e914c5a49f2b5a88d71d Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Thu, 20 Mar 2025 14:12:29 +0100 Subject: [PATCH 46/73] 0.1.2 --- app/build.gradle | 4 ++-- fastlane/metadata/android/en-US/changelogs/42.txt | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 fastlane/metadata/android/en-US/changelogs/42.txt diff --git a/app/build.gradle b/app/build.gradle index 9c779e1..349f75c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -23,8 +23,8 @@ android { minSdkVersion 21 targetSdkVersion 35 compileSdk 35 - versionCode 41 - versionName "0.1.1" + versionCode 42 + versionName "0.1.2" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/fastlane/metadata/android/en-US/changelogs/42.txt b/fastlane/metadata/android/en-US/changelogs/42.txt new file mode 100644 index 0000000..39011cf --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/42.txt @@ -0,0 +1 @@ +* Fixed bug where keyboard does not open automatically From 54409b63121fe6d6bca3c71dee9980da5944fab7 Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Thu, 20 Mar 2025 14:55:22 +0100 Subject: [PATCH 47/73] fix #133 --- .../jrpie/android/launcher/ui/HomeActivity.kt | 22 +++++++------------ .../launcher/ui/TouchGestureDetector.kt | 14 ++++++++++-- 2 files changed, 20 insertions(+), 16 deletions(-) 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 a658cd1..53a0876 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 @@ -2,10 +2,10 @@ package de.jrpie.android.launcher.ui import android.annotation.SuppressLint import android.content.SharedPreferences +import android.content.res.Configuration import android.content.res.Resources import android.os.Build import android.os.Bundle -import android.util.DisplayMetrics import android.view.KeyEvent import android.view.MotionEvent import android.view.View @@ -56,22 +56,11 @@ class HomeActivity : UIObject, AppCompatActivity() { super<AppCompatActivity>.onCreate(savedInstanceState) super<UIObject>.onCreate() - val displayMetrics = DisplayMetrics() - - @Suppress("deprecation") // required to support API < 30 - windowManager.defaultDisplay.getMetrics(displayMetrics) - - val width = displayMetrics.widthPixels - val height = displayMetrics.heightPixels - touchGestureDetector = TouchGestureDetector( - this, - width, - height, + this, 0, 0, LauncherPreferences.enabled_gestures().edgeSwipeEdgeWidth() / 100f ) - - + touchGestureDetector.updateScreenSize(windowManager) // Initialise layout binding = HomeBinding.inflate(layoutInflater) @@ -103,6 +92,11 @@ class HomeActivity : UIObject, AppCompatActivity() { } } + override fun onConfigurationChanged(newConfig: Configuration) { + super.onConfigurationChanged(newConfig) + touchGestureDetector.updateScreenSize(windowManager) + } + override fun onStart() { super<AppCompatActivity>.onStart() diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/TouchGestureDetector.kt b/app/src/main/java/de/jrpie/android/launcher/ui/TouchGestureDetector.kt index 9000fa8..8e8ed4e 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/TouchGestureDetector.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/TouchGestureDetector.kt @@ -5,8 +5,10 @@ import android.graphics.Insets import android.os.Build import android.os.Handler import android.os.Looper +import android.util.DisplayMetrics import android.view.MotionEvent import android.view.ViewConfiguration +import android.view.WindowManager import androidx.annotation.RequiresApi import de.jrpie.android.launcher.actions.Gesture import de.jrpie.android.launcher.preferences.LauncherPreferences @@ -17,8 +19,8 @@ import kotlin.math.tan class TouchGestureDetector( private val context: Context, - val width: Int, - val height: Int, + var width: Int, + var height: Int, var edgeWidth: Float ) { private val ANGULAR_THRESHOLD = tan(Math.PI / 6) @@ -319,6 +321,14 @@ class TouchGestureDetector( } } + fun updateScreenSize(windowManager: WindowManager) { + val displayMetrics = DisplayMetrics() + @Suppress("deprecation") // required to support API < 30 + windowManager.defaultDisplay.getMetrics(displayMetrics) + width = displayMetrics.widthPixels + height = displayMetrics.heightPixels + } + @RequiresApi(Build.VERSION_CODES.Q) fun setSystemGestureInsets(insets: Insets) { systemGestureInsetTop = insets.top From 7fc58fe38482a692b297a746358e3a04daf01a87 Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Thu, 20 Mar 2025 15:52:12 +0100 Subject: [PATCH 48/73] 0.1.3 --- app/build.gradle | 4 ++-- fastlane/metadata/android/en-US/changelogs/43.txt | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 fastlane/metadata/android/en-US/changelogs/43.txt diff --git a/app/build.gradle b/app/build.gradle index 349f75c..c280794 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -23,8 +23,8 @@ android { minSdkVersion 21 targetSdkVersion 35 compileSdk 35 - versionCode 42 - versionName "0.1.2" + versionCode 43 + versionName "0.1.3" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/fastlane/metadata/android/en-US/changelogs/43.txt b/fastlane/metadata/android/en-US/changelogs/43.txt new file mode 100644 index 0000000..2bca600 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/43.txt @@ -0,0 +1 @@ +* Fixed gesture detection in landscape orientation From 8e140e2e69d88ab3190642cc271ffb0f793e7c82 Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Thu, 20 Mar 2025 16:23:01 +0100 Subject: [PATCH 49/73] rename tab "Apps" to "Actions" and "Volume Up/Down" to "Volume Up/Down Key" --- .../jrpie/android/launcher/ui/settings/SettingsActivity.kt | 2 +- app/src/main/res/values-de/strings.xml | 6 +++--- app/src/main/res/values/strings.xml | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/settings/SettingsActivity.kt b/app/src/main/java/de/jrpie/android/launcher/ui/settings/SettingsActivity.kt index 4c464e5..cd59726 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/settings/SettingsActivity.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/settings/SettingsActivity.kt @@ -109,7 +109,7 @@ class SettingsActivity : AppCompatActivity(), UIObject { } private val TAB_TITLES = arrayOf( - R.string.settings_tab_app, + R.string.settings_tab_actions, R.string.settings_tab_launcher, R.string.settings_tab_meta ) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 735aa9d..d07ff7d 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -14,7 +14,7 @@ - --> <string name="settings_title">Einstellungen</string> - <string name="settings_tab_app">Apps</string> + <string name="settings_tab_actions">Aktionen</string> <string name="settings_tab_launcher">Launcher</string> <string name="settings_tab_meta">Meta</string> <!-- @@ -54,9 +54,9 @@ <string name="settings_gesture_description_down_left_edge">An der linken Kante nach unten wischen</string> <string name="settings_gesture_down_right_edge">Abwärts (rechts)</string> <string name="settings_gesture_description_down_right_edge">An der rechten Kanten nach unten wischen</string> - <string name="settings_gesture_vol_up">Lautstärke +</string> + <string name="settings_gesture_vol_up">Lauter-Taste</string> <string name="settings_gesture_description_vol_up">Die Taste \"Lauter\" drücken</string> - <string name="settings_gesture_vol_down">Lautstärke -</string> + <string name="settings_gesture_vol_down">Leiser-Taste</string> <string name="settings_gesture_description_vol_down">Die Taste \"Leiser\" drücken</string> <string name="settings_gesture_double_click">Doppelklick</string> <string name="settings_gesture_description_double_click">In einem leeren Bereich doppelt klicken</string> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6205281..c426a5c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -16,7 +16,7 @@ --> <string name="settings_title">Settings</string> - <string name="settings_tab_app">Apps</string> + <string name="settings_tab_actions">Actions</string> <string name="settings_tab_launcher">Launcher</string> <string name="settings_tab_meta">Meta</string> @@ -85,9 +85,9 @@ <string name="settings_gesture_swipe_lambda_reverse">Λ (Reverse)</string> <string name="settings_gesture_description_swipe_lambda_reverse">Bottom right -> top mid -> bottom left</string> - <string name="settings_gesture_vol_up">Volume Up</string> + <string name="settings_gesture_vol_up">Volume Up Key</string> <string name="settings_gesture_description_vol_up">Press the volume up button</string> - <string name="settings_gesture_vol_down">Volume Down</string> + <string name="settings_gesture_vol_down">Volume Down Key</string> <string name="settings_gesture_description_vol_down">Press the volume down button</string> <string name="settings_gesture_double_click">Double Click</string> <string name="settings_gesture_description_double_click">Double click an empty area</string> From b4608ef15338891d9715ec7ca133c05bbde3ec28 Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Mon, 24 Mar 2025 13:21:58 +0100 Subject: [PATCH 50/73] add new action: show recent apps --- app/src/main/AndroidManifest.xml | 4 +-- .../launcher/actions/LauncherAction.kt | 12 +++++++- .../lock/LauncherAccessibilityService.kt | 30 +++++++++++++++---- .../launcher/actions/lock/LockMethod.kt | 1 + .../main/res/drawable/baseline_apps_24.xml | 11 +++++++ app/src/main/res/values/strings.xml | 21 ++++++++++--- 6 files changed, 67 insertions(+), 12 deletions(-) create mode 100644 app/src/main/res/drawable/baseline_apps_24.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 93f6ce8..a5f8831 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -85,7 +85,7 @@ <service android:name=".actions.lock.LauncherAccessibilityService" android:exported="true" - android:label="@string/accessibility_service_name" + android:label="@string/app_name" android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"> <intent-filter> <action android:name="android.accessibilityservice.AccessibilityService" /> @@ -97,4 +97,4 @@ </service> </application> -</manifest> \ No newline at end of file +</manifest> 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 5d2be94..ee9502c 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 @@ -11,7 +11,9 @@ import android.view.KeyEvent import android.widget.Toast import androidx.appcompat.content.res.AppCompatResources import de.jrpie.android.launcher.Application +import de.jrpie.android.launcher.BuildConfig import de.jrpie.android.launcher.R +import de.jrpie.android.launcher.actions.lock.LauncherAccessibilityService import de.jrpie.android.launcher.apps.AppFilter import de.jrpie.android.launcher.apps.hidePrivateSpaceWhenLocked import de.jrpie.android.launcher.apps.isPrivateSpaceSupported @@ -132,6 +134,14 @@ enum class LauncherAction( R.drawable.baseline_settings_applications_24, ::expandSettingsPanel ), + RECENT_APPS( + "recent_apps", + R.string.list_other_recent_apps, + R.drawable.baseline_apps_24, + LauncherAccessibilityService::openRecentApps, + false, + { _ -> BuildConfig.USE_ACCESSIBILITY_SERVICE } + ), LOCK_SCREEN( "lock_screen", R.string.list_other_lock_screen, @@ -142,7 +152,7 @@ enum class LauncherAction( "toggle_torch", R.string.list_other_torch, R.drawable.baseline_flashlight_on_24, - ::toggleTorch + ::toggleTorch, ), NOP("nop", R.string.list_other_nop, R.drawable.baseline_not_interested_24, {}); diff --git a/app/src/main/java/de/jrpie/android/launcher/actions/lock/LauncherAccessibilityService.kt b/app/src/main/java/de/jrpie/android/launcher/actions/lock/LauncherAccessibilityService.kt index a8ef6f2..7cb32d9 100644 --- a/app/src/main/java/de/jrpie/android/launcher/actions/lock/LauncherAccessibilityService.kt +++ b/app/src/main/java/de/jrpie/android/launcher/actions/lock/LauncherAccessibilityService.kt @@ -22,26 +22,44 @@ class LauncherAccessibilityService : AccessibilityService() { companion object { private const val TAG = "Launcher Accessibility" + private const val ACTION_REQUEST_ENABLE = "ACTION_REQUEST_ENABLE" const val ACTION_LOCK_SCREEN = "ACTION_LOCK_SCREEN" + const val ACTION_RECENT_APPS = "ACTION_RECENT_APPS" - fun lockScreen(context: Context) { + private fun invoke(context: Context, action: String, failureMessageRes: Int) { try { context.startService( Intent( context, LauncherAccessibilityService::class.java ).apply { - action = ACTION_LOCK_SCREEN + this.action = action }) - } catch (e: Exception) { + } catch (_: Exception) { Toast.makeText( context, - context.getString(R.string.alert_lock_screen_failed), + context.getString(failureMessageRes), Toast.LENGTH_LONG ).show() } } + fun lockScreen(context: Context) { + if (!isEnabled(context)) { + showEnableDialog(context) + } else { + invoke(context, ACTION_LOCK_SCREEN, R.string.alert_lock_screen_failed) + } + } + + fun openRecentApps(context: Context) { + if (!isEnabled(context)) { + showEnableDialog(context) + } else { + invoke(context, ACTION_RECENT_APPS, R.string.alert_recent_apps_failed) + } + } + fun isEnabled(context: Context): Boolean { val enabledServices = Settings.Secure.getString( context.contentResolver, @@ -58,7 +76,7 @@ class LauncherAccessibilityService : AccessibilityService() { setView(R.layout.dialog_consent_accessibility) setTitle(R.string.dialog_consent_accessibility_title) setPositiveButton(R.string.dialog_consent_accessibility_ok) { _, _ -> - lockScreen(context) + invoke(context, ACTION_REQUEST_ENABLE, R.string.alert_enable_accessibility_failed) } setNegativeButton(R.string.dialog_cancel) { _, _ -> } }.create().also { it.show() }.apply { @@ -94,7 +112,9 @@ class LauncherAccessibilityService : AccessibilityService() { } when (action) { + ACTION_REQUEST_ENABLE -> {} // do nothing ACTION_LOCK_SCREEN -> handleLockScreen() + ACTION_RECENT_APPS -> performGlobalAction(GLOBAL_ACTION_RECENTS) } } return super.onStartCommand(intent, flags, startId) diff --git a/app/src/main/java/de/jrpie/android/launcher/actions/lock/LockMethod.kt b/app/src/main/java/de/jrpie/android/launcher/actions/lock/LockMethod.kt index 541510a..93b4cbf 100644 --- a/app/src/main/java/de/jrpie/android/launcher/actions/lock/LockMethod.kt +++ b/app/src/main/java/de/jrpie/android/launcher/actions/lock/LockMethod.kt @@ -6,6 +6,7 @@ import android.widget.Button import androidx.appcompat.app.AlertDialog import de.jrpie.android.launcher.BuildConfig import de.jrpie.android.launcher.R +import de.jrpie.android.launcher.actions.lock.LauncherAccessibilityService import de.jrpie.android.launcher.preferences.LauncherPreferences diff --git a/app/src/main/res/drawable/baseline_apps_24.xml b/app/src/main/res/drawable/baseline_apps_24.xml new file mode 100644 index 0000000..c5a49a0 --- /dev/null +++ b/app/src/main/res/drawable/baseline_apps_24.xml @@ -0,0 +1,11 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + + <path + android:fillColor="?android:textColor" + android:pathData="M4,8h4L8,4L4,4v4zM10,20h4v-4h-4v4zM4,20h4v-4L4,16v4zM4,14h4v-4L4,10v4zM10,14h4v-4h-4v4zM16,4v4h4L20,4h-4zM10,8h4L14,4h-4v4zM16,14h4v-4h-4v4zM16,20h4v-4h-4v4z" /> + +</vector> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c426a5c..83b963b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -252,6 +252,7 @@ <string name="list_other_track_previous">Music: Previous</string> <string name="list_other_track_play_pause">Music: Play / Pause</string> <string name="list_other_expand_notifications_panel">Expand notifications panel</string> + <string name="list_other_recent_apps">Recent Apps</string> <string name="list_other_nop">Do nothing</string> <string name="list_other_lock_screen">Lock Screen</string> <string name="list_other_torch">Toggle Torch</string> @@ -307,6 +308,8 @@ <string name="alert_no_torch_found">No camera with torch detected.</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_recent_apps_failed">Error: Failed to show recent apps. (If you just upgraded the app, try to disable and re-enable the accessibility service in phone settings)</string> + <string name="alert_enable_accessibility_failed">Error: Failed to enable the accessibility service.</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> @@ -315,12 +318,17 @@ <string name="tooltip_lock_private_space">Lock private space</string> <string name="tooltip_unlock_private_space">Unlock 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="accessibility_service_name">μLauncher - lock screen</string> + <string name="accessibility_service_name">μLauncher</string> <string name="accessibility_service_description"> - Setting μLauncher as an accessibility service allows it to lock the screen. + Setting μLauncher as an accessibility service allows it to lock the screen and open the recent apps menu. Note that excessive permissions are required. You should never grant such permissions lightly to any app. - μLauncher will use the accessibility service only for locking the screen. You can check the source code to make sure. + μLauncher will use the accessibility service only for performing the following actions when requested by the user: + + * lock screen + * open recent apps + + μLauncher will never use the accessibility service to collect data. You can check the source code to make sure. Note that locking the screen can also be accomplished by granting μLauncher device administrator permissions. However that method doesn\'t work with fingerprint and face unlock. </string> @@ -365,7 +373,12 @@ <string name="dialog_consent_accessibility_other_options">I am aware that other options exist (using device administrator privileges or the power button).</string> <string name="dialog_consent_accessibility_consent">I consent to μLauncher using the accessibility service to provide functionality unrelated to accessibility.</string> <string name="dialog_consent_accessibility_data_collection">I consent to μLauncher not collecting any data.</string> - <string name="dialog_consent_accessibility_text"><![CDATA[You are about to activate the accessibility service. This will grant <strong>far-reaching privileges</strong> to μLauncher.<br/>μLauncher will use these privileges <strong>only to lock the screen</strong>. μLauncher <strong>will never collect any data</strong>. In particular, μLauncher does not use the accessibility service to collect any data.]]></string> + <string name="dialog_consent_accessibility_text"><![CDATA[You are about to activate the accessibility service. This will grant <strong>far-reaching privileges</strong> to μLauncher.<br/>μLauncher will use these privileges <strong>only</strong> to perform the following actions: + <ul> + <li>Lock Screen</li> + <li>Recent Apps</li> + </ul> + μLauncher <strong>will never collect any data</strong>. In particular, μLauncher does not use the accessibility service to collect any data.]]></string> <string name="dialog_consent_accessibility_title">Activating the Accessibility Service</string> <string name="dialog_consent_accessibility_ok">Activate Accessibility Service</string> <string name="dialog_cancel">Cancel</string> From 5d695ec0ea49177cf4627196e8ebcf2e7a1ce886 Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Sat, 29 Mar 2025 18:45:53 +0100 Subject: [PATCH 51/73] fix #135 --- app/src/main/java/de/jrpie/android/launcher/Functions.kt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) 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 7bbbdb5..df57008 100644 --- a/app/src/main/java/de/jrpie/android/launcher/Functions.kt +++ b/app/src/main/java/de/jrpie/android/launcher/Functions.kt @@ -38,6 +38,8 @@ import androidx.core.net.toUri const val LOG_TAG = "Launcher" +const val REQUEST_SET_DEFAULT_HOME = 42 + fun isDefaultHomeScreen(context: Context): Boolean { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { val roleManager = context.getSystemService(RoleManager::class.java) @@ -62,8 +64,9 @@ fun setDefaultHomeScreen(context: Context, checkDefault: Boolean = false) { && !isDefault // using role manager only works when µLauncher is not already the default. ) { val roleManager = context.getSystemService(RoleManager::class.java) - context.startActivity( - roleManager.createRequestRoleIntent(RoleManager.ROLE_HOME) + context.startActivityForResult( + roleManager.createRequestRoleIntent(RoleManager.ROLE_HOME), + REQUEST_SET_DEFAULT_HOME ) return } From 653d16b269f609d9de0c523d9f3bd56930e29302 Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Sat, 29 Mar 2025 21:09:15 +0100 Subject: [PATCH 52/73] new action: launch other launchers --- .../java/de/jrpie/android/launcher/Functions.kt | 2 +- .../android/launcher/actions/LauncherAction.kt | 15 +++++++++++++++ app/src/main/res/drawable/baseline_home_24.xml | 11 +++++++++++ app/src/main/res/values/strings.xml | 1 + 4 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 app/src/main/res/drawable/baseline_home_24.xml 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 df57008..afc2c31 100644 --- a/app/src/main/java/de/jrpie/android/launcher/Functions.kt +++ b/app/src/main/java/de/jrpie/android/launcher/Functions.kt @@ -61,7 +61,7 @@ fun setDefaultHomeScreen(context: Context, checkDefault: Boolean = false) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && context is Activity - && !isDefault // using role manager only works when µLauncher is not already the default. + && checkDefault // using role manager only works when µLauncher is not already the default. ) { val roleManager = context.getSystemService(RoleManager::class.java) context.startActivityForResult( 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 ee9502c..6ba467e 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 @@ -154,6 +154,12 @@ enum class LauncherAction( R.drawable.baseline_flashlight_on_24, ::toggleTorch, ), + LAUNCH_OTHER_LAUNCHER( + "launcher_other_launcher", + R.string.list_other_launch_other_launcher, + R.drawable.baseline_home_24, + ::launchOtherLauncher + ), NOP("nop", R.string.list_other_nop, R.drawable.baseline_not_interested_24, {}); override fun invoke(context: Context, rect: Rect?): Boolean { @@ -258,6 +264,15 @@ private fun expandSettingsPanel(context: Context) { } } +private fun launchOtherLauncher(context: Context) { + context.startActivity( + Intent.createChooser( + Intent(Intent.ACTION_MAIN).also { it.addCategory(Intent.CATEGORY_HOME) }, + context.getString(R.string.list_other_launch_other_launcher) + ) + ) +} + private fun openSettings(context: Context) { context.startActivity(Intent(context, SettingsActivity::class.java)) } diff --git a/app/src/main/res/drawable/baseline_home_24.xml b/app/src/main/res/drawable/baseline_home_24.xml new file mode 100644 index 0000000..935d1b6 --- /dev/null +++ b/app/src/main/res/drawable/baseline_home_24.xml @@ -0,0 +1,11 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + + <path + android:fillColor="?android:textColor" + android:pathData="M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z" /> + +</vector> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 83b963b..a8bc9b3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -256,6 +256,7 @@ <string name="list_other_nop">Do nothing</string> <string name="list_other_lock_screen">Lock Screen</string> <string name="list_other_torch">Toggle Torch</string> + <string name="list_other_launch_other_launcher">Launch other Home Screen</string> <!-- Pin shortcuts --> <string name="pin_shortcut_title">Add Shortcut</string> From e7c1d285766bb0f8a3625653158d70a15b72abf1 Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Sun, 13 Apr 2025 14:40:57 +0200 Subject: [PATCH 53/73] upgrade AGP --- .scripts/release.sh | 2 +- build.gradle | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.scripts/release.sh b/.scripts/release.sh index 0c71f4a..f207c87 100755 --- a/.scripts/release.sh +++ b/.scripts/release.sh @@ -1,5 +1,5 @@ #!/bin/bash -export JAVA_HOME="/usr/lib/jvm/java-23-openjdk/" +export JAVA_HOME="/usr/lib/jvm/java-21-openjdk/" OUTPUT_DIR="$HOME/launcher-release" BUILD_TOOLS_DIR="$HOME/Android/Sdk/build-tools/35.0.0" KEYSTORE="$HOME/data/keys/launcher_jrpie.jks" diff --git a/build.gradle b/build.gradle index 2bb501f..57dd74a 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ buildscript { ext.kotlin_version = '2.0.0' - ext.android_plugin_version = '8.9.0' + ext.android_plugin_version = '8.9.1' repositories { google() mavenCentral() @@ -10,7 +10,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:8.9.0' + classpath 'com.android.tools.build:gradle:8.9.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "com.android.tools.build:gradle:$android_plugin_version" classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version" From 0441b3fd3d76cde098c496327b42af20a2f9b929 Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Sun, 13 Apr 2025 14:54:11 +0200 Subject: [PATCH 54/73] set max width for choose app button; change label from scegliere l'applicazione to scegliere in Italian --- app/src/main/res/layout/settings_actions_row.xml | 6 ++++-- app/src/main/res/values-it/strings.xml | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/layout/settings_actions_row.xml b/app/src/main/res/layout/settings_actions_row.xml index df449c4..a60a5a4 100644 --- a/app/src/main/res/layout/settings_actions_row.xml +++ b/app/src/main/res/layout/settings_actions_row.xml @@ -43,13 +43,15 @@ android:id="@+id/settings_actions_row_button_choose" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:ellipsize="end" + android:maxLines="2" + android:maxWidth="100dp" android:text="@string/settings_apps_choose" android:textAllCaps="false" android:visibility="invisible" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintTop_toTopOf="parent" - /> + app:layout_constraintTop_toTopOf="parent" /> <ImageView android:id="@+id/settings_actions_row_icon_img" diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index a01b8e7..db80232 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -2,7 +2,7 @@ <resources> <string name="settings_gesture_description_right_bottom_edge">Scorri verso destra sul bordo inferiore dello schermo</string> <string name="settings_launcher_section_appearance">Aspetto</string> - <string name="settings_apps_choose">Scegliere l\'applicazione</string> + <string name="settings_apps_choose">Scegliere</string> <string name="settings_theme_color_theme">Tema</string> <string name="tutorial_concept_text">Questo launcher è progettato per essere minimale, efficiente e privo di distrazioni. Non contiene pagamenti, pubblicità o servizi di tracciamento.</string> <string name="settings_theme_color_theme_item_default">Predefinito</string> From e6dd2634ae434bdde7a47fb24e8f5b251f7e3c3a Mon Sep 17 00:00:00 2001 From: class0068 <monkeyotw@proton.me> Date: Tue, 18 Mar 2025 19:41:41 +0000 Subject: [PATCH 55/73] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (254 of 254 strings) Translation: jrpie-Launcher/Launcher Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/zh_Hans/ --- app/src/main/res/values-zh-rCN/strings.xml | 32 +++++++++++----------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 55376c3..12e6a68 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -104,7 +104,7 @@ <string name="settings_apps_hide_bound_apps">不要在应用抽屉中显示被绑定到手势的应用</string> <string name="alert_requires_android_m">此功能需要 Android 6 或更高版本。</string> <string name="snackbar_app_hidden">应用程序已隐藏。您可在设置中让它再次显示。</string> - <string name="toast_device_admin_not_enabled">µLauncher 需要获得设备管理员权限才能够锁定屏幕。</string> + <string name="toast_device_admin_not_enabled">µLauncher 需要激活“设备管理应用”权限才能够锁定屏幕。</string> <string name="device_admin_explanation">这是执行锁屏操作所必需的。</string> <string name="accessibility_service_name">µLauncher - 锁屏</string> <string name="list_title_favorite">收藏的应用</string> @@ -158,16 +158,16 @@ <string name="settings_enabled_gestures_edge_swipe_edge_width">边缘宽度</string> <string name="list_app_rename">重命名</string> <string name="device_admin_description">启用锁屏动作</string> - <string name="toast_accessibility_service_not_enabled">μLauncher 的无障碍服务未启用,请在设置中启用它。</string> - <string name="toast_lock_screen_not_supported">错误:此设备不支持使用无障碍功能锁定屏幕。请改用设备管理员模式。</string> - <string name="screen_lock_method_use_accessibility">使用无障碍服务</string> - <string name="screen_lock_method_use_device_admin">使用设备管理员模式</string> + <string name="toast_accessibility_service_not_enabled">μLauncher 的“无障碍”服务未启用,请在设置中启用它。</string> + <string name="toast_lock_screen_not_supported">错误:此设备不支持使用“无障碍”服务锁定屏幕。请改用激活“设备管理应用”权限。</string> + <string name="screen_lock_method_use_accessibility">使用“无障碍”服务</string> + <string name="screen_lock_method_use_device_admin">激活“设备管理应用”权限</string> <string name="dialog_cancel">取消</string> <string name="settings_theme_color_theme_item_light">亮色</string> <string name="list_other_expand_settings_panel">快速设置</string> - <string name="alert_lock_screen_failed">错误:锁定屏幕失败。(如果您刚刚升级了本启动器,请尝试在手机设置中手动禁用并重新启用无障碍服务)</string> + <string name="alert_lock_screen_failed">错误:锁定屏幕失败。(如果您刚刚升级了本启动器,请尝试在手机设置中手动禁用并重新启用“无障碍”服务)</string> <string name="settings_enabled_gestures_edge_swipe_summary">在屏幕边缘滑动</string> - <string name="accessibility_service_description">将 µLauncher 设为无障碍服务允许其锁定屏幕。请注意,这需要过多的权限。你永远不应该轻易地授予任何应用程序这样的权限。µLauncher 将仅使用无障碍服务功能锁屏。您可以审核源代码。请注意,锁屏也可以通过授予 µLauncher 设备管理员权限来实现,然而,这种方法不适用于以指纹和面部解锁。</string> + <string name="accessibility_service_description">将 µLauncher 设置为“无障碍”服务以允许其锁定屏幕。请注意,这会使 µLauncher 获得额外的权限。你永远不应该轻易地授予任何应用程序这样的权限。获得授权后“无障碍”服务将仅被用于锁定屏幕。您可以审核我们的源代码。请注意,锁定屏幕也可以通过激活 µLauncher 的“设备管理应用”权限来实现,然而,这种方法无法与于指纹解锁和面部解锁兼容。</string> <string name="settings_gesture_back">返回</string> <string name="dialog_select_color_red">红色</string> <string name="dialog_select_color_blue">蓝色</string> @@ -193,8 +193,8 @@ <string name="dialog_report_bug_button_clipboard">复制到剪贴板</string> <string name="alert_requires_android_v">此功能需要 Android 15 或更高版本。</string> <string name="list_other_toggle_private_space_lock">切换私人空间锁</string> - <string name="dialog_consent_accessibility_ok">激活无障碍服务</string> - <string name="dialog_consent_accessibility_title">正在激活无障碍服务</string> + <string name="dialog_consent_accessibility_ok">激活“无障碍”服务</string> + <string name="dialog_consent_accessibility_title">正在激活“无障碍”服务</string> <string name="settings_meta_licenses">开源许可证</string> <string name="legal_info_title">开源许可证</string> <string name="pin_shortcut_switch_visible">在应用列表中显示</string> @@ -219,8 +219,8 @@ 有2种方式可以用来锁定屏幕。 遗憾的是,两者都有缺点:<br/><br/> - <h3>通过设置“设备管理应用”</h3> - 无法和指纹解锁和脸部解锁共同使用。 + <h3>通过激活“设备管理应用”权限</h3> + 该方法无法和指纹解锁和脸部解锁共同使用。 <br/> <br/> @@ -229,16 +229,16 @@ 需要更多的权限。 μLauncher 将这些权限仅用于锁定屏幕。 <br/> - (对于任何一个从网上下载的应用所做的类似声明,你都不应该抱持“默认为可信”的态度,你可以并应该检查一下它的<a href=\"https://github.com/jrpie/Launcher\">源代码</a>.) + (对于任何一个从网上下载的应用所做的类似声明,你都不应该抱持“默认为可信”的态度,你可以并应该检查一下它的<a href=\"https://github.com/jrpie/Launcher\">源代码</a>.) <br/> - 在某些设备上,激活辅助功能服务后,启动PIN码将不再用于加密数据。 - 如果遇到该问题,可以通过<a href="https://issuetracker.google.com/issues/37010136#comment36">该方法</a>重新激活启动PIN码用于数据加密。 + 在某些设备上,激活“无障碍”服务后,启动 PIN 码将不再用于加密数据。 + 如果遇到该问题,可以通过<a href="https://issuetracker.google.com/issues/37010136#comment36">该方法</a>重新激活启动 PIN 码用于数据加密。 <br/><br/><br/><br/> 你可以在设置中随时更改这个选项。 ]]></string> <string name="list_apps_search_hint_no_auto_launch">搜索(不触发自动启动匹配项)</string> - <string name="dialog_consent_accessibility_text"><![CDATA[您即将激活“无障碍”服务。这将授予 μLauncher <strong>广泛且重要的权限</strong>。<br/>μLauncher 将这些权限<strong>仅用于锁定屏幕</strong>。µLauncher <strong>绝不会收集任何数据</strong>。尤其是,μLauncher 不会使用“无障碍”服务来收集任何数据。]]></string> + <string name="dialog_consent_accessibility_text"><![CDATA[您即将激活“无障碍”服务。这将授予 μLauncher <strong>广泛且重要的权限</strong>。<br/>但 μLauncher <strong>仅会在需要锁定屏幕时</strong>使用这些权限。µLauncher <strong>绝不会收集任何数据</strong>。尤其是,μLauncher 不会使用“无障碍”服务来收集任何数据。]]></string> <string name="settings_gesture_description_swipe_larger">(从)左上 (滑向)中右(滑向)左下</string> <string name="settings_gesture_tap_up">单击 + 上滑</string> <string name="settings_gesture_tap_down">单击 + 下滑</string> @@ -263,7 +263,7 @@ <string name="dialog_report_bug_button_security">报告安全漏洞</string> <string name="dialog_report_bug_security_info">请不要在 Github 上以公开的方式报告安全漏洞,请使用以下方式进行报告:</string> <string name="dialog_report_bug_info">感谢您帮助改进 µLauncher!\n请考虑在您的应用程序错误反馈中添加以下信息:</string> - <string name="dialog_consent_accessibility_other_options">我已知晓,还有其他替代方法(使用设备管理员模式或电源按键)。</string> + <string name="dialog_consent_accessibility_other_options">我已知晓,还有其他替代方法(激活“设备管理应用”权限或通过电源按键)。</string> <string name="dialog_consent_accessibility_data_collection">我同意 μLauncher 不收集任何数据。</string> <string name="settings_meta_donate">捐赠</string> <string name="list_other_volume_adjust">调整音量</string> From 8a487eb4c78a07b1f646bc64227625ff3694fce8 Mon Sep 17 00:00:00 2001 From: class0068 <monkeyotw@proton.me> Date: Thu, 20 Mar 2025 23:06:32 +0000 Subject: [PATCH 56/73] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (254 of 254 strings) Translation: jrpie-Launcher/Launcher Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/zh_Hans/ --- app/src/main/res/values-zh-rCN/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 12e6a68..e5ca8ac 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -13,7 +13,7 @@ <string name="alert_cant_open_title">无法打开应用</string> <string name="alert_cant_open_message">要更改其设置吗?</string> <string name="toast_cant_open_message">打开设置,为该手势绑定一个应用程序</string> - <string name="settings_tab_app">应用程序</string> + <string name="settings_tab_app">快捷操作</string> <string name="settings_tab_launcher">启动器</string> <string name="settings_tab_meta">杂项</string> <string name="settings_gesture_left">左</string> From 4f801427a41d890788e1e3dd54eb1cc8d1513592 Mon Sep 17 00:00:00 2001 From: toolatebot <toolate@othing.xyz> Date: Fri, 21 Mar 2025 00:07:18 +0000 Subject: [PATCH 57/73] Update translation files Updated by "Cleanup translation files" add-on in Weblate. Translation: jrpie-Launcher/Launcher Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/ --- app/src/main/res/values-es/strings.xml | 1 - app/src/main/res/values-fr/strings.xml | 1 - app/src/main/res/values-it/strings.xml | 1 - app/src/main/res/values-ja/strings.xml | 1 - app/src/main/res/values-pt-rBR/strings.xml | 1 - app/src/main/res/values-tr/strings.xml | 1 - app/src/main/res/values-zh-rCN/strings.xml | 1 - 7 files changed, 7 deletions(-) diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index ccbeb3f..4a363b0 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -23,7 +23,6 @@ - --> <string name="settings_title">Configuración</string> - <string name="settings_tab_app">Aplicaciones</string> <string name="settings_tab_launcher">Launcher</string> <string name="settings_tab_meta">Meta</string> <!-- diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index e84d6ae..c1d11b3 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -14,7 +14,6 @@ - --> <string name="settings_title">Réglages</string> - <string name="settings_tab_app">Applications</string> <string name="settings_tab_launcher">Launcher</string> <string name="settings_tab_meta">Meta</string> <!-- diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index db80232..318ad43 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -38,7 +38,6 @@ <string name="alert_cant_open_message">Desideri modificare le impostazioni?</string> <string name="toast_cant_open_message">Apri le impostazioni per abbinare un\'azione a questo gesto</string> <string name="settings_title">Impostazioni</string> - <string name="settings_tab_app">Applicazioni</string> <string name="settings_tab_launcher">Launcher</string> <string name="settings_tab_meta">Meta</string> <string name="settings_gesture_description_double_down">Scorri verso il basso con due dita</string> diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 050d750..6d081f0 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -3,7 +3,6 @@ <string name="alert_cant_open_title">アプリを開けません</string> <string name="alert_cant_open_message">設定を変更しますか?</string> <string name="settings_title">設定</string> - <string name="settings_tab_app">アプリ</string> <string name="settings_tab_launcher">ランチャー</string> <string name="settings_tab_meta">その他</string> <string name="toast_cant_open_message">このジェスチャのアクションを選択するには設定を開きます</string> diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index f0c0295..c39f0cb 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -14,7 +14,6 @@ - --> <string name="settings_title">Configurações</string> - <string name="settings_tab_app">Apps</string> <string name="settings_tab_launcher">Launcher</string> <string name="settings_tab_meta">Meta</string> <!-- diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 0cc240e..8c5a2e7 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -52,7 +52,6 @@ <string name="alert_cant_open_message">Ayarlarını değiştirmek ister misiniz?</string> <string name="toast_cant_open_message">Bu harekete bir eylem atamak için ayarları açın</string> <string name="settings_title">Ayarlar</string> - <string name="settings_tab_app">Uygulamalar</string> <string name="settings_tab_launcher">Başlatıcı</string> <string name="settings_tab_meta">Daha Fazlası</string> <string name="settings_gesture_up">Yukarı</string> diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index e5ca8ac..3eeaf50 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -13,7 +13,6 @@ <string name="alert_cant_open_title">无法打开应用</string> <string name="alert_cant_open_message">要更改其设置吗?</string> <string name="toast_cant_open_message">打开设置,为该手势绑定一个应用程序</string> - <string name="settings_tab_app">快捷操作</string> <string name="settings_tab_launcher">启动器</string> <string name="settings_tab_meta">杂项</string> <string name="settings_gesture_left">左</string> From 8b1963f3e189824af2be3a6feb1d94ba26f80ef9 Mon Sep 17 00:00:00 2001 From: T <toolate.c1i0c@silomails.com> Date: Sat, 22 Mar 2025 18:13:35 +0000 Subject: [PATCH 58/73] Translated using Weblate (Spanish) Currently translated at 98.0% (249 of 254 strings) Translation: jrpie-Launcher/Launcher Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/es/ --- app/src/main/res/values-es/strings.xml | 235 ++++++++++++++++++++++--- 1 file changed, 215 insertions(+), 20 deletions(-) diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 4a363b0..1a04590 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -16,7 +16,7 @@ --> <string name="alert_cant_open_title">No se pudo abrir la aplicación</string> <string name="alert_cant_open_message">¿Desea cambiar la configuración?</string> - <string name="toast_cant_open_message">Abra la configuración para elegir una aplicación para esta acción</string> + <string name="toast_cant_open_message">Abra la configuración para elegir una acción para este gesto</string> <!-- - - Settings @@ -30,20 +30,20 @@ - Settings : Apps - --> - <string name="settings_gesture_up">Deslizar Arriba</string> + <string name="settings_gesture_up">Arriba</string> <string name="settings_gesture_double_up">Doble Arriba</string> - <string name="settings_gesture_down">Deslizar Abajo</string> + <string name="settings_gesture_down">Abajo</string> <string name="settings_gesture_double_down">Doble Abajo</string> - <string name="settings_gesture_left">Deslizar Izquierda</string> + <string name="settings_gesture_left">Izquierda</string> <string name="settings_gesture_double_left">Doble Izquierda</string> - <string name="settings_gesture_right">Deslizar Derecha</string> + <string name="settings_gesture_right">Derecha</string> <string name="settings_gesture_double_right">Doble Derecha</string> - <string name="settings_gesture_vol_up">Subir Volumen</string> - <string name="settings_gesture_vol_down">Bajar Volumen</string> + <string name="settings_gesture_vol_up">Tecla para subir el volumen</string> + <string name="settings_gesture_vol_down">Tecla para bajar el volumen</string> <string name="settings_gesture_double_click">Doble Click</string> <string name="settings_gesture_long_click">Click Largo</string> - <string name="settings_gesture_date">Toca la fecha</string> - <string name="settings_gesture_time">Toca el reloj</string> + <string name="settings_gesture_date">Fecha</string> + <string name="settings_gesture_time">reloj</string> <string name="settings_apps_choose">Elegir Aplicación</string> <string name="settings_apps_install">Instalar aplicaciones</string> <string name="settings_apps_toast_store_not_found">No se encontró la Store</string> @@ -72,7 +72,7 @@ --> <string name="settings_general_choose_home_screen">Seleccionar Launcher</string> <string name="settings_meta_cant_select_launcher">Información de la aplicación</string> - <string name="settings_meta_show_tutorial">Ver tutorial de Launcher</string> + <string name="settings_meta_show_tutorial">Ver el tutorial de µLauncher</string> <string name="settings_meta_reset">Configuración por defecto</string> <string name="settings_meta_reset_confirm">Todas sus preferencias se eliminarán. Desea continuar?</string> <string name="settings_meta_report_bug">Reportar un error</string> @@ -91,11 +91,11 @@ <string name="list_tab_other">Otros</string> <string name="list_app_delete">Desinstalar</string> <string name="list_app_info">Información</string> - <string name="list_apps_search_hint">Buscar Aplicaciones</string> - <string name="list_other_settings">Configuración de Launcher</string> + <string name="list_apps_search_hint">Buscar</string> + <string name="list_other_settings">Configuración de μLauncher</string> <string name="list_other_list">Aplicaciones</string> - <string name="list_other_volume_up">Música: Subir</string> - <string name="list_other_volume_down">Música: Bajar</string> + <string name="list_other_volume_up">Subir el volumen</string> + <string name="list_other_volume_down">Bajar volumen</string> <string name="list_other_track_next">Música: Siguiente</string> <string name="list_other_track_previous">Música: Anterior</string> <string name="list_other_nop">Nada</string> @@ -105,19 +105,214 @@ - --> <string name="tutorial_title">Tutorial</string> - <string name="tutorial_start_text">Tómate unos segundos para aprender a usar este launcher</string> + <string name="tutorial_start_text">👋\n\n¡Tómate unos segundos para aprender a utilizar este Launcher!</string> <string name="tutorial_concept_title">Concepto</string> - <string name="tutorial_concept_text">Launcher está diseñado para ser minimalista, eficiente y libre de distracciones.\n\nEs gratis y libre de anuncios y servicios de rastreo.</string> - <string name="tutorial_concept_text_2">La aplicación es de código abierto (licencia MIT) y está disponible en GitHub!\n\nNo olvides echarle un vistazo al repositorio!</string> + <string name="tutorial_concept_text">μLauncher está diseñado para ser mínimo, eficiente y libre de distracciones.\n\nNo contiene anuncios ni recopila datos.</string> + <string name="tutorial_concept_text_2">¡Es software libre (licencia MIT)!\n¡No olvides visitar el repositorio!</string> <string name="tutorial_usage_title">Uso</string> <string name="tutorial_usage_text">Tu pantalla de inicio contiene la fecha y hora local. Sin distracciones.</string> - <string name="tutorial_usage_text_2">Puedes iniciar tus aplicaciones con solo presionar o deslizar una vez. Elige algunas en la siguiente pantalla.</string> + <string name="tutorial_usage_text_2">Puede iniciar sus aplicaciones más importantes con gestos táctiles o presionando botones.</string> <string name="tutorial_setup_title">Puesta a punto</string> - <string name="tutorial_setup_text">Elegimos algunas aplicaciones por defecto para ti, si lo deseas puedes cambiarlas ahora.</string> + <string name="tutorial_setup_text">Elegimos algunas aplicaciones predeterminadas para ti. Puedes cambiarlos ahora si lo deseas:</string> <string name="tutorial_setup_text_2">También puedes cambiar tu selección más tarde.</string> <string name="tutorial_finish_title">Vamos!</string> - <string name="tutorial_finish_text">Estás listo para iniciar!\n\n Esperamos que esto te sea de gran ayuda!\n\n- Finn M Glas\n(el desarrollador)</string> + <string name="tutorial_finish_text">¡Estás listo para comenzar!\n\n¡Espero que esto sea de gran valor para ti!\n\n- Finn (quien creó Launcher) y Josia (quien hizo algunas mejoras y mantiene la bifurcación μLauncher)</string> <string name="tutorial_finish_button">Iniciar</string> <string name="settings">Configuración</string> <string name="ic_menu_alt">Más opciones</string> + <string name="settings_gesture_back">atrás</string> + <string name="settings_gesture_description_tap_right">Toca + Derecha Toca y desliza hacia la derecha</string> + <string name="settings_gesture_description_left_bottom_edge">Desliza el dedo hacia la izquierda en la parte inferior de la pantalla</string> + <string name="settings_gesture_description_down_right_edge">Desliza hacia abajo en el borde derecho de la pantalla</string> + <string name="settings_gesture_description_back">Botón de retroceso / gesto de retroceso</string> + <string name="settings_gesture_description_up_left_edge">Desliza el dedo hacia arriba en el borde izquierdo de la pantalla</string> + <string name="settings_gesture_description_up_right_edge">Desliza el dedo hacia arriba en el borde derecho de la pantalla</string> + <string name="settings_gesture_description_down_left_edge">Desliza el dedo hacia abajo en el borde izquierdo de la pantalla</string> + <string name="settings_theme_color_theme_item_dynamic">Dinámico</string> + <string name="settings_clock_color">Color</string> + <string name="settings_gesture_description_tap_up">Toca y desliza hacia arriba</string> + <string name="settings_gesture_tap_left">Toque + Izquierda</string> + <string name="settings_gesture_description_right_bottom_edge">Desliza el dedo hacia la derecha en la parte inferior de la pantalla</string> + <string name="settings_gesture_description_left_top_edge">Desliza el dedo hacia la izquierda en la parte superior de la pantalla</string> + <string name="settings_gesture_down_left_edge">Abajo (borde izquierdo)</string> + <string name="settings_gesture_description_vol_up">Presione el botón para subir el volumen</string> + <string name="settings_functionality_auto_launch_summary">Presione la barra espaciadora para desactivar esta función temporalmente.</string> + <string name="settings_launcher_section_apps">Aplicaciones</string> + <string name="settings_gesture_description_swipe_v">Arriba a la izquierda -> Abajo en el medio -> Arriba a la derecha</string> + <string name="settings_functionality_search_web_summary">Presione regresar mientras busca en la lista de aplicaciones para iniciar una búsqueda web.</string> + <string name="alert_torch_access_exception">Error: No se puede acceder a la antorcha.</string> + <string name="settings_theme_background">Fondo (lista de aplicaciones y configuración)</string> + <string name="settings_theme_color_theme">Tema de color</string> + <string name="settings_theme_font">Fuente</string> + <string name="settings_theme_monochrome_icons">Iconos de aplicaciones monocromáticos</string> + <string name="settings_gesture_right_top_edge">Derecha (arriba)</string> + <string name="settings_gesture_right_bottom_edge">Derecha (Abajo)</string> + <string name="settings_gesture_left_top_edge">Izquierda (arriba)</string> + <string name="dialog_consent_accessibility_text"><![CDATA[Está a punto de activar el servicio de accesibilidad. Esto otorgará privilegios de amplio alcance a μLauncher. μLauncher utilizará estos privilegios solo para bloquear la pantalla. μLauncher <strong>nunca recopilará ningún dato</strong>. En particular, μLauncher no utiliza el servicio de accesibilidad para recopilar ningún dato.]]></string> + <string name="accessibility_service_description">Configurar μLauncher como un servicio de accesibilidad le permite bloquear la pantalla. Tenga en cuenta que se requieren permisos excesivos. Nunca debe otorgar dichos permisos a la ligera a ninguna aplicación. μLauncher utilizará el servicio de accesibilidad solo para bloquear la pantalla. Puedes consultar el código fuente para asegurarte. Tenga en cuenta que también se puede bloquear la pantalla otorgando permisos de administrador del dispositivo μLauncher. Sin embargo, ese método no funciona con el desbloqueo mediante huellas dactilares y rostro.</string> + <string name="settings_apps_hide_private_space_apps">Ocultar el espacio privado de la lista de aplicaciones</string> + <string name="settings_list_layout">Diseño de la lista de aplicaciones</string> + <string name="list_title_private_space">Espacio privado</string> + <string name="alert_no_torch_found">No se detectó ninguna cámara con linterna.</string> + <string name="list_other_toggle_private_space_lock">Activar o desactivar el bloqueo del espacio privado</string> + <string name="list_other_torch">Activar o desactivar la antorcha</string> + <string name="settings_apps_hide_paused_apps">Ocultar aplicaciones pausadas</string> + <string name="settings_apps_hidden">Aplicaciones ocultas</string> + <string name="dialog_rename_title">Cambiar el nombre de %1$s</string> + <string name="dialog_cancel">Cancelar</string> + <string name="settings_gesture_swipe_v">V</string> + <string name="dialog_report_bug_title">Informar un error</string> + <string name="list_app_hidden_remove">mostrar</string> + <string name="toast_private_space_default_home_screen">μLauncher debe ser la pantalla de inicio predeterminada para acceder al espacio privado.</string> + <string name="dialog_report_bug_security_info">No informe vulnerabilidades de seguridad públicamente en GitHub, sino utilice lo siguiente:</string> + <string name="dialog_report_bug_button_security">Informar sobre una vulnerabilidad de seguridad</string> + <string name="dialog_report_bug_create_report">Crear informe</string> + <string name="settings_meta_join_chat">Únete al chat de μLauncher</string> + <string name="settings_meta_donate">Donar</string> + <string name="list_other_volume_adjust">Ajustar el volumen</string> + <string name="list_other_expand_notifications_panel">Expandir el panel de notificaciones</string> + <string name="toast_private_space_not_available">El espacio privado no está disponible</string> + <string name="settings_gesture_description_up">Desliza hacia arriba</string> + <string name="settings_gesture_description_double_click">Haga doble clic en un área vacía</string> + <string name="settings_gesture_description_vol_down">Presione el botón para bajar el volumen</string> + <string name="settings_gesture_description_long_click">Haga clic largo en un área vacía</string> + <string name="settings_gesture_description_date">Haga clic en la fecha</string> + <string name="settings_gesture_description_time">Haga clic en el reloj</string> + <string name="settings_clock_time_visible">Mostrar la hora</string> + <string name="settings_theme_text_shadow">Sombra de texto</string> + <string name="settings_display_hide_status_bar">Ocultar la barra de estado</string> + <string name="settings_display_hide_navigation_bar">Ocultar la barra de navegación</string> + <string name="settings_enabled_gestures_double_swipe_summary">Deslizar con dos dedos</string> + <string name="settings_list_layout_item_default">predeterminado</string> + <string name="list_title_favorite">Aplicaciones favoritas</string> + <string name="list_title_hidden">Aplicaciones ocultas</string> + <string name="undo">Deshacer</string> + <string name="dialog_consent_accessibility_consent">Doy mi consentimiento para que μLauncher utilice el servicio de accesibilidad para proporcionar una funcionalidad no relacionada con la accesibilidad.</string> + <string name="list_apps_search_hint_no_auto_launch">Buscar (sin inicio automático)</string> + <string name="dialog_consent_accessibility_privileges">Soy consciente de que esto otorgará privilegios de gran alcance a μLauncher.</string> + <string name="dialog_consent_accessibility_other_options">Soy consciente de que existen otras opciones (utilizando privilegios de administrador del dispositivo o el botón de encendido).</string> + <string name="settings_meta_licenses">Licencias de código abierto</string> + <string name="legal_info_title">Licencias de código abierto</string> + <string name="tutorial_concept_label_version">versión</string> + <string name="tutorial_app_list_title">Todas las aplicaciones</string> + <string name="screen_lock_method_dialog_title">Elija el método para bloquear</string> + <string name="screen_lock_method_dialog_text"><![CDATA[ + Elegir método de bloqueo + Hay dos métodos para bloquear la pantalla. + Desafortunadamente, ambos tienen desventajas:<br/><br/> + + Administrador del dispositivo + No funciona con desbloqueo por huella dactilar ni reconocimiento facial. + + <br/> + <br/> + + Servicio de Accesibilidad + Requiere privilegios excesivos. + μLauncher utilizará esos privilegios solo para bloquear la pantalla. + <br/> + (Realmente no deberías confiar en una aplicación aleatoria que acabas de descargar con tal afirmación, pero puedes consultar el <a href=\"https://github.com/jrpie/Launcher\">código fuente</a>). + <br/> + En algunos dispositivos, el PIN de inicio ya no se utilizará para cifrar datos después de activar un servicio de accesibilidad. + Esto se puede <a href="https://issuetracker.google.com/issues/37010136#comment36">reactivar</a> posteriormente. + + <br/><br/><br/><br/> + Puede cambiar su selección más tarde en la configuración. + ]]></string> + <string name="screen_lock_method_use_accessibility">Utilice el servicio de accesibilidad</string> + <string name="screen_lock_method_use_device_admin">Usar el administrador del dispositivo</string> + <string name="settings_actions_lock_method">Elija el método para bloquear la pantalla</string> + <string name="dialog_select_color_red">Rojo</string> + <string name="dialog_select_color_alpha">alfa</string> + <string name="dialog_select_color_blue">Azul</string> + <string name="dialog_select_color_green">Verde</string> + <string name="settings_theme_font_item_sans_serif">Sans serif</string> + <string name="settings_theme_font_item_serif">Serif</string> + <string name="settings_theme_font_item_monospace">Monoespaciado</string> + <string name="settings_theme_font_item_serif_monospace">Serif monoespaciado</string> + <string name="settings_clock_date_visible">Mostrar la fecha</string> + <string name="settings_clock_localized">Utilice el formato de fecha localizado</string> + <string name="settings_clock_show_seconds">Mostrar segundos</string> + <string name="settings_clock_flip_date_time">Cambiar fecha y hora</string> + <string name="settings_display_rotate_screen">Girar la pantalla</string> + <string name="settings_enabled_gestures_edge_swipe">Acciones de deslizamiento de borde</string> + <string name="settings_enabled_gestures_edge_swipe_summary">Desliza el dedo por el borde de la pantalla</string> + <string name="settings_enabled_gestures_edge_swipe_edge_width">Ancho del borde</string> + <string name="settings_apps_hide_bound_apps">No mostrar aplicaciones que estén vinculadas a un gesto en la lista de aplicaciones</string> + <string name="settings_meta_view_code">Ver el código fuente</string> + <string name="dialog_report_bug_info">¡Gracias por ayudarnos a mejorar μLauncher!\nConsidere agregar la siguiente información a su informe de error:</string> + <string name="dialog_report_bug_button_clipboard">Copiar al portapapeles</string> + <string name="list_app_favorite_add">Añadir a favoritos</string> + <string name="list_app_favorite_remove">Eliminar de favoritos</string> + <string name="list_app_hidden_add">Esconder</string> + <string name="list_app_rename">Renombrar</string> + <string name="list_other_list_favorites">Aplicaciones favoritas</string> + <string name="list_other_list_private_space">Espacio privado</string> + <string name="tutorial_app_list_text">Puede buscar rápidamente entre todas las aplicaciones en la lista de aplicaciones.\n\nDesliza hacia arriba para abrirlo o asigne un gesto diferente.</string> + <string name="tutorial_app_list_text_2">Una vez que sólo coincide una aplicación, se inicia automáticamente.\nEsto se puede desactivar anteponiendo un espacio a la consulta.</string> + <string name="alert_cant_expand_status_bar_panel">Error: No se puede expandir la barra de estado. Esta acción utiliza una funcionalidad que no forma parte de la API de Android publicada. Lamentablemente, no parece funcionar en su dispositivo.</string> + <string name="alert_requires_android_m">Esta funcionalidad requiere Android 6 o posterior.</string> + <string name="alert_requires_android_v">Esta funcionalidad requiere Android 15 o posterior.</string> + <string name="snackbar_app_hidden">Aplicación oculta. Puedes hacerlo visible nuevamente en la configuración.</string> + <string name="list_other_expand_settings_panel">Configuración rápida</string> + <string name="toast_device_admin_not_enabled">μLauncher debe ser administrador del dispositivo para poder bloquear la pantalla.</string> + <string name="device_admin_explanation">Esto es necesario para la acción de la pantalla de bloqueo.</string> + <string name="device_admin_description">Habilitar la acción de bloqueo de pantalla</string> + <string name="alert_lock_screen_failed">Error: Error al bloquear la pantalla. (Si acaba de actualizar la aplicación, intente deshabilitar y volver a habilitar el servicio de accesibilidad en la configuración del teléfono)</string> + <string name="toast_accessibility_service_not_enabled">El servicio de accesibilidad de μLauncher no está habilitado. Por favor, habilítelo en la configuración</string> + <string name="toast_private_space_locked">Espacio privado bloqueado</string> + <string name="toast_private_space_unlocked">Espacio privado desbloqueado</string> + <string name="tooltip_lock_private_space">Bloquear el espacio privado</string> + <string name="tooltip_unlock_private_space">Desbloquear espacio privado</string> + <string name="toast_lock_screen_not_supported">Error: El bloqueo de la pantalla mediante accesibilidad no es compatible con este dispositivo. En su lugar, utilice el administrador del dispositivo.</string> + <string name="accessibility_service_name">μLauncher - pantalla de bloqueo</string> + <string name="dialog_select_color_color_hex">Color</string> + <string name="dialog_choose_color_title">Elige el color</string> + <string name="dialog_consent_accessibility_data_collection">Doy mi consentimiento para que μLauncher no recopile ningún dato.</string> + <string name="dialog_consent_accessibility_title">Activación del servicio de accesibilidad</string> + <string name="dialog_consent_accessibility_ok">Activar el servicio de accesibilidad</string> + <string name="toast_activity_not_found_search_web">No se encontró ninguna aplicación para gestionar la búsqueda.</string> + <string name="toast_activity_not_found_browser">No se puede abrir la URL: no se encontró ningún navegador.</string> + <string name="settings_tab_actions">Acciones</string> + <string name="settings_gesture_tap_up">Toca + Arriba</string> + <string name="settings_gesture_description_double_up">Desliza hacia arriba con dos dedos</string> + <string name="settings_gesture_description_down">Desliza hacia abajo</string> + <string name="settings_gesture_tap_down">Toque + Abajo</string> + <string name="settings_gesture_description_tap_down">Toca y desliza hacia abajo</string> + <string name="settings_gesture_description_double_down">Desliza hacia abajo con dos dedos</string> + <string name="settings_gesture_description_left">Desliza hacia la izquierda</string> + <string name="settings_gesture_description_tap_left">Toca y desliza hacia la izquierda</string> + <string name="settings_gesture_description_double_left">Desliza dos dedos hacia la izquierda</string> + <string name="settings_gesture_description_right">Desliza hacia la derecha</string> + <string name="settings_gesture_tap_right">Toque + Derecha</string> + <string name="settings_gesture_description_double_right">Desliza con dos dedos hacia la derecha</string> + <string name="settings_gesture_description_right_top_edge">Desliza el dedo hacia la derecha en la parte superior de la pantalla</string> + <string name="settings_gesture_left_bottom_edge">Izquierda (Abajo)</string> + <string name="settings_gesture_up_left_edge">Arriba (borde izquierdo)</string> + <string name="settings_gesture_up_right_edge">Arriba (borde derecho)</string> + <string name="settings_gesture_down_right_edge">Abajo (borde derecho)</string> + <string name="settings_gesture_description_swipe_larger">Arriba a la izquierda -> centro a la derecha -> abajo a la izquierda</string> + <string name="settings_gesture_description_swipe_larger_reverse">Abajo a la izquierda -> centro a la derecha -> arriba a la izquierda</string> + <string name="settings_gesture_description_swipe_smaller">Arriba a la derecha -> centro a la izquierda -> abajo a la derecha</string> + <string name="settings_gesture_description_swipe_smaller_reverse">Abajo a la derecha -> centro a la izquierda -> arriba a la derecha</string> + <string name="settings_gesture_swipe_v_reverse">V (Reversa)</string> + <string name="settings_gesture_description_swipe_v_reverse">Arriba a la derecha -> Abajo en el medio -> Arriba a la izquierda</string> + <string name="settings_gesture_swipe_lambda">Λ</string> + <string name="settings_gesture_description_swipe_lambda">Abajo a la izquierda -> arriba en el medio -> abajo a la derecha</string> + <string name="settings_gesture_swipe_lambda_reverse">Λ (Inverso)</string> + <string name="settings_gesture_description_swipe_lambda_reverse">Abajo a la derecha -> arriba en el medio -> abajo a la izquierda</string> + <string name="settings_theme_background_item_dim">Atenuación</string> + <string name="settings_theme_background_item_solid">Sólido</string> + <string name="settings_theme_font_item_system_default">Valor predeterminado del sistema</string> + <string name="settings_theme_background_item_transparent">Transparente</string> + <string name="settings_theme_background_item_blur">Difuminar</string> + <string name="settings_functionality_search_web">Buscar en la web</string> + <string name="settings_list_layout_item_text">texto</string> + <string name="settings_list_layout_item_grid">Red</string> + <string name="list_other_track_play_pause">Música: Reproducir / Pausa</string> + <string name="list_other_lock_screen">Pantalla de bloqueo</string> + <string name="pin_shortcut_title">Agregar acceso directo</string> + <string name="pin_shortcut_button_bind">Vincular al gesto</string> + <string name="pin_shortcut_switch_visible">Mostrar en la lista de aplicaciones</string> + <string name="settings_list_reverse_layout">Invertir la lista de aplicaciones</string> </resources> From bfc84b57ca573a8699dd6a9c29dc2482ca4c61c7 Mon Sep 17 00:00:00 2001 From: Vossa Excelencia <nationalistic.tention@hele.win> Date: Sat, 22 Mar 2025 16:48:40 +0000 Subject: [PATCH 59/73] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (254 of 254 strings) Translation: jrpie-Launcher/Launcher Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/pt_BR/ --- app/src/main/res/values-pt-rBR/strings.xml | 57 +++++++++++++--------- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index c39f0cb..4b2bcd2 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -37,8 +37,8 @@ <string name="settings_gesture_up_right_edge">Para cima (borda direita)</string> <string name="settings_gesture_down_left_edge">Para baixo (borda esquerda)</string> <string name="settings_gesture_down_right_edge">Para baixo (borda direita)</string> - <string name="settings_gesture_vol_up">Aumento de volume</string> - <string name="settings_gesture_vol_down">Diminuição de volume</string> + <string name="settings_gesture_vol_up">Botão de aumentar volume</string> + <string name="settings_gesture_vol_down">Botão de diminuição de volume</string> <string name="settings_gesture_double_click">Toque duplo</string> <string name="settings_gesture_long_click">Toque longo</string> <string name="settings_gesture_date">Data</string> @@ -76,7 +76,7 @@ --> <string name="settings_general_choose_home_screen">Definir o μLauncher como tela inicial</string> <string name="settings_meta_cant_select_launcher">Informações do aplicativo</string> - <string name="settings_meta_show_tutorial">Ver tutorial do launcher</string> + <string name="settings_meta_show_tutorial">Ver tutorial do µLauncher</string> <string name="settings_meta_reset">Redefinir configuraçãos</string> <string name="settings_meta_reset_confirm">Você vai descartar todas as suas preferências. Continuar?</string> <string name="settings_meta_report_bug">Reportar um bug</string> @@ -96,10 +96,10 @@ <string name="list_app_delete">Desinstalar</string> <string name="list_app_info">Informações do aplicativo</string> <string name="list_apps_search_hint">Busque</string> - <string name="list_other_settings">Configurações do µLauncher</string> + <string name="list_other_settings">Configurações do μLauncher</string> <string name="list_other_list">Todos os apps</string> - <string name="list_other_volume_up">Música: Mais alto</string> - <string name="list_other_volume_down">Música: Mais silencioso</string> + <string name="list_other_volume_up">Aumento de volume</string> + <string name="list_other_volume_down">Diminuição de volume</string> <string name="list_other_track_next">Música: Próximo</string> <string name="list_other_track_previous">Música: Anterior</string> <string name="list_other_nop">Não faça nada</string> @@ -109,18 +109,18 @@ - --> <string name="tutorial_title">Tutorial</string> - <string name="tutorial_start_text">Tire alguns segundos para aprender a usar este Launcher!</string> + <string name="tutorial_start_text">👋\n\nTire alguns segundos para aprender a usar este Launcher!</string> <string name="tutorial_concept_title">Conceito</string> - <string name="tutorial_concept_text">O Launcher foi criado para ser minimalista, eficiente e livre de distrações. Ele é livre de pagamentos, anúncios e serviços de rastreamento.</string> - <string name="tutorial_concept_text_2">O app é de código aberto (licença MIT) e está disponível no GitHub! Não deixe de conferir o repositório!</string> + <string name="tutorial_concept_text">O μLauncher foi criado para ser minimalista, eficiente e livre de distrações. \n\n\nNão contém anúncios e não coleta dados.</string> + <string name="tutorial_concept_text_2">É um software livre (sob licença MIT)!\nNão deixe de conferir o repositório!</string> <string name="tutorial_usage_title">Uso</string> <string name="tutorial_usage_text">Sua tela inicial contém a data e hora local. Sem distrações.</string> - <string name="tutorial_usage_text_2">Você pode iniciar seus aplicativos com um gesto único ou apertando um botão. Escolha algumas ações no próximo slide.</string> + <string name="tutorial_usage_text_2">Você pode iniciar seus aplicativos com gestos de toque ou apertando um botão.</string> <string name="tutorial_setup_title">Configurar</string> <string name="tutorial_setup_text">Selecionamos alguns aplicativos padrão para você. Se quiser, você pode alterá-los agora:</string> <string name="tutorial_setup_text_2">Você pode alterar suas escolhas mais tarde.</string> <string name="tutorial_finish_title">Vamos lá!</string> - <string name="tutorial_finish_text">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)</string> + <string name="tutorial_finish_text">Tá todo pronto para começar!\n\nEspero que isso seja de grande valor para você!\n\n- Finn (que criou o Launcher) e Josia (que fez algumas melhorias e tb mantém o fork do μLauncher)</string> <string name="tutorial_finish_button">Começar</string> <string name="settings">Configurações</string> <string name="ic_menu_alt">Mais opções</string> @@ -147,11 +147,11 @@ <string name="alert_lock_screen_failed">Erro: Falha ao bloquear a tela. (Se você acabou de atualizar o app, tente desativar e reativar o Serviço de acessibilidade em configurações do aparelho)</string> <string name="toast_accessibility_service_not_enabled">O Serviço de acessibilidade do μLauncher não está ativado. Entre em configurações para ativar</string> <string name="settings_apps_hide_bound_apps">Não mostrar apps com um gesto atribuído na lista de aplicativos</string> - <string name="toast_device_admin_not_enabled">O µLauncher precisa tornar-se o Administrador do dispositivo para poder bloquear a tela.</string> + <string name="toast_device_admin_not_enabled">O μLauncher precisa virar um Administrador do dispositivo para poder bloquear a tela.</string> <string name="device_admin_explanation">Isto é necessário para realizar a ação de bloqueio da tela.</string> <string name="device_admin_description">Permitir a ação de bloqueio da tela</string> <string name="alert_torch_access_exception">Erro: Não é possível acessar a lanterna.</string> - <string name="accessibility_service_name">µLauncher - bloqueio da tela</string> + <string name="accessibility_service_name">μLauncher - bloqueio da tela</string> <string name="screen_lock_method_use_accessibility">Usar o Serviço de acessibilidade</string> <string name="screen_lock_method_use_device_admin">Usar o Administrador do dispositivo</string> <string name="screen_lock_method_dialog_title">Escolha um método de bloqueio</string> @@ -160,7 +160,7 @@ <string name="alert_requires_android_m">Essa funcionalidade requer o Android 6 ou mais recente.</string> <string name="alert_no_torch_found">Nenhuma câmera com lanterna detectada.</string> <string name="toast_lock_screen_not_supported">Erro: O bloqueio da tela via Serviço de acessibilidade não é compatível com este aparelho. Tente usar Administrador do dispositivo como método alternativo.</string> - <string name="accessibility_service_description">Definindo µLauncher como Serviço de acessibilidade permite a ele bloquear a tela. Considere que é necessário conceder as permissões elevadas. Você nunca deveria autorizar essas permissões a qualquer aplicativo sem avaliação. O µLauncher usará o Serviço de acessibilidade somente para bloquear a tela. Você pode verificar o código-fonte para ter certeza. O bloqueio da tela também pode ser realizado dando ao µLauncher permissões de Administrador do dispositivo. Apesar de que esse método não funciona com impressão digital e desbloqueio facial.</string> + <string name="accessibility_service_description">Definindo o μLauncher como Serviço de acessibilidade permite bloquear a tela. Considere que é necessário conceder as permissões elevadas. Você nunca deveria autorizar essas permissões a qualquer aplicativo sem avaliação. O μLauncher usará o Serviço de acessibilidade somente para bloquear a tela. Você pode verificar o código-fonte para ter certeza. O bloqueio da tela também pode ser realizado dando ao μLauncher permissões de Administrador do dispositivo. Apesar de que esse método não funciona com impressão digital e desbloqueio facial.</string> <string name="screen_lock_method_dialog_text"><![CDATA[ <h1>Escolha um método de bloqueio</h1> Há dois métodos para bloquear a tela. @@ -174,9 +174,9 @@ <h3>Serviço de acessibilidade</h3> Exige permissões elevadas. - O µLauncher usará essas permissões apenas para bloquear a tela. + O μLauncher usará essas permissões apenas para bloquear a tela. <br/> - (Você realmente não deveria confiar num app aleatório que você baixou que tá pedindo estas permissões, mas pode verificar o <a href=\"https://github.com/jrpie/Launcher\">código-fonte</a>.) + (Você realmente não deveria confiar num app aleatório que você baixou e tá pedindo estas permissões, mas pode verificar o <a href=\"https://github.com/jrpie/Launcher\">código-fonte</a>.) <br/> Em alguns aparelhos após ativação do Serviço de acessibilidade não será mais exigido o PIN para acessar dados criptografados, na inicialização do celular. Isto pode ser <a href="https://issuetracker.google.com/issues/37010136#comment36">reativado</a> depois. @@ -210,7 +210,7 @@ <string name="settings_enabled_gestures_edge_swipe_summary">Deslize na borda da tela</string> <string name="settings_enabled_gestures_edge_swipe_edge_width">Largura da borda</string> <string name="settings_meta_view_code">Ver código-fonte</string> - <string name="settings_meta_join_chat">Entre no chat do µLauncher</string> + <string name="settings_meta_join_chat">Entre no chat do μLauncher</string> <string name="list_other_lock_screen">Bloquear a tela</string> <string name="settings_theme_text_shadow">Sombra no texto</string> <string name="settings_theme_background_item_transparent">Transparente</string> @@ -236,13 +236,13 @@ <string name="dialog_select_color_green">Verde</string> <string name="dialog_select_color_color_hex">Cor</string> <string name="dialog_choose_color_title">Escola a cor</string> - <string name="dialog_consent_accessibility_consent">Autorizo a utilização do Serviço de acessibilidade para disponibilizar funcionalidades não relacionadas com a acessibilidade.</string> - <string name="dialog_consent_accessibility_data_collection">Não autorizo ao µLauncher a coleta de quaisquer dados.</string> + <string name="dialog_consent_accessibility_consent">Autorizo o μLauncher a usar Serviço de acessibilidade para acessar funcionalidades não relacionadas com a acessibilidade.</string> + <string name="dialog_consent_accessibility_data_collection">Não autorizo ao μLauncher coletar quaisquer dados.</string> <string name="dialog_consent_accessibility_title">Ativação do Serviço de acessibilidade</string> <string name="dialog_consent_accessibility_ok">Ativar o Serviço de acessibilidade</string> <string name="dialog_cancel">Cancelar</string> - <string name="dialog_consent_accessibility_text"><![CDATA[Você está prestes a ativar o Serviço de acessibilidade. Isto concederá <strong>permissões elevadas</strong> ao µLauncher.<br/>µLauncher usará estas permissões <strong>apenas para bloquear a tela</strong>. µLauncher <strong>nunca coletará nenhum dado</strong>. Sobretudo, o µLauncher não implementa o Serviço de acessibilidade para coletar dados.]]></string> - <string name="dialog_consent_accessibility_privileges">Estou ciente de que isto concederá permissões elevadas ao µLauncher.</string> + <string name="dialog_consent_accessibility_text"><![CDATA[Você está prestes a ativar o Serviço de acessibilidade. Isto concederá <strong>permissões elevadas</strong> ao μLauncher.<br/>μLauncher usará estas permissões <strong>apenas para bloquear a tela</strong>. μLauncher <strong>nunca coletará nenhum dado</strong>. Sobretudo, o μLauncher não implementa o Serviço de acessibilidade para coletar dados.]]></string> + <string name="dialog_consent_accessibility_privileges">Estou ciente de que isto concederá permissões elevadas ao μLauncher.</string> <string name="dialog_consent_accessibility_other_options">Estou ciente de que existem outras opções (permissões de Administrador do aparelho ou o botão de ligar).</string> <string name="settings_functionality_search_web">Pesquise na internet</string> <string name="settings_functionality_search_web_summary">Ao buscar na lista de apps toque no Enter para iniciar uma pesquisa na internet.</string> @@ -255,13 +255,13 @@ <string name="toast_private_space_locked">Espaço privado trancado</string> <string name="toast_private_space_unlocked">Espaço privado liberado</string> <string name="toast_private_space_not_available">Espaço privado indisponível</string> - <string name="toast_private_space_default_home_screen">O µLauncher precisa ser definido como a tela inicial padrão para poder usar Espaço privado.</string> + <string name="toast_private_space_default_home_screen">O μLauncher precisa ser definido como a tela inicial padrão para poder usar Espaço privado.</string> <string name="dialog_report_bug_button_clipboard">Copiar para memória</string> <string name="dialog_report_bug_security_info">Não relate vulnerabilidades de segurança publicamente no GitHub, use o seguinte:</string> <string name="dialog_report_bug_button_security">Relatar vulnerabilidade de segurança</string> <string name="dialog_report_bug_create_report">Criar relatório</string> <string name="dialog_report_bug_title">Relatar um bug</string> - <string name="dialog_report_bug_info">Obrigado por ajudar a melhorar o µLauncher!\nConsidere adicionar as seguintes informações ao relatório de bug:</string> + <string name="dialog_report_bug_info">Obrigado por ajudar a melhorar o μLauncher!\nConsidere adicionar as seguintes informações ao relatório dos bugs:</string> <string name="settings_functionality_auto_launch_summary">Toque no espaço para temporariamente desativar esta funcionalidade.</string> <string name="toast_activity_not_found_browser">Não foi possível abrir a URL: nenhum navegador encontrado.</string> <string name="toast_activity_not_found_search_web">Nenhum app encontrado para efetuar a pesquisa.</string> @@ -300,5 +300,14 @@ <string name="list_other_track_play_pause">Música: Reproduzir / Pausar</string> <string name="settings_gesture_description_swipe_smaller_reverse">Canto inferior direito -> centro esquerdo -> canto superior direito</string> <string name="settings_gesture_description_swipe_lambda_reverse">Inferior direito -> superior médio -> inferior esquerdo</string> - <string name="settings_list_reverse_layout">Lista de apps inversa</string> + <string name="settings_list_reverse_layout">Inverter a lista de apps</string> + <string name="settings_meta_donate">Doar</string> + <string name="list_other_volume_adjust">Ajuste de volume</string> + <string name="settings_display_hide_status_bar">Ocultar barra de status</string> + <string name="settings_display_hide_navigation_bar">Ocultar barra de navegação</string> + <string name="tutorial_concept_label_version">Versão</string> + <string name="tutorial_app_list_title">Todos apps</string> + <string name="tutorial_app_list_text">Você pode encontrar rápido todos os apps na lista de aplicativos.\n\nDeslize para cima para abrir ou definir um gesto específico.</string> + <string name="tutorial_app_list_text_2">Quando apenas um aplicativo corresponde, vai ser iniciado automaticamente.\nIsso pode ser desativado acrescentando um espaço durante a busca.</string> + <string name="settings_tab_actions">Ações</string> </resources> From 14ffbd1f6cefe6e8b74c8d027729c16ce43e4a53 Mon Sep 17 00:00:00 2001 From: class0068 <monkeyotw@proton.me> Date: Mon, 24 Mar 2025 13:07:24 +0000 Subject: [PATCH 60/73] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (254 of 254 strings) Translation: jrpie-Launcher/Launcher Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/zh_Hans/ --- app/src/main/res/values-zh-rCN/strings.xml | 135 +++++++++++---------- 1 file changed, 68 insertions(+), 67 deletions(-) diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 3eeaf50..4a7cd64 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -5,36 +5,36 @@ <string name="ic_menu_alt">更多选项</string> <string name="settings_title">设置</string> <string name="settings_launcher_section_appearance">外观</string> - <string name="settings_theme_color_theme">主题风格</string> + <string name="settings_theme_color_theme">色调风格</string> <string name="settings_launcher_section_display">显示</string> <string name="list_tab_other">其他</string> - <string name="settings_gesture_up">上</string> - <string name="settings_gesture_down">下</string> + <string name="settings_gesture_up">上滑</string> + <string name="settings_gesture_down">下滑</string> <string name="alert_cant_open_title">无法打开应用</string> <string name="alert_cant_open_message">要更改其设置吗?</string> <string name="toast_cant_open_message">打开设置,为该手势绑定一个应用程序</string> <string name="settings_tab_launcher">启动器</string> <string name="settings_tab_meta">杂项</string> <string name="settings_gesture_left">左</string> - <string name="settings_gesture_double_left">左滑两次</string> - <string name="settings_gesture_double_up">上滑两次</string> - <string name="settings_gesture_double_down">下滑两次</string> + <string name="settings_gesture_double_left">双指左滑</string> + <string name="settings_gesture_double_up">双指上滑</string> + <string name="settings_gesture_double_down">双指下滑</string> <string name="settings_gesture_right">右</string> - <string name="settings_gesture_double_right">右滑两次</string> - <string name="settings_gesture_right_top_edge">右(顶部)</string> - <string name="settings_gesture_right_bottom_edge">右(底部)</string> - <string name="settings_gesture_left_bottom_edge">左(底部)</string> - <string name="settings_gesture_left_top_edge">左(顶部)</string> - <string name="settings_gesture_up_left_edge">上(左边缘)</string> - <string name="settings_gesture_up_right_edge">上(右边缘)</string> - <string name="settings_gesture_down_left_edge">下(左边缘)</string> - <string name="settings_gesture_down_right_edge">下(右边缘)</string> - <string name="settings_gesture_vol_up">音量加</string> - <string name="settings_gesture_vol_down">音量减</string> + <string name="settings_gesture_double_right">双指右滑</string> + <string name="settings_gesture_right_top_edge">右滑(顶部)</string> + <string name="settings_gesture_right_bottom_edge">右滑(底部)</string> + <string name="settings_gesture_left_bottom_edge">左滑(底部)</string> + <string name="settings_gesture_left_top_edge">左滑(顶部)</string> + <string name="settings_gesture_up_left_edge">上滑(左边缘)</string> + <string name="settings_gesture_up_right_edge">上滑(右边缘)</string> + <string name="settings_gesture_down_left_edge">下滑(左边缘)</string> + <string name="settings_gesture_down_right_edge">下滑(右边缘)</string> + <string name="settings_gesture_vol_up">音量增加键</string> + <string name="settings_gesture_vol_down">音量降低键</string> <string name="settings_gesture_double_click">双击</string> <string name="settings_gesture_long_click">长按</string> - <string name="settings_gesture_date">日期</string> - <string name="settings_gesture_time">时间</string> + <string name="settings_gesture_date">桌面日期</string> + <string name="settings_gesture_time">桌面时钟</string> <string name="settings_apps_choose">选择应用</string> <string name="settings_apps_install">安装应用</string> <string name="settings_apps_toast_store_not_found">没有找到应用市场</string> @@ -42,9 +42,9 @@ <string name="settings_theme_wallpaper">选择壁纸</string> <string name="settings_display_screen_timeout_disabled">保持屏幕常亮</string> <string name="settings_launcher_section_functionality">功能</string> - <string name="settings_enabled_gestures_edge_swipe">边缘滑动动作</string> - <string name="settings_functionality_auto_launch">启动搜索匹配项</string> - <string name="settings_functionality_auto_keyboard">搜索时呼出键盘</string> + <string name="settings_enabled_gestures_edge_swipe">边缘滑动手势</string> + <string name="settings_functionality_auto_launch">自动启动搜索匹配项</string> + <string name="settings_functionality_auto_keyboard">自动激活搜索</string> <string name="settings_launcher_sensitivity">灵敏度</string> <string name="settings_meta_cant_select_launcher">应用信息</string> <string name="settings_meta_show_tutorial">查看 µLauncher 的使用教程</string> @@ -61,10 +61,10 @@ <string name="tutorial_concept_title">概念</string> <string name="tutorial_concept_text_2">这是一款自由软件(遵循 MIT 许可)!\n欢迎查看项目仓库!</string> <string name="tutorial_usage_title">使用方法</string> - <string name="tutorial_usage_text">您的主屏幕仅包含本地日期和时间,没有多余项目。</string> + <string name="tutorial_usage_text">您的主屏幕仅包含本地日期和时间,没有多余的项目。</string> <string name="tutorial_setup_title">设置</string> - <string name="tutorial_setup_text">我们为您选择了一些默认应用。如果您希望进行更改,现在就可以:</string> - <string name="tutorial_setup_text_2">您也可以稍后对您的选择进行更改。</string> + <string name="tutorial_setup_text">我们为您预设了一些快捷操作。如果您不满意,现在就试试点击右侧图标:</string> + <string name="tutorial_setup_text_2">您也可以稍后更改您的选择。</string> <string name="tutorial_finish_title">开始!</string> <string name="list_tab_app">应用</string> <string name="list_app_delete">卸载</string> @@ -79,15 +79,15 @@ <string name="list_other_nop">啥也不干</string> <string name="tutorial_title">教程</string> <string name="tutorial_concept_text">μLauncher 的设计理念是简约、高效,无干扰。\n\n不含广告、且不收集任何数据。</string> - <string name="tutorial_usage_text_2">您可以通过手势或按键来启动最重要的应用程序。</string> - <string name="settings_general_choose_home_screen">将 μLauncher 设为默认桌面</string> - <string name="tutorial_finish_text">您已经准备好开始使用本启动器了!\n\n希望这对你有帮助!\n\n- Finn(Launcher 的作者)和 Josia(对 μLauncher 进行了改进和维护)</string> - <string name="settings_enabled_gestures_double_swipe">双滑动作</string> + <string name="tutorial_usage_text_2">您可以通过手势或按键来启动对您来说最重要的应用程序。</string> + <string name="settings_general_choose_home_screen">将 μLauncher 设为默认启动器</string> + <string name="tutorial_finish_text">您已经准备好开始使用本启动器了!\n\n希望本快捷教程能对您有所帮助!\n\n- Finn(Launcher 的作者)和 Josia(对 μLauncher 进行了改进和维护)</string> + <string name="settings_enabled_gestures_double_swipe">双指滑动手势</string> <string name="settings_clock_localized">使用本地日期格式</string> <string name="settings_clock_time_visible">显示时间</string> <string name="settings_clock_date_visible">显示日期</string> - <string name="settings_clock_flip_date_time">翻转日期和时间</string> - <string name="settings_theme_background">背景(应用列表和设置)</string> + <string name="settings_clock_flip_date_time">交换日期和时间位置</string> + <string name="settings_theme_background">背景(应用程序列表和设置页面)</string> <string name="settings_theme_font">字体</string> <string name="settings_theme_monochrome_icons">黑白应用图标</string> <string name="settings_clock_show_seconds">显示秒</string> @@ -100,7 +100,7 @@ <string name="alert_torch_access_exception">错误:无法访问闪光灯。</string> <string name="screen_lock_method_dialog_title">选择锁屏方法</string> <string name="settings_actions_lock_method">选择锁屏的方法</string> - <string name="settings_apps_hide_bound_apps">不要在应用抽屉中显示被绑定到手势的应用</string> + <string name="settings_apps_hide_bound_apps">不要在应用程序列表中显示已被绑定到手势操作的应用</string> <string name="alert_requires_android_m">此功能需要 Android 6 或更高版本。</string> <string name="snackbar_app_hidden">应用程序已隐藏。您可在设置中让它再次显示。</string> <string name="toast_device_admin_not_enabled">µLauncher 需要激活“设备管理应用”权限才能够锁定屏幕。</string> @@ -114,34 +114,34 @@ <string name="undo">撤销</string> <string name="settings_apps_hidden">隐藏的应用</string> <string name="list_title_hidden">隐藏的应用</string> - <string name="settings_gesture_description_up">上滑</string> - <string name="settings_gesture_description_double_up">用双指向上滑动</string> - <string name="settings_gesture_description_down">下滑</string> + <string name="settings_gesture_description_up">向上滑动</string> + <string name="settings_gesture_description_double_up">双指向上滑动</string> + <string name="settings_gesture_description_down">向下滑动</string> <string name="settings_gesture_description_double_down">双指向下滑动</string> - <string name="settings_gesture_description_left">左滑</string> + <string name="settings_gesture_description_left">向左滑动</string> <string name="settings_gesture_description_double_left">双指向左滑动</string> - <string name="settings_gesture_description_right">右滑</string> + <string name="settings_gesture_description_right">向右滑动</string> <string name="settings_gesture_description_double_right">双指向右滑动</string> - <string name="settings_gesture_description_right_top_edge">在屏幕顶部向右滑动</string> - <string name="settings_gesture_description_right_bottom_edge">在屏幕底部向右滑动</string> - <string name="settings_gesture_description_left_bottom_edge">在屏幕底部向左滑动</string> - <string name="settings_gesture_description_left_top_edge">在屏幕顶部向左滑动</string> - <string name="settings_gesture_description_up_left_edge">在屏幕左边缘向上滑动</string> - <string name="settings_gesture_description_up_right_edge">在屏幕右边缘向上滑动</string> - <string name="settings_gesture_description_down_left_edge">在屏幕左边缘向下滑动</string> - <string name="settings_gesture_description_down_right_edge">在屏幕右边缘向下滑动</string> - <string name="settings_gesture_description_vol_up">按下音量增大按钮</string> - <string name="settings_gesture_description_vol_down">按下音量降低按钮</string> + <string name="settings_gesture_description_right_top_edge">在桌面顶部向右滑动</string> + <string name="settings_gesture_description_right_bottom_edge">在桌面底部向右滑动</string> + <string name="settings_gesture_description_left_bottom_edge">在桌面底部向左滑动</string> + <string name="settings_gesture_description_left_top_edge">在桌面顶部向左滑动</string> + <string name="settings_gesture_description_up_left_edge">在桌面左边缘向上滑动</string> + <string name="settings_gesture_description_up_right_edge">在桌面右边缘向上滑动</string> + <string name="settings_gesture_description_down_left_edge">在桌面左边缘向下滑动</string> + <string name="settings_gesture_description_down_right_edge">在桌面右边缘向下滑动</string> + <string name="settings_gesture_description_vol_up">按下音量增加键</string> + <string name="settings_gesture_description_vol_down">按下音量降低键</string> <string name="settings_gesture_description_double_click">双击空白区域</string> <string name="settings_gesture_description_long_click">长按空白区域</string> - <string name="settings_gesture_description_date">点击日期</string> - <string name="settings_gesture_description_time">点击时间</string> + <string name="settings_gesture_description_date">点击桌面日期</string> + <string name="settings_gesture_description_time">点击桌面时钟</string> <string name="settings_meta_view_code">查看源代码</string> <string name="settings_meta_join_chat">加入 μLauncher 的聊天群</string> <string name="list_other_list_favorites">收藏的应用</string> <string name="list_other_lock_screen">锁屏</string> <string name="settings_theme_text_shadow">文本阴影</string> - <string name="settings_enabled_gestures_double_swipe_summary">双指滑动</string> + <string name="settings_enabled_gestures_double_swipe_summary">使用双指进行滑动手势操作</string> <string name="dialog_rename_title">重命名 %1$s</string> <string name="settings_theme_color_theme_item_default">默认</string> <string name="settings_theme_color_theme_item_dark">暗色</string> @@ -165,9 +165,9 @@ <string name="settings_theme_color_theme_item_light">亮色</string> <string name="list_other_expand_settings_panel">快速设置</string> <string name="alert_lock_screen_failed">错误:锁定屏幕失败。(如果您刚刚升级了本启动器,请尝试在手机设置中手动禁用并重新启用“无障碍”服务)</string> - <string name="settings_enabled_gestures_edge_swipe_summary">在屏幕边缘滑动</string> + <string name="settings_enabled_gestures_edge_swipe_summary">在桌面边缘进行滑动手势操作</string> <string name="accessibility_service_description">将 µLauncher 设置为“无障碍”服务以允许其锁定屏幕。请注意,这会使 µLauncher 获得额外的权限。你永远不应该轻易地授予任何应用程序这样的权限。获得授权后“无障碍”服务将仅被用于锁定屏幕。您可以审核我们的源代码。请注意,锁定屏幕也可以通过激活 µLauncher 的“设备管理应用”权限来实现,然而,这种方法无法与于指纹解锁和面部解锁兼容。</string> - <string name="settings_gesture_back">返回</string> + <string name="settings_gesture_back">返回操作</string> <string name="dialog_select_color_red">红色</string> <string name="dialog_select_color_blue">蓝色</string> <string name="dialog_select_color_alpha">透明度</string> @@ -175,19 +175,19 @@ <string name="settings_theme_color_theme_item_dynamic">动态</string> <string name="list_title_private_space">私人空间</string> <string name="list_other_list_private_space">私人空间</string> - <string name="dialog_choose_color_title">选择颜色</string> + <string name="dialog_choose_color_title">设置颜色</string> <string name="dialog_select_color_color_hex">颜色</string> <string name="dialog_report_bug_title">错误反馈</string> <string name="settings_gesture_swipe_larger"><![CDATA[>]]></string> <string name="tooltip_lock_private_space">锁定私人空间</string> <string name="settings_gesture_swipe_v">V</string> <string name="settings_gesture_swipe_lambda">Λ</string> - <string name="settings_list_layout_item_text">文本</string> + <string name="settings_list_layout_item_text">纯文本</string> <string name="settings_list_layout_item_grid">网格</string> <string name="dialog_report_bug_create_report">创建报告</string> <string name="tooltip_unlock_private_space">解锁私人空间</string> <string name="settings_list_layout_item_default">默认</string> - <string name="settings_clock_color">颜色</string> + <string name="settings_clock_color">文本颜色</string> <string name="settings_gesture_swipe_smaller"><![CDATA[<]]></string> <string name="dialog_report_bug_button_clipboard">复制到剪贴板</string> <string name="alert_requires_android_v">此功能需要 Android 15 或更高版本。</string> @@ -210,9 +210,9 @@ <string name="settings_gesture_description_back">返回按键 / 返回手势</string> <string name="settings_gesture_description_tap_down">先单击然后再下滑</string> <string name="settings_functionality_search_web">在网络上搜索</string> - <string name="settings_gesture_description_swipe_smaller">(从)右上 (滑向)中左(滑向)右下</string> - <string name="settings_functionality_search_web_summary">通过按回车键在应用列表搜索界面激活网络搜索。</string> - <string name="settings_gesture_description_swipe_lambda">(从)左下 (滑向)中上(滑向)右下</string> + <string name="settings_gesture_description_swipe_smaller">(从)右上(滑向)中左(滑向)右下</string> + <string name="settings_functionality_search_web_summary">输入搜索内容后,按回车键直接在应用列表界面启动网络搜索。</string> + <string name="settings_gesture_description_swipe_lambda">(从)左下(滑向)中上(滑向)右下</string> <string name="screen_lock_method_dialog_text"><![CDATA[ <h1>选择锁定设备的方式</h1> 有2种方式可以用来锁定屏幕。 @@ -238,7 +238,7 @@ ]]></string> <string name="list_apps_search_hint_no_auto_launch">搜索(不触发自动启动匹配项)</string> <string name="dialog_consent_accessibility_text"><![CDATA[您即将激活“无障碍”服务。这将授予 μLauncher <strong>广泛且重要的权限</strong>。<br/>但 μLauncher <strong>仅会在需要锁定屏幕时</strong>使用这些权限。µLauncher <strong>绝不会收集任何数据</strong>。尤其是,μLauncher 不会使用“无障碍”服务来收集任何数据。]]></string> - <string name="settings_gesture_description_swipe_larger">(从)左上 (滑向)中右(滑向)左下</string> + <string name="settings_gesture_description_swipe_larger">(从)左上(滑向)中右(滑向)左下</string> <string name="settings_gesture_tap_up">单击 + 上滑</string> <string name="settings_gesture_tap_down">单击 + 下滑</string> <string name="settings_gesture_tap_left">单击 + 左滑</string> @@ -246,16 +246,16 @@ <string name="settings_gesture_description_tap_up">先单击然后再上滑</string> <string name="settings_gesture_tap_right">单击 + 右滑</string> <string name="settings_gesture_description_tap_right">先单击然后再右滑</string> - <string name="settings_gesture_description_swipe_larger_reverse">(从)左下 (滑向)中右(滑向)左上</string> - <string name="settings_gesture_description_swipe_smaller_reverse">(从)右下 (滑向)中左(滑向)右上</string> - <string name="settings_gesture_description_swipe_v">(从)左上 (滑向)中下(滑向)右上</string> - <string name="settings_gesture_description_swipe_v_reverse">(从)右上 (滑向)中下(滑向)左上</string> - <string name="settings_gesture_description_swipe_lambda_reverse">(从)右下 (滑向)中上(滑向)左下</string> + <string name="settings_gesture_description_swipe_larger_reverse">(从)左下(滑向)中右(滑向)左上</string> + <string name="settings_gesture_description_swipe_smaller_reverse">(从)右下(滑向)中左(滑向)右上</string> + <string name="settings_gesture_description_swipe_v">(从)左上(滑向)中下(滑向)右上</string> + <string name="settings_gesture_description_swipe_v_reverse">(从)右上(滑向)中下(滑向)左上</string> + <string name="settings_gesture_description_swipe_lambda_reverse">(从)右下(滑向)中上(滑向)左下</string> <string name="settings_gesture_swipe_lambda_reverse">Λ (反向)</string> <string name="settings_gesture_swipe_v_reverse">V(反向)</string> <string name="settings_gesture_swipe_larger_reverse"><![CDATA[>(反向)]]></string> <string name="settings_gesture_swipe_smaller_reverse"><![CDATA[<(反向)]]></string> - <string name="settings_functionality_auto_launch_summary">开启后将直接启动匹配搜索内容的应用,可以通过按空格键临时暂停该功能。</string> + <string name="settings_functionality_auto_launch_summary">开启后将直接启动搜索所匹配到的应用,可以通过在搜索内容前添加空格来临时停用该功能。</string> <string name="settings_list_layout">应用程序列表样式</string> <string name="pin_shortcut_button_bind">绑定到手势</string> <string name="list_other_track_play_pause">音乐:播放 / 暂停</string> @@ -268,10 +268,11 @@ <string name="list_other_volume_adjust">调整音量</string> <string name="tutorial_concept_label_version">版本</string> <string name="tutorial_app_list_title">所有应用</string> - <string name="tutorial_app_list_text">您可以在应用程序列表中快速所搜所有应用。\n\n您可以通过上滑打开应用程序列表,也可以通过绑定其他手势操作来打开应用程序列表。</string> - <string name="tutorial_app_list_text_2">当匹配到唯一的应用程序后,该应用将自动启动。\n如果你不想触发自动启动,在查询内容前加上空格即可禁用。</string> + <string name="tutorial_app_list_text">您可以在应用程序列表中快速找到已安装的应用程序。\n\n您可以通过上滑打开应用程序列表,也可以通过绑定其他手势操作来打开应用程序列表。</string> + <string name="tutorial_app_list_text_2">您还可以搜索,当匹配到唯一的应用程序后,该应用将自动启动。\n如果你不想触发自动启动,可以在搜索内容前加上空格以禁用。</string> <string name="settings_display_hide_status_bar">隐藏状态栏</string> <string name="settings_display_hide_navigation_bar">隐藏导航栏</string> <string name="settings_list_reverse_layout">倒序排列应用程序</string> <string name="dialog_consent_accessibility_consent">我同意 μLauncher 使用无障碍服务来提供与无障碍服务无关的其他功能。</string> + <string name="settings_tab_actions">快捷操作</string> </resources> From 940e5785dc4d716c633bd603f115b6c60335411d Mon Sep 17 00:00:00 2001 From: Vossa Excelencia <nationalistic.tention@hele.win> Date: Mon, 24 Mar 2025 20:00:26 +0000 Subject: [PATCH 61/73] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (254 of 254 strings) Translation: jrpie-Launcher/Launcher Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/pt_BR/ --- app/src/main/res/values-pt-rBR/strings.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 4b2bcd2..5ee6a46 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -38,7 +38,7 @@ <string name="settings_gesture_down_left_edge">Para baixo (borda esquerda)</string> <string name="settings_gesture_down_right_edge">Para baixo (borda direita)</string> <string name="settings_gesture_vol_up">Botão de aumentar volume</string> - <string name="settings_gesture_vol_down">Botão de diminuição de volume</string> + <string name="settings_gesture_vol_down">Botão de diminuir volume</string> <string name="settings_gesture_double_click">Toque duplo</string> <string name="settings_gesture_long_click">Toque longo</string> <string name="settings_gesture_date">Data</string> @@ -98,8 +98,8 @@ <string name="list_apps_search_hint">Busque</string> <string name="list_other_settings">Configurações do μLauncher</string> <string name="list_other_list">Todos os apps</string> - <string name="list_other_volume_up">Aumento de volume</string> - <string name="list_other_volume_down">Diminuição de volume</string> + <string name="list_other_volume_up">Aumentar volume</string> + <string name="list_other_volume_down">Diminuir volume</string> <string name="list_other_track_next">Música: Próximo</string> <string name="list_other_track_previous">Música: Anterior</string> <string name="list_other_nop">Não faça nada</string> @@ -302,7 +302,7 @@ <string name="settings_gesture_description_swipe_lambda_reverse">Inferior direito -> superior médio -> inferior esquerdo</string> <string name="settings_list_reverse_layout">Inverter a lista de apps</string> <string name="settings_meta_donate">Doar</string> - <string name="list_other_volume_adjust">Ajuste de volume</string> + <string name="list_other_volume_adjust">Ajustar volume</string> <string name="settings_display_hide_status_bar">Ocultar barra de status</string> <string name="settings_display_hide_navigation_bar">Ocultar barra de navegação</string> <string name="tutorial_concept_label_version">Versão</string> From cbd23159da4a64ba5eaf7327fcdce97ba636478f Mon Sep 17 00:00:00 2001 From: class0068 <monkeyotw@proton.me> Date: Tue, 25 Mar 2025 12:40:13 +0000 Subject: [PATCH 62/73] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 98.8% (254 of 257 strings) Translation: jrpie-Launcher/Launcher Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/zh_Hans/ --- app/src/main/res/values-zh-rCN/strings.xml | 29 ++++++++++++---------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 4a7cd64..a0d7381 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -61,7 +61,7 @@ <string name="tutorial_concept_title">概念</string> <string name="tutorial_concept_text_2">这是一款自由软件(遵循 MIT 许可)!\n欢迎查看项目仓库!</string> <string name="tutorial_usage_title">使用方法</string> - <string name="tutorial_usage_text">您的主屏幕仅包含本地日期和时间,没有多余的项目。</string> + <string name="tutorial_usage_text">您的桌面仅包含本地日期和时间,没有多余的项目。</string> <string name="tutorial_setup_title">设置</string> <string name="tutorial_setup_text">我们为您预设了一些快捷操作。如果您不满意,现在就试试点击右侧图标:</string> <string name="tutorial_setup_text_2">您也可以稍后更改您的选择。</string> @@ -76,7 +76,7 @@ <string name="list_other_volume_down">降低音量</string> <string name="list_other_track_previous">音乐:上一首</string> <string name="list_other_track_next">音乐:下一首</string> - <string name="list_other_nop">啥也不干</string> + <string name="list_other_nop">不做任何设置</string> <string name="tutorial_title">教程</string> <string name="tutorial_concept_text">μLauncher 的设计理念是简约、高效,无干扰。\n\n不含广告、且不收集任何数据。</string> <string name="tutorial_usage_text_2">您可以通过手势或按键来启动对您来说最重要的应用程序。</string> @@ -115,13 +115,13 @@ <string name="settings_apps_hidden">隐藏的应用</string> <string name="list_title_hidden">隐藏的应用</string> <string name="settings_gesture_description_up">向上滑动</string> - <string name="settings_gesture_description_double_up">双指向上滑动</string> + <string name="settings_gesture_description_double_up">使用双指向上滑动</string> <string name="settings_gesture_description_down">向下滑动</string> - <string name="settings_gesture_description_double_down">双指向下滑动</string> + <string name="settings_gesture_description_double_down">使用双指向下滑动</string> <string name="settings_gesture_description_left">向左滑动</string> - <string name="settings_gesture_description_double_left">双指向左滑动</string> + <string name="settings_gesture_description_double_left">使用双指向左滑动</string> <string name="settings_gesture_description_right">向右滑动</string> - <string name="settings_gesture_description_double_right">双指向右滑动</string> + <string name="settings_gesture_description_double_right">使用双指向右滑动</string> <string name="settings_gesture_description_right_top_edge">在桌面顶部向右滑动</string> <string name="settings_gesture_description_right_bottom_edge">在桌面底部向右滑动</string> <string name="settings_gesture_description_left_bottom_edge">在桌面底部向左滑动</string> @@ -163,8 +163,8 @@ <string name="screen_lock_method_use_device_admin">激活“设备管理应用”权限</string> <string name="dialog_cancel">取消</string> <string name="settings_theme_color_theme_item_light">亮色</string> - <string name="list_other_expand_settings_panel">快速设置</string> - <string name="alert_lock_screen_failed">错误:锁定屏幕失败。(如果您刚刚升级了本启动器,请尝试在手机设置中手动禁用并重新启用“无障碍”服务)</string> + <string name="list_other_expand_settings_panel">启动器设置</string> + <string name="alert_lock_screen_failed">错误:锁定屏幕失败。(如果您刚刚升级了本启动器,请尝试在手机设置中手动禁用再重新启用“无障碍”服务。)</string> <string name="settings_enabled_gestures_edge_swipe_summary">在桌面边缘进行滑动手势操作</string> <string name="accessibility_service_description">将 µLauncher 设置为“无障碍”服务以允许其锁定屏幕。请注意,这会使 µLauncher 获得额外的权限。你永远不应该轻易地授予任何应用程序这样的权限。获得授权后“无障碍”服务将仅被用于锁定屏幕。您可以审核我们的源代码。请注意,锁定屏幕也可以通过激活 µLauncher 的“设备管理应用”权限来实现,然而,这种方法无法与于指纹解锁和面部解锁兼容。</string> <string name="settings_gesture_back">返回操作</string> @@ -201,14 +201,14 @@ <string name="toast_private_space_locked">私人空间已锁定</string> <string name="toast_private_space_unlocked">私人空间已解锁</string> <string name="toast_private_space_not_available">私人空间不可用</string> - <string name="toast_private_space_default_home_screen">µLauncher 需要作为默认主屏幕才能访问私人空间。</string> + <string name="toast_private_space_default_home_screen">µLauncher 需要作为默认启动器才能访问私人空间。</string> <string name="toast_activity_not_found_search_web">没有找到处理搜索的应用。</string> <string name="toast_activity_not_found_browser">无法打开 URL:找不到浏览器。</string> <string name="dialog_consent_accessibility_privileges">我已知晓,这将赋予 μLauncher 广泛且重要的权限。</string> <string name="settings_apps_hide_private_space_apps">在应用程序列表中隐藏私人空间</string> <string name="settings_apps_hide_paused_apps">隐藏已被暂停的应用</string> <string name="settings_gesture_description_back">返回按键 / 返回手势</string> - <string name="settings_gesture_description_tap_down">先单击然后再下滑</string> + <string name="settings_gesture_description_tap_down">先单击然后再向下滑动</string> <string name="settings_functionality_search_web">在网络上搜索</string> <string name="settings_gesture_description_swipe_smaller">(从)右上(滑向)中左(滑向)右下</string> <string name="settings_functionality_search_web_summary">输入搜索内容后,按回车键直接在应用列表界面启动网络搜索。</string> @@ -242,10 +242,10 @@ <string name="settings_gesture_tap_up">单击 + 上滑</string> <string name="settings_gesture_tap_down">单击 + 下滑</string> <string name="settings_gesture_tap_left">单击 + 左滑</string> - <string name="settings_gesture_description_tap_left">先单击然后再左滑</string> - <string name="settings_gesture_description_tap_up">先单击然后再上滑</string> + <string name="settings_gesture_description_tap_left">先单击然后再向左滑动</string> + <string name="settings_gesture_description_tap_up">先单击然后再向上滑动</string> <string name="settings_gesture_tap_right">单击 + 右滑</string> - <string name="settings_gesture_description_tap_right">先单击然后再右滑</string> + <string name="settings_gesture_description_tap_right">先单击然后再向右滑动</string> <string name="settings_gesture_description_swipe_larger_reverse">(从)左下(滑向)中右(滑向)左上</string> <string name="settings_gesture_description_swipe_smaller_reverse">(从)右下(滑向)中左(滑向)右上</string> <string name="settings_gesture_description_swipe_v">(从)左上(滑向)中下(滑向)右上</string> @@ -275,4 +275,7 @@ <string name="settings_list_reverse_layout">倒序排列应用程序</string> <string name="dialog_consent_accessibility_consent">我同意 μLauncher 使用无障碍服务来提供与无障碍服务无关的其他功能。</string> <string name="settings_tab_actions">快捷操作</string> + <string name="list_other_recent_apps">最近使用的应用</string> + <string name="alert_enable_accessibility_failed">错误:启用“无障碍”服务失败。</string> + <string name="alert_recent_apps_failed">错误:无法显示最近使用的应用。(如果您刚刚升级了本启动器,请尝试在手机设置中手动禁用再重新启用“无障碍”服务。)</string> </resources> From c085087e1ef2b7b27d2e2b0a3e588c7e66cb1a56 Mon Sep 17 00:00:00 2001 From: class0068 <monkeyotw@proton.me> Date: Tue, 25 Mar 2025 20:55:21 +0000 Subject: [PATCH 63/73] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (257 of 257 strings) Translation: jrpie-Launcher/Launcher Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/zh_Hans/ --- app/src/main/res/values-zh-rCN/strings.xml | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index a0d7381..de7c02b 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -105,7 +105,7 @@ <string name="snackbar_app_hidden">应用程序已隐藏。您可在设置中让它再次显示。</string> <string name="toast_device_admin_not_enabled">µLauncher 需要激活“设备管理应用”权限才能够锁定屏幕。</string> <string name="device_admin_explanation">这是执行锁屏操作所必需的。</string> - <string name="accessibility_service_name">µLauncher - 锁屏</string> + <string name="accessibility_service_name">µLauncher</string> <string name="list_title_favorite">收藏的应用</string> <string name="list_app_favorite_add">添加到收藏夹</string> <string name="list_app_favorite_remove">从收藏夹中移除</string> @@ -166,7 +166,7 @@ <string name="list_other_expand_settings_panel">启动器设置</string> <string name="alert_lock_screen_failed">错误:锁定屏幕失败。(如果您刚刚升级了本启动器,请尝试在手机设置中手动禁用再重新启用“无障碍”服务。)</string> <string name="settings_enabled_gestures_edge_swipe_summary">在桌面边缘进行滑动手势操作</string> - <string name="accessibility_service_description">将 µLauncher 设置为“无障碍”服务以允许其锁定屏幕。请注意,这会使 µLauncher 获得额外的权限。你永远不应该轻易地授予任何应用程序这样的权限。获得授权后“无障碍”服务将仅被用于锁定屏幕。您可以审核我们的源代码。请注意,锁定屏幕也可以通过激活 µLauncher 的“设备管理应用”权限来实现,然而,这种方法无法与于指纹解锁和面部解锁兼容。</string> + <string name="accessibility_service_description">将 µLauncher 设置为“无障碍”服务以允许其锁定屏幕和展示最近应用屏幕。请注意,这会使 µLauncher 获得额外的权限。你永远不应该轻易地授予任何应用程序这样的权限。μLauncher 仅在被用户要求时才会使用“无障碍”服务权限以实现: * 锁定屏幕 * 展示最近应用屏幕。μLauncher 不会使用“无障碍”服务来收集任何数据。您可以审核我们的源代码。请注意,锁定屏幕也可以通过激活 µLauncher 的“设备管理应用”权限来实现,然而,这种方法无法与于指纹解锁和面部解锁兼容。</string> <string name="settings_gesture_back">返回操作</string> <string name="dialog_select_color_red">红色</string> <string name="dialog_select_color_blue">蓝色</string> @@ -237,7 +237,12 @@ 你可以在设置中随时更改这个选项。 ]]></string> <string name="list_apps_search_hint_no_auto_launch">搜索(不触发自动启动匹配项)</string> - <string name="dialog_consent_accessibility_text"><![CDATA[您即将激活“无障碍”服务。这将授予 μLauncher <strong>广泛且重要的权限</strong>。<br/>但 μLauncher <strong>仅会在需要锁定屏幕时</strong>使用这些权限。µLauncher <strong>绝不会收集任何数据</strong>。尤其是,μLauncher 不会使用“无障碍”服务来收集任何数据。]]></string> + <string name="dialog_consent_accessibility_text"><![CDATA[您即将激活“无障碍”服务。这将授予 μLauncher <strong>广泛且重要的权限</strong>。<br/>但 μLauncher <strong>仅</strong>将这些权限用于: + <ul> + <li>锁定屏幕</li> + <li>展示最近应用屏幕</li> + </ul> +µLauncher <strong>绝不会收集任何数据</strong>。尤其是,μLauncher 不会使用“无障碍”服务来收集任何数据。]]></string> <string name="settings_gesture_description_swipe_larger">(从)左上(滑向)中右(滑向)左下</string> <string name="settings_gesture_tap_up">单击 + 上滑</string> <string name="settings_gesture_tap_down">单击 + 下滑</string> @@ -275,7 +280,7 @@ <string name="settings_list_reverse_layout">倒序排列应用程序</string> <string name="dialog_consent_accessibility_consent">我同意 μLauncher 使用无障碍服务来提供与无障碍服务无关的其他功能。</string> <string name="settings_tab_actions">快捷操作</string> - <string name="list_other_recent_apps">最近使用的应用</string> + <string name="list_other_recent_apps">最近应用屏幕</string> <string name="alert_enable_accessibility_failed">错误:启用“无障碍”服务失败。</string> - <string name="alert_recent_apps_failed">错误:无法显示最近使用的应用。(如果您刚刚升级了本启动器,请尝试在手机设置中手动禁用再重新启用“无障碍”服务。)</string> + <string name="alert_recent_apps_failed">错误:无法展示最近应用屏幕。(如果您刚刚升级了本启动器,请尝试在手机设置中手动禁用再重新启用“无障碍”服务。)</string> </resources> From ce65741717e314057d59b21d43b5dabf83b6a5e4 Mon Sep 17 00:00:00 2001 From: Vossa Excelencia <nationalistic.tention@hele.win> Date: Sun, 30 Mar 2025 16:53:37 +0000 Subject: [PATCH 64/73] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (258 of 258 strings) Translation: jrpie-Launcher/Launcher Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/pt_BR/ --- app/src/main/res/values-pt-rBR/strings.xml | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 5ee6a46..fcdd9e8 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -151,7 +151,7 @@ <string name="device_admin_explanation">Isto é necessário para realizar a ação de bloqueio da tela.</string> <string name="device_admin_description">Permitir a ação de bloqueio da tela</string> <string name="alert_torch_access_exception">Erro: Não é possível acessar a lanterna.</string> - <string name="accessibility_service_name">μLauncher - bloqueio da tela</string> + <string name="accessibility_service_name">μLauncher</string> <string name="screen_lock_method_use_accessibility">Usar o Serviço de acessibilidade</string> <string name="screen_lock_method_use_device_admin">Usar o Administrador do dispositivo</string> <string name="screen_lock_method_dialog_title">Escolha um método de bloqueio</string> @@ -160,7 +160,7 @@ <string name="alert_requires_android_m">Essa funcionalidade requer o Android 6 ou mais recente.</string> <string name="alert_no_torch_found">Nenhuma câmera com lanterna detectada.</string> <string name="toast_lock_screen_not_supported">Erro: O bloqueio da tela via Serviço de acessibilidade não é compatível com este aparelho. Tente usar Administrador do dispositivo como método alternativo.</string> - <string name="accessibility_service_description">Definindo o μLauncher como Serviço de acessibilidade permite bloquear a tela. Considere que é necessário conceder as permissões elevadas. Você nunca deveria autorizar essas permissões a qualquer aplicativo sem avaliação. O μLauncher usará o Serviço de acessibilidade somente para bloquear a tela. Você pode verificar o código-fonte para ter certeza. O bloqueio da tela também pode ser realizado dando ao μLauncher permissões de Administrador do dispositivo. Apesar de que esse método não funciona com impressão digital e desbloqueio facial.</string> + <string name="accessibility_service_description">Definindo o μLauncher como Serviço de acessibilidade permite bloquear a tela e abrir o menu de apps recentes. Considere que é necessário conceder as permissões elevadas. Você nunca deveria autorizar essas permissões a qualquer aplicativo sem avaliação. O μLauncher usará o Serviço de acessibilidade somente para executar as seguintes ações quando solicitado pelo usuário: * bloquear a tela * abrir aplicativos recentes μLauncher nunca usará o Serviço de acessibilidade para coletar os dados. Você pode verificar o código-fonte para ter certeza. O bloqueio da tela também pode ser realizado dando ao μLauncher permissões de Administrador do dispositivo. Apesar de que esse método não funciona com impressão digital e desbloqueio facial.</string> <string name="screen_lock_method_dialog_text"><![CDATA[ <h1>Escolha um método de bloqueio</h1> Há dois métodos para bloquear a tela. @@ -241,7 +241,12 @@ <string name="dialog_consent_accessibility_title">Ativação do Serviço de acessibilidade</string> <string name="dialog_consent_accessibility_ok">Ativar o Serviço de acessibilidade</string> <string name="dialog_cancel">Cancelar</string> - <string name="dialog_consent_accessibility_text"><![CDATA[Você está prestes a ativar o Serviço de acessibilidade. Isto concederá <strong>permissões elevadas</strong> ao μLauncher.<br/>μLauncher usará estas permissões <strong>apenas para bloquear a tela</strong>. μLauncher <strong>nunca coletará nenhum dado</strong>. Sobretudo, o μLauncher não implementa o Serviço de acessibilidade para coletar dados.]]></string> + <string name="dialog_consent_accessibility_text"><![CDATA[Você está prestes a ativar o Serviço de acessibilidade. Isto concederá <strong>permissões elevadas</strong> ao μLauncher.<br/>μLauncher usará estas permissões <strong>apenas</strong> para executar as seguintes ações: + <ul> + <li>Bloquear a tela</li> + <li>Apps recentes</li> + </ul> + μLauncher<strong>nunca coletará nenhum dado</strong>. Sobretudo, o μLauncher não implementa o Serviço de acessibilidade para coletar os dados.]]></string> <string name="dialog_consent_accessibility_privileges">Estou ciente de que isto concederá permissões elevadas ao μLauncher.</string> <string name="dialog_consent_accessibility_other_options">Estou ciente de que existem outras opções (permissões de Administrador do aparelho ou o botão de ligar).</string> <string name="settings_functionality_search_web">Pesquise na internet</string> @@ -310,4 +315,8 @@ <string name="tutorial_app_list_text">Você pode encontrar rápido todos os apps na lista de aplicativos.\n\nDeslize para cima para abrir ou definir um gesto específico.</string> <string name="tutorial_app_list_text_2">Quando apenas um aplicativo corresponde, vai ser iniciado automaticamente.\nIsso pode ser desativado acrescentando um espaço durante a busca.</string> <string name="settings_tab_actions">Ações</string> + <string name="list_other_recent_apps">Apps recentes</string> + <string name="alert_enable_accessibility_failed">Erro: Falha ao ativar o Serviço de acessibilidade.</string> + <string name="list_other_launch_other_launcher">Usar outro iniciador</string> + <string name="alert_recent_apps_failed">Erro: Falha ao mostrar apps recentes. (Se você acabou de atualizar o app, tente desativar e reativar o Serviço de acessibilidade em configurações do Android)</string> </resources> From 03a9833b5154335b31bd5a753e4ecb1517c3f792 Mon Sep 17 00:00:00 2001 From: class0068 <monkeyotw@proton.me> Date: Wed, 2 Apr 2025 19:01:34 +0000 Subject: [PATCH 65/73] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (258 of 258 strings) Translation: jrpie-Launcher/Launcher Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/zh_Hans/ --- app/src/main/res/values-zh-rCN/strings.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index de7c02b..608e57b 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -196,7 +196,7 @@ <string name="dialog_consent_accessibility_title">正在激活“无障碍”服务</string> <string name="settings_meta_licenses">开源许可证</string> <string name="legal_info_title">开源许可证</string> - <string name="pin_shortcut_switch_visible">在应用列表中显示</string> + <string name="pin_shortcut_switch_visible">在应用程序列表中显示</string> <string name="pin_shortcut_title">添加快捷方式</string> <string name="toast_private_space_locked">私人空间已锁定</string> <string name="toast_private_space_unlocked">私人空间已解锁</string> @@ -211,7 +211,7 @@ <string name="settings_gesture_description_tap_down">先单击然后再向下滑动</string> <string name="settings_functionality_search_web">在网络上搜索</string> <string name="settings_gesture_description_swipe_smaller">(从)右上(滑向)中左(滑向)右下</string> - <string name="settings_functionality_search_web_summary">输入搜索内容后,按回车键直接在应用列表界面启动网络搜索。</string> + <string name="settings_functionality_search_web_summary">输入搜索内容后,按回车键直接在应用程序列表界面启动网络搜索。</string> <string name="settings_gesture_description_swipe_lambda">(从)左下(滑向)中上(滑向)右下</string> <string name="screen_lock_method_dialog_text"><![CDATA[ <h1>选择锁定设备的方式</h1> @@ -283,4 +283,5 @@ <string name="list_other_recent_apps">最近应用屏幕</string> <string name="alert_enable_accessibility_failed">错误:启用“无障碍”服务失败。</string> <string name="alert_recent_apps_failed">错误:无法展示最近应用屏幕。(如果您刚刚升级了本启动器,请尝试在手机设置中手动禁用再重新启用“无障碍”服务。)</string> + <string name="list_other_launch_other_launcher">启动其他启动器</string> </resources> From 0877ca677260a52377c21f5ca26b323746b52887 Mon Sep 17 00:00:00 2001 From: class0068 <monkeyotw@proton.me> Date: Wed, 2 Apr 2025 18:56:56 +0000 Subject: [PATCH 66/73] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 14.2% (3 of 21 strings) Translation: jrpie-Launcher/metadata Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/metadata/zh_Hans/ --- .../android/zh-CN/full_description.txt | 32 ++++++++++--------- .../android/zh-CN/short_description.txt | 2 +- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/fastlane/metadata/android/zh-CN/full_description.txt b/fastlane/metadata/android/zh-CN/full_description.txt index b4defca..89025a5 100644 --- a/fastlane/metadata/android/zh-CN/full_description.txt +++ b/fastlane/metadata/android/zh-CN/full_description.txt @@ -1,19 +1,21 @@ -µLauncher 是主屏幕启动程序,允许您使用滑动手势和按下按钮来启动其他应用。 -它是<b>最小、高效且无干扰</b>。 +µLauncher 是桌面启动器程序,允许您使用各种滑动手势和按下按钮来启动其他应用。 +它是<b>简约、高效且无干扰</b>的。 -您的主屏幕仅显示日期、时间和壁纸。 -按返回或向上滑动(可以配置)打开 -所有已安装应用的列表,可以高效地搜索。 +您的桌面仅显示日期、时间和壁纸。 +按返回按键或向上滑动(可自定义其他手势)即可打开 +应用程序列表,且支持高效地搜索。 -这是 Finn M Glas 的应用 <a href="https://f-droid.org/packages/com.finnmglas.launcher/">Launcher</a> 的一个 fork。 +本启动器是基于 Finn M Glas 开发的 <a href="https://f-droid.org/packages/com.finnmglas.launcher/">Launcher 启动器</a> 的一个派生应用程序。 -显著变化: -* 边缘手势:可分为屏幕边缘滑动和中心滑动的设置。 -* 与工作配置文件兼容,因此可以使用 Shelter 等应用。 -* 此应用使用系统壁纸而不是自定义解决方案。 -* 字体已更改为 Hack。 -* Material 图标所取代了 Font Awesome 图标。 -* 移除了主屏幕上的齿轮按钮。按返回按钮会打开应用列表,可以从那里访问应用设置。 -* 搜索算法已修改为优先匹配应用名称开头的内容,即当搜索“te”时,“termux”会排在“notes”之前。 -* 搜索栏已移动到屏幕底部 +功能: +* 您可以设定 35 个不同的手势操作。如: + - 启动一个应用程序 + - 打开应用程序列表 + - 打开收藏的应用程序列表 + - 调整音量 + - 快速切换 上一首/下一首 音乐 + - 锁定屏幕 + - 开启/关闭 手机闪光灯 + - 展开通知栏 / 快捷设定栏 +* 兼容工作空间配置,因此支持使用 Shelter 等应用。 diff --git a/fastlane/metadata/android/zh-CN/short_description.txt b/fastlane/metadata/android/zh-CN/short_description.txt index d49c27c..66d4684 100644 --- a/fastlane/metadata/android/zh-CN/short_description.txt +++ b/fastlane/metadata/android/zh-CN/short_description.txt @@ -1 +1 @@ -无干扰的最小主屏幕应用启动器。 +无干扰的简约风格启动器。 From 7cce425339a84449dc9c2c121867cb730a2f3781 Mon Sep 17 00:00:00 2001 From: Lukas Hamm <ideallygrey@tuta.io> Date: Fri, 11 Apr 2025 20:54:28 +0000 Subject: [PATCH 67/73] Added translation using Weblate (Lithuanian) --- app/src/main/res/values-lt/strings.xml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 app/src/main/res/values-lt/strings.xml diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml new file mode 100644 index 0000000..a6b3dae --- /dev/null +++ b/app/src/main/res/values-lt/strings.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources></resources> \ No newline at end of file From 24250ad345a95f440bac1e48e3bd032cce0d59ac Mon Sep 17 00:00:00 2001 From: Lukas Hamm <ideallygrey@tuta.io> Date: Fri, 11 Apr 2025 20:57:34 +0000 Subject: [PATCH 68/73] Translated using Weblate (Lithuanian) Currently translated at 5.4% (14 of 258 strings) Translation: jrpie-Launcher/Launcher Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/lt/ --- app/src/main/res/values-lt/strings.xml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index a6b3dae..0a45d57 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -1,2 +1,16 @@ <?xml version="1.0" encoding="utf-8"?> -<resources></resources> \ No newline at end of file +<resources> + <string name="alert_cant_open_message">Norite pakeisti nustatymus?</string> + <string name="settings_title">Nustatymai</string> + <string name="settings_tab_actions">Veiksmai</string> + <string name="settings_tab_launcher">Paleidimo programėlė</string> + <string name="settings_tab_meta">Apie</string> + <string name="settings_gesture_back">Atgal</string> + <string name="settings_gesture_description_back">Grįžimo mygtukas / grįžimo gestas</string> + <string name="settings_gesture_description_up">Perbraukimas aukštyn</string> + <string name="settings_gesture_tap_up">Bakstelėkite + aukštyn</string> + <string name="alert_cant_open_title">Nepavyksta paleisti programėlės</string> + <string name="toast_cant_open_message">Atidarykite nustatymus norėdami pasirinkti šio gesto veiksmą</string> + <string name="settings_gesture_up">Aukštyn</string> + <string name="settings_gesture_description_tap_up">Bakstelėjimas ir perbraukimas aukštyn</string> +</resources> From 20a01e9f0329b222e1637e59ef0c1cd4d7d51caf Mon Sep 17 00:00:00 2001 From: letterhaven <likely.dormouse.asez@letterhaven.net> Date: Sat, 12 Apr 2025 14:03:03 +0000 Subject: [PATCH 69/73] Added translation using Weblate (Arabic) --- app/src/main/res/values-ar/strings.xml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 app/src/main/res/values-ar/strings.xml diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml new file mode 100644 index 0000000..a6b3dae --- /dev/null +++ b/app/src/main/res/values-ar/strings.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources></resources> \ No newline at end of file From a0b2417363850772db574f82654fbadb5e228b07 Mon Sep 17 00:00:00 2001 From: letterhaven <likely.dormouse.asez@letterhaven.net> Date: Sat, 12 Apr 2025 14:04:14 +0000 Subject: [PATCH 70/73] Translated using Weblate (Arabic) Currently translated at 99.6% (257 of 258 strings) Translation: jrpie-Launcher/Launcher Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/ar/ --- app/src/main/res/values-ar/strings.xml | 264 ++++++++++++++++++++++++- 1 file changed, 263 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index a6b3dae..1b7d9a2 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -1,2 +1,264 @@ <?xml version="1.0" encoding="utf-8"?> -<resources></resources> \ No newline at end of file +<resources> + <string name="alert_cant_open_title">لا يمكن فتح التطبيق</string> + <string name="alert_cant_open_message">هل تريد تعديل اعداداته؟</string> + <string name="toast_cant_open_message">افتح الاعدادات لاختيار أمر لهذه الإيماءة</string> + <string name="settings_title">الاعدادات</string> + <string name="settings_tab_actions">الأوامر</string> + <string name="settings_tab_launcher">المشغل</string> + <string name="settings_tab_meta">بيانات</string> + <string name="settings_gesture_back">رجوع</string> + <string name="settings_gesture_up">أعلى</string> + <string name="settings_gesture_double_up">لأعلى بأصبعين</string> + <string name="settings_gesture_description_double_up">اسحب لأعلى بأصبعين</string> + <string name="settings_gesture_description_tap_up">أنقر ثم اسحب لأعلى</string> + <string name="settings_gesture_description_back">اضغط على زر الرجوع</string> + <string name="settings_gesture_description_up">اسحب لأعلى</string> + <string name="settings_gesture_tap_up">نقرة + أعلى</string> + <string name="settings_gesture_down">أسفل</string> + <string name="settings_gesture_description_down">اسحب لأسفل</string> + <string name="settings_gesture_tap_down">نقرة + لأسفل</string> + <string name="settings_gesture_double_down">لأسفل بأصبعين</string> + <string name="settings_gesture_left">يسار</string> + <string name="settings_gesture_description_left">اسحب من اليسار</string> + <string name="settings_gesture_tap_left">نقرة + يسار</string> + <string name="settings_gesture_description_tap_left">أنقر ثم اسحب إلى اليسار</string> + <string name="settings_gesture_double_left">يسار بأصبعين</string> + <string name="settings_gesture_right">يمين</string> + <string name="settings_gesture_description_right">اسحب إلى اليمين</string> + <string name="settings_gesture_tap_right">نقرة + يمين</string> + <string name="settings_gesture_description_tap_right">أنقر ثم اسحب إلى اليمين</string> + <string name="settings_gesture_double_right">يمين بأصبعين</string> + <string name="settings_gesture_description_double_right">اسحب إلى اليمين بأصبعين</string> + <string name="settings_gesture_right_top_edge">يمين (في الأعلى)</string> + <string name="settings_gesture_right_bottom_edge">يمين (في الأسفل)</string> + <string name="settings_gesture_description_right_bottom_edge">اسحب إلى اليمين من أسفل الشاشة</string> + <string name="settings_gesture_left_top_edge">يسار (في الأعلى)</string> + <string name="settings_gesture_description_left_top_edge">اسحب إلى اليسار من أعلى الشاشة</string> + <string name="settings_gesture_up_left_edge">أعلى (الحافة اليسرى)</string> + <string name="settings_gesture_description_up_left_edge">اسحب إلى الأعلى من حافة الشاشة اليسرى</string> + <string name="settings_gesture_up_right_edge">أعلى (الحافة اليمنى)</string> + <string name="settings_gesture_down_left_edge">أسفل (الحافة اليسرى)</string> + <string name="settings_gesture_description_down_left_edge">اسحب إلى الأسفل من حافة الشاشة اليسرى</string> + <string name="settings_gesture_down_right_edge">أسفل (الحافة اليمنى)</string> + <string name="settings_gesture_description_swipe_larger">أعلى اليسار -> وسط اليمين -> أسفل اليسار</string> + <string name="settings_gesture_description_swipe_larger_reverse">أسفل اليسار -> وسط اليمين -> أعلى اليسار</string> + <string name="settings_gesture_description_swipe_smaller">أعلى اليمين -> وسط اليسار -> أسفل اليمين</string> + <string name="settings_gesture_description_swipe_v">أعلى اليسار -> الأسفل الوسط -> أعلى اليمين</string> + <string name="settings_gesture_swipe_v_reverse">V (معكوس)</string> + <string name="settings_gesture_description_swipe_v_reverse">أعلى اليمين -> الأسفل الوسط -> أعلى اليسار</string> + <string name="settings_gesture_description_swipe_lambda">أسفل اليسار -> أعلى الوسط -> أسفل اليمين</string> + <string name="settings_gesture_swipe_lambda_reverse">Λ (معكوس)</string> + <string name="settings_gesture_vol_up">زر رفع الصوت</string> + <string name="settings_gesture_description_vol_up">اضغط على زر رفع الصوت</string> + <string name="settings_gesture_vol_down">زر خفض الصوت</string> + <string name="settings_gesture_description_vol_down">اضغط على زر خفض الصوت</string> + <string name="settings_gesture_double_click">نقرة مزدوجة</string> + <string name="settings_gesture_long_click">نقرة مطولة</string> + <string name="settings_gesture_description_long_click">أنقر مطولًا في مكان فارغ على الشاشة</string> + <string name="settings_gesture_date">التاريخ</string> + <string name="settings_gesture_description_date">أنقر على التاريخ</string> + <string name="settings_gesture_time">الوقت</string> + <string name="settings_gesture_description_time">أنقر على الوقت</string> + <string name="settings_apps_choose">اختر تطبيق</string> + <string name="settings_apps_install">ثبت تطبيقات</string> + <string name="settings_launcher_section_appearance">المظهر</string> + <string name="settings_theme_color_theme">السمة</string> + <string name="settings_gesture_swipe_larger"><![CDATA[>]]></string> + <string name="settings_gesture_swipe_larger_reverse"><![CDATA[> (معكوس)]]></string> + <string name="settings_gesture_swipe_smaller"><![CDATA[<]]></string> + <string name="settings_gesture_swipe_smaller_reverse"><![CDATA[< (Reverse)]]></string> + <string name="settings_gesture_swipe_v">V</string> + <string name="settings_gesture_swipe_lambda">Λ</string> + <string name="settings_theme_color_theme_item_dark">داكن</string> + <string name="settings_theme_color_theme_item_light">فاتح</string> + <string name="settings_theme_color_theme_item_dynamic">متغير</string> + <string name="settings_theme_text_shadow">ظل النص</string> + <string name="settings_theme_background_item_transparent">شفاف</string> + <string name="settings_theme_background_item_dim">مظلل</string> + <string name="settings_theme_background_item_blur">مُموه</string> + <string name="settings_theme_background_item_solid">لون ثابت</string> + <string name="settings_theme_font">الخط</string> + <string name="settings_theme_font_item_system_default">خط النظام</string> + <string name="settings_theme_font_item_sans_serif">بدون تذييل</string> + <string name="settings_theme_font_item_serif">مذيل</string> + <string name="settings_theme_font_item_monospace">أحادي المسافة</string> + <string name="settings_theme_monochrome_icons">أيقونات تطبيقات أحادية اللون</string> + <string name="settings_clock_color">اللون</string> + <string name="settings_clock_time_visible">أظهر الوقت</string> + <string name="settings_clock_date_visible">أظهر التاريخ</string> + <string name="settings_clock_localized">استخدم تنسيق التاريخ المحلي</string> + <string name="settings_clock_flip_date_time">إقلب مكان التاريخ مع الوقت</string> + <string name="settings_theme_wallpaper">اختر خلفية</string> + <string name="settings_launcher_section_display">العرض</string> + <string name="settings_display_screen_timeout_disabled">حافظ على بقاء الشاشة قيد التشغيل</string> + <string name="settings_display_hide_status_bar">إخفِ شريط الحالة</string> + <string name="settings_display_rotate_screen">تدوير الشاشة</string> + <string name="settings_launcher_section_functionality">الوظائف</string> + <string name="settings_enabled_gestures_double_swipe">أوامر السحب بأصبعين</string> + <string name="settings_enabled_gestures_double_swipe_summary">اسحب باستخدام أصبعين</string> + <string name="settings_enabled_gestures_edge_swipe">أوامر السحب من الحواف</string> + <string name="settings_enabled_gestures_edge_swipe_edge_width">عرض الحواف</string> + <string name="settings_functionality_auto_launch">إظهار نتائج البحث</string> + <string name="settings_functionality_auto_launch_summary">اضغط مسافة لتعطيل هذه الميزة مؤقتًا</string> + <string name="settings_functionality_search_web">ابحث في الويب</string> + <string name="settings_functionality_auto_keyboard">أظهر لوحة المفاتيح عند البحث</string> + <string name="settings_launcher_sensitivity">الحساسية</string> + <string name="settings_launcher_section_apps">التطبيقات</string> + <string name="settings_apps_hidden">التطبيقات المخفية</string> + <string name="settings_launcher_section_date_time"><![CDATA[Date & time]]></string> + <string name="settings_apps_hide_private_space_apps">إخفِ المساحة الخاصة من قائمة التطبيقات</string> + <string name="settings_list_layout">تخطيط قائمة التطبيقات</string> + <string name="settings_list_layout_item_default">الافتراضي</string> + <string name="settings_list_layout_item_text">نص</string> + <string name="settings_list_layout_item_grid">شبكة</string> + <string name="settings_general_choose_home_screen">تعيين μauncher كشاشة المنزل</string> + <string name="settings_meta_cant_select_launcher">معلومات التطبيق</string> + <string name="settings_meta_reset">إعادة تعيين الإعدادات</string> + <string name="settings_meta_reset_confirm">أنت على وشك تجاهل كل تفضيلاتك، هل تريد الإكمال؟</string> + <string name="settings_meta_view_code">عرض شيفرة المصدر</string> + <string name="settings_meta_report_bug">الإبلاغ عن خطأ</string> + <string name="dialog_report_bug_button_clipboard">النسخ إلى الحافظة</string> + <string name="dialog_report_bug_security_info">يرجى عدم الإبلاغ عن الثغرات الأمنية علنًا على Github ، استخدم ما يلي بدلاً من ذلك:</string> + <string name="dialog_report_bug_button_security">الإبلاغ عن ثغرة أمنية</string> + <string name="dialog_report_bug_create_report">إنشاء تقرير</string> + <string name="settings_meta_fork_contact">اتصل بمطور النسخة</string> + <string name="settings_meta_join_chat">انضم إلى دردشة μauncher</string> + <string name="settings_meta_donate">تبرع</string> + <string name="settings_meta_privacy">سياسة الخصوصية</string> + <string name="list_title_view">كل التطبيقات</string> + <string name="list_title_favorite">التطبيقات المفضلة</string> + <string name="list_title_hidden">التطبيقات المخفية</string> + <string name="list_title_private_space">المساحة الخاصة</string> + <string name="list_title_pick">اختر تطبيق</string> + <string name="list_tab_app">التطبيقات</string> + <string name="list_tab_other">أخرى</string> + <string name="list_app_delete">إلغاء التثبيت</string> + <string name="list_app_favorite_remove">إزالة من المفضلة</string> + <string name="list_app_hidden_add">إخفِ</string> + <string name="list_app_hidden_remove">أظهر</string> + <string name="list_app_rename">إعادة التسمية</string> + <string name="list_apps_search_hint">بحث</string> + <string name="list_apps_search_hint_no_auto_launch">بحث (بدون تشغيل تلقائي)</string> + <string name="list_other_settings">اعدادات التطبيق</string> + <string name="list_other_list">درج التطبيقات</string> + <string name="list_other_list_private_space">المساحة الخاصة</string> + <string name="list_other_toggle_private_space_lock">تبديل قفل المساحة الخاصة</string> + <string name="list_other_volume_up">ارفع الصوت</string> + <string name="settings_meta_discord">إنضم إلى مجموعة discord!</string> + <string name="list_other_volume_adjust">ضبط مستوى الصوت</string> + <string name="list_other_track_previous">الموسيقى: السابق</string> + <string name="list_other_track_play_pause">الموسيقى: تشغيل / ايقاف مؤقت</string> + <string name="list_other_recent_apps">التطبيقات الحديثة</string> + <string name="list_other_nop">لا تفعل شيئًا</string> + <string name="list_other_lock_screen">قفل الشاشة</string> + <string name="list_other_torch">تبديل الفلاش</string> + <string name="list_other_launch_other_launcher">شغل شاشة منزل أخرى</string> + <string name="pin_shortcut_title">أضف اختصارًا</string> + <string name="pin_shortcut_button_bind">اربط بإيماءة</string> + <string name="tutorial_title">درس تعليمي</string> + <string name="tutorial_start_text">👋\n\nخذ بضع ثوان لمعرفة كيفية استخدام هذا المشغل!</string> + <string name="tutorial_concept_title">المفهوم</string> + <string name="tutorial_concept_text_2">إنه برنامج مجاني (ترخيص MIT)!\nتأكد من مراجعة المستودع!</string> + <string name="tutorial_concept_label_version">النسخة</string> + <string name="tutorial_usage_title">الاستخدام</string> + <string name="tutorial_usage_text">تحتوي شاشتك الرئيسية على التاريخ والوقت المحليين. لا الهاء.</string> + <string name="tutorial_app_list_title">كل التطبيقات</string> + <string name="tutorial_app_list_text_2">بمجرد تطابق تطبيق واحد فقط، يتم تشغيله تلقائيًا.\nيمكن تعطيل ذلك عن طريق اضافة مساحة في بداية استعلام.</string> + <string name="tutorial_setup_title">الإعداد</string> + <string name="tutorial_setup_text">اخترنا بعض التطبيقات الافتراضية لك. يمكنك تغييرها الآن إذا كنت تريد:</string> + <string name="tutorial_setup_text_2">يمكنك أيضًا تغيير اختيارك لاحقًا.</string> + <string name="tutorial_finish_title">لنبدأ!</string> + <string name="tutorial_finish_button">ابدأ</string> + <string name="settings">الإعدادات</string> + <string name="ic_menu_alt">المزيد من الخيارات</string> + <string name="alert_requires_android_m">هذه الوظيفة تتطلب أندرويد 6 أو أحدث.</string> + <string name="alert_requires_android_v">هذه الوظيفة تتطلب أندرويد 15 أو أحدث.</string> + <string name="undo">تراجع</string> + <string name="snackbar_app_hidden">تم إخفاء التطبيق. يمكنك جعله مرئيًا مرة أخرى في الإعدادات.</string> + <string name="list_other_expand_settings_panel">الاعدادات السريعة</string> + <string name="toast_device_admin_not_enabled">يجب أن يكون μlauncher مسؤولًا من أجل قفل الشاشة.</string> + <string name="device_admin_explanation">هذا مطلوب لإجراء شاشة القفل.</string> + <string name="device_admin_description">تمكين إجراء شاشة القفل</string> + <string name="alert_no_torch_found">لم يتم اكتشاف كاميرا مع فلاش.</string> + <string name="alert_torch_access_exception">خطأ: لا يمكن الوصول إلى الفلاش.</string> + <string name="alert_recent_apps_failed">خطأ: فشل في إظهار التطبيقات الحديثة. (إذا قمت للتو بترقية التطبيق ، فحاول تعطيل خدمة الوصول وإعادة تمكينها في إعدادات الهاتف)</string> + <string name="alert_enable_accessibility_failed">خطأ: فشل في تمكين خدمة الوصول.</string> + <string name="toast_accessibility_service_not_enabled">لم يتم تمكين خدمة الوصول إلى μlauncher. يرجى تمكينه في الإعدادات</string> + <string name="toast_private_space_locked">المساحة الخاصة مقفلة</string> + <string name="toast_private_space_unlocked">المساحة الخاصة مفتوحة</string> + <string name="toast_private_space_not_available">المساحة الخاصة غير متوافرة</string> + <string name="tooltip_lock_private_space">قفل المساحة الخاصة</string> + <string name="tooltip_unlock_private_space">فتح المساحة الخاصة</string> + <string name="accessibility_service_name">μLauncher</string> + <string name="screen_lock_method_dialog_title">اختر طريقة القفل</string> + <string name="screen_lock_method_use_accessibility">استخدام خدمة إمكانية الوصول</string> + <string name="screen_lock_method_use_device_admin">استخدم مسؤول الجهاز</string> + <string name="settings_actions_lock_method">اختر طريقة لقفل الشاشة</string> + <string name="dialog_rename_title">اعادة تسمية %1$s</string> + <string name="dialog_select_color_red">أحمر</string> + <string name="dialog_select_color_alpha">شفافية</string> + <string name="dialog_select_color_blue">أزرق</string> + <string name="dialog_select_color_green">أخضر</string> + <string name="dialog_select_color_color_hex">اللون</string> + <string name="dialog_choose_color_title">اختر لونًا</string> + <string name="dialog_consent_accessibility_privileges">أدرك أن هذا سيمنح أذونات كثيرة لـμauncher.</string> + <string name="dialog_consent_accessibility_other_options">أدرك وجود خيارات أخرى (باستخدام أذونات مسؤول الجهاز أو زر الطاقة).</string> + <string name="dialog_consent_accessibility_consent">أوافق لـμlauncher باستخدام خدمة إمكانية الوصول لتوفير الوظائف ليس لها صلة بإمكانية الوصول.</string> + <string name="dialog_consent_accessibility_data_collection">أوافق على أن μlauncher لا يجمع أي بيانات.</string> + <string name="dialog_consent_accessibility_title">يتم تفعيل خدمة إمكانية الوصول</string> + <string name="dialog_consent_accessibility_ok">تفعيل خدمة إمكانية الوصول</string> + <string name="dialog_cancel">إلغاء</string> + <string name="settings_meta_licenses">تراخيص المصادر المفتوحة</string> + <string name="legal_info_title">تراخيص المصادر المفتوحة</string> + <string name="toast_activity_not_found_search_web">لم يتم العثور على تطبيق للتعامل مع البحث.</string> + <string name="toast_activity_not_found_browser">لا يمكن فتح عنوان URL: لم يتم العثور على متصفح.</string> + <string name="dialog_consent_accessibility_text"><![CDATA[أنت على وشك تنشيط خدمة إمكانية الوصول. سيمنح هذا <strong> أذونات كثيرة </strong> إلى التطبيق: + <ul> + <li>قفل الشاشة</li> + <li>التطبيقات الحديثة</li> + </ul> + <strong> لن يقومμlauncher أبدًا بجمع أي بيانات </strong>. على وجه الخصوص ، لا يستخدم μlauncher خدمة إمكانية الوصول لجمع أي بيانات.]]></string> + <string name="settings_gesture_description_tap_down">أنقر ثم اسحب لأسفل</string> + <string name="settings_theme_color_theme_item_default">الافتراضي</string> + <string name="pin_shortcut_switch_visible">أظهر في قائمة التطبيقات</string> + <string name="settings_gesture_description_double_down">اسحب لأسفل بأصبعين</string> + <string name="settings_clock_show_seconds">أظهر الثواني</string> + <string name="dialog_report_bug_title">الإبلاغ عن خطأ</string> + <string name="settings_gesture_description_double_left">اسحب إلى اليسار بأصبعين</string> + <string name="settings_gesture_description_double_click">أنقر مرتين في مكان فارغ على الشاشة</string> + <string name="settings_functionality_search_web_summary">اضغط على زر الرجوع أثناء البحث في قائمة التطبيقات لإظهار البحث على الويب</string> + <string name="settings_gesture_description_right_top_edge">اسحب إلى اليمين من أعلى الشاشة</string> + <string name="settings_gesture_left_bottom_edge">يسار (في الأسفل)</string> + <string name="settings_gesture_description_up_right_edge">اسحب إلى الأعلى من حافة الشاشة اليمنى</string> + <string name="settings_gesture_description_swipe_lambda_reverse">أسفل اليمين -> أعلى الوسط -> أسفل اليسار</string> + <string name="settings_apps_hide_bound_apps">لا تظهر التطبيقات المرتبطة بإيماءة في قائمة التطبيقات</string> + <string name="list_other_list_favorites">درج التطبيقات المفضلة</string> + <string name="list_other_track_next">الموسيقى: التالي</string> + <string name="tutorial_concept_text">تم تصميم μlauncher ليكون فعال، وخالي من الهاء.\n\nلا يحتوي على أي إعلانات ولا يجمع أي بيانات.</string> + <string name="tutorial_finish_text">أنت مستعد للبدء!\n\nآمل أن يكون هذا ذا قيمة كبيرة بالنسبة لك!\n\n- المطورين</string> + <string name="toast_private_space_default_home_screen">يجب أن يكون μlauncher الشاشة الرئيسية الافتراضية للوصول إلى مساحة خاصة.</string> + <string name="settings_gesture_description_left_bottom_edge">اسحب إلى اليسار من أسفل الشاشة</string> + <string name="settings_gesture_description_swipe_smaller_reverse">أسفل اليمين -> وسط اليسار -> أعلى اليمين</string> + <string name="settings_apps_toast_store_not_found">لم يتم العثور على تطبيق المتجر</string> + <string name="settings_display_hide_navigation_bar">إخفِ شريط التنقل</string> + <string name="list_app_info">معلومات التطبيق</string> + <string name="list_app_favorite_add">أضف إلى المفضلة</string> + <string name="list_other_expand_notifications_panel">توسيع لوحة الاشعارات</string> + <string name="tutorial_app_list_text">يمكنك البحث بسرعة من خلال جميع التطبيقات في قائمة التطبيقات.\n\nاسحب لأعلى لفتح القائمة، أو ربطها بإيماءة ما.</string> + <string name="alert_lock_screen_failed">خطأ: فشل في قفل الشاشة. (إذا قمت للتو بترقية التطبيق ، فحاول تعطيل خدمة الوصول وإعادة تمكينها في إعدادات الهاتف)</string> + <string name="settings_gesture_description_down_right_edge">اسحب إلى الأسفل من حافة الشاشة اليمنى</string> + <string name="settings_theme_font_item_serif_monospace">أحادي المسافة مذيل</string> + <string name="settings_list_reverse_layout">عكس قائمة التطبيقات</string> + <string name="alert_cant_expand_status_bar_panel">خطأ: لا يمكن توسيع شريط الحالة. يستخدم هذا الإجراء وظيفة ليست جزءًا من نظام أندرويد. لسوء الحظ ، لا يبدو أنه يعمل على جهازك.</string> + <string name="settings_theme_background">خلفية القوائم</string> + <string name="settings_apps_hide_paused_apps">إخفِ التطبيقات المتوقفة</string> + <string name="settings_meta_show_tutorial">أظهر العرض التعليمي للتطبيق</string> + <string name="dialog_report_bug_info">شكرا لك على المساعدة في تحسين μLauncher!\nيرجى إضافة المعلومات التالية إلى تقرير الأخطاء الخاص بك:</string> + <string name="settings_meta_contact">اتصل بالمطور الأصلي</string> + <string name="list_other_volume_down">اخفض الصوت</string> + <string name="tutorial_usage_text_2">يمكنك تشغيل أهم تطبيقاتك بوسطة إيماءات اللمس أو الضغط على الأزرار.</string> + <string name="settings_enabled_gestures_edge_swipe_summary">اسحب من حواف الشاشة</string> + <string name="toast_lock_screen_not_supported">خطأ: قفل الشاشة باستخدام إمكانية الوصول غير مدعوم على هذا الجهاز. الرجاء استخدام طريقة مسؤول الجهاز بدلاً من ذلك.</string> + <string name="accessibility_service_description">يتيح تعيين μlauncher كخدمة إمكانية الوصول قفل الشاشة وفتح قائمة التطبيقات الحديثة. يرجى ملاحظة أنه يتطلب كمية كبيرة من الأذونات. يجب ألا تمنح مثل هذه الأذونات باستخفاف لأي تطبيق. سوف يستخدم μlauncher خدمة إمكانية الوصول فقط لأداء الإجراءات التالية عند طلب المستخدم: * قفل شاشة * فتح التطبيقات الحديثة μlauncher لن يستخدم أبدًا خدمة إمكانية الوصول لجمع البيانات. يمكنك التحقق من شيفرة المصدر للتأكد. يرجى ملاحظة أنه يمكنك قفل الشاشة من خلال منح أذونات مسؤول الجهاز، لكنها لا تعمل مع بصمات الأصابع وفتح الوجه.</string> +</resources> From 2774b74d9d47539dcb08fb29bdce6b1ffd409965 Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Tue, 15 Apr 2025 18:38:00 +0200 Subject: [PATCH 71/73] 0.1.4 --- app/build.gradle | 4 ++-- fastlane/metadata/android/en-US/changelogs/44.txt | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 fastlane/metadata/android/en-US/changelogs/44.txt diff --git a/app/build.gradle b/app/build.gradle index c280794..1a0a6fb 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -23,8 +23,8 @@ android { minSdkVersion 21 targetSdkVersion 35 compileSdk 35 - versionCode 43 - versionName "0.1.3" + versionCode 44 + versionName "0.1.4" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/fastlane/metadata/android/en-US/changelogs/44.txt b/fastlane/metadata/android/en-US/changelogs/44.txt new file mode 100644 index 0000000..6c6c4f7 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/44.txt @@ -0,0 +1,11 @@ +* New action: Launch other launchers +* New action: Show recent apps (workaround for an Android bug) +* Fixed "Set µLauncher as home screen" button +* Size of "choose app" button was limited + +* Added Arabic translation (thank you, letterhaven!) +* Started Lithuanian translation (thank you, IdeallyGrey!) +* Improved Chinese translation (thank you, monkeyotg!) +* Improved Portuguese translation (thank you, "Vossa Excelencia"!) +* Improved Spanish translation (thank you, T!) + From 4f795289d5176fb6c9130cd8aa136061eb6d0793 Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Tue, 15 Apr 2025 18:55:13 +0200 Subject: [PATCH 72/73] improve English translation --- app/src/main/res/values/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a8bc9b3..21f25f5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -251,12 +251,12 @@ <string name="list_other_track_next">Music: Next</string> <string name="list_other_track_previous">Music: Previous</string> <string name="list_other_track_play_pause">Music: Play / Pause</string> - <string name="list_other_expand_notifications_panel">Expand notifications panel</string> + <string name="list_other_expand_notifications_panel">Expand Notifications Panel</string> <string name="list_other_recent_apps">Recent Apps</string> - <string name="list_other_nop">Do nothing</string> + <string name="list_other_nop">Do Nothing</string> <string name="list_other_lock_screen">Lock Screen</string> <string name="list_other_torch">Toggle Torch</string> - <string name="list_other_launch_other_launcher">Launch other Home Screen</string> + <string name="list_other_launch_other_launcher">Launch Other Home Screen</string> <!-- Pin shortcuts --> <string name="pin_shortcut_title">Add Shortcut</string> From 22633bdac3d057b552258d8bd84868c9cc7473b8 Mon Sep 17 00:00:00 2001 From: Josia Pietsch <git@jrpie.de> Date: Tue, 15 Apr 2025 19:24:23 +0200 Subject: [PATCH 73/73] try to fix #138 --- .../jrpie/android/launcher/ui/HomeActivity.kt | 45 ++++++++++--------- 1 file changed, 24 insertions(+), 21 deletions(-) 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 53a0876..2ab5d9f 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 @@ -37,7 +37,7 @@ import java.util.Locale class HomeActivity : UIObject, AppCompatActivity() { private lateinit var binding: HomeBinding - private lateinit var touchGestureDetector: TouchGestureDetector + private var touchGestureDetector: TouchGestureDetector? = null private var sharedPreferencesListener = SharedPreferences.OnSharedPreferenceChangeListener { _, prefKey -> @@ -56,29 +56,12 @@ class HomeActivity : UIObject, AppCompatActivity() { super<AppCompatActivity>.onCreate(savedInstanceState) super<UIObject>.onCreate() - touchGestureDetector = TouchGestureDetector( - this, 0, 0, - LauncherPreferences.enabled_gestures().edgeSwipeEdgeWidth() / 100f - ) - touchGestureDetector.updateScreenSize(windowManager) // Initialise layout binding = HomeBinding.inflate(layoutInflater) setContentView(binding.root) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - binding.root.setOnApplyWindowInsetsListener { _, windowInsets -> - @Suppress("deprecation") // required to support API 29 - val insets = windowInsets.systemGestureInsets - touchGestureDetector.setSystemGestureInsets(insets) - - windowInsets - } - } - - - // Handle back key / gesture on Android 13+, cf. onKeyDown() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { onBackInvokedDispatcher.registerOnBackInvokedCallback( @@ -94,7 +77,7 @@ class HomeActivity : UIObject, AppCompatActivity() { override fun onConfigurationChanged(newConfig: Configuration) { super.onConfigurationChanged(newConfig) - touchGestureDetector.updateScreenSize(windowManager) + touchGestureDetector?.updateScreenSize(windowManager) } override fun onStart() { @@ -188,8 +171,28 @@ class HomeActivity : UIObject, AppCompatActivity() { override fun onResume() { super.onResume() - touchGestureDetector.edgeWidth = + /* This should be initialized in onCreate() + However on some devices there seems to be a bug where the touchGestureDetector + is not working properly after resuming the app. + Reinitializing the touchGestureDetector every time the app is resumed might help to fix that. + (see issue #138) + */ + touchGestureDetector = TouchGestureDetector( + this, 0, 0, LauncherPreferences.enabled_gestures().edgeSwipeEdgeWidth() / 100f + ).also { + it.updateScreenSize(windowManager) + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + binding.root.setOnApplyWindowInsetsListener { _, windowInsets -> + @Suppress("deprecation") // required to support API 29 + val insets = windowInsets.systemGestureInsets + touchGestureDetector?.setSystemGestureInsets(insets) + + windowInsets + } + } initClock() updateSettingsFallbackButtonVisibility() @@ -230,7 +233,7 @@ class HomeActivity : UIObject, AppCompatActivity() { } override fun onTouchEvent(event: MotionEvent): Boolean { - touchGestureDetector.onTouchEvent(event) + touchGestureDetector?.onTouchEvent(event) return true }