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() - 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...onCreate(savedInstanceState) super.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.onStart() + super.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 @@ + + + + + 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 @@ + + + + + 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 f0237e8..0000000 Binary files a/app/src/main/res/drawable/home_round_screen.png and /dev/null differ 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 @@ + + + + + \ 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 0000000..66ebaaf Binary files /dev/null and b/app/src/main/res/drawable/tutorial_app_list.png differ 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 0000000..ccbce5d Binary files /dev/null and b/app/src/main/res/drawable/tutorial_home_screen.png differ 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" /> \ 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" /> + tools:text="@string/app_name" /> \ No newline at end of file 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"> - + + + + + + app:layout_constraintTop_toBottomOf="@+id/tutorial_viewpager" /> \ 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"> - - - \ 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"> + app:layout_constraintBottom_toTopOf="@id/tutorial_concept_badge_version_label"/> + + 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"> + + + + + + + + + + + \ 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"> + tools:context=".ui.tutorial.tabs.TutorialFragment5Finish"> µLauncher +

μLauncher

Modifications to Launcher.

github.com/jrpie/launcher

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 @@ Set μLauncher as home screen App Info - View Launcher Tutorial + View µLauncher Tutorial Reset Settings You are going to discard all your preferences. Continue? @@ -202,14 +202,14 @@ Report a bug Report a bug - Thank you for helping to improve µLauncher!\nPlease consider adding the following information to your bug report: + Thank you for helping to improve μLauncher!\nPlease consider adding the following information to your bug report: Copy to clipboard Please do not report security vulnerabilities publicly on GitHub, but use the following instead: Report a security vulnerability Create report Contact the developer of the fork - Join µLauncher chat + Join μLauncher chat Donate Privacy Policy @@ -246,7 +246,7 @@ Search Search (no auto launch) - µLauncher Settings + μLauncher Settings All Applications Favorite Applications Private Space @@ -274,22 +274,29 @@ - --> Tutorial - Take a few seconds to learn how to use this Launcher! + 👋\n\nTake a few seconds to learn how to use this Launcher! Concept - Launcher is designed to be minimal, efficient and free of distraction. It is free of payments, ads and tracking services. - The app is open-source (MIT license) and available on GitHub! Make sure to check out the repository! + μLauncher is designed to be minimal, efficient and free of distraction. + \n\nIt contains no ads and collects no data. + It is free software (MIT license)!\nMake sure to check out the repository! + Version Usage Your home screen contains the local date and time. No distraction. - You can launch your apps with a single swipe or button press. Choose some in the next slide. + You can launch your most important apps with touch gestures or button presses. + + All Apps + You can quickly search through all apps in the app list.\n\nSwipe up to open it, or bind it to a different gesture. + Once only one app matches, it launches automatically.\nThis can be disabled by prefixing the query with a space. + Setup We chose some default apps for you. You can change them now if you want to: You can also change your selection later. Let\'s go! - 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) + 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) Start @@ -301,7 +308,7 @@ App hidden. You can make it visible again in settings. Undo Quick Settings - µLauncher needs to be a device admin in order to lock the screen. + μLauncher needs to be a device admin in order to lock the screen. This is required for the lock screen action. Enable the lock screen action No camera with torch detected. @@ -311,18 +318,18 @@ Private space locked Private space unlocked Private space is not available - µLauncher needs to be the default home screen to access private space. + μLauncher needs to be the default home screen to access private space. Lock private space Unlock private space Error: Locking the screen using accessibility is not supported on this device. Please use device admin instead. - µLauncher - lock screen + μLauncher - lock screen - 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. @@ -340,7 +347,7 @@

Accessibility Service

Requires excessive privileges. - µLauncher will use those privileges only for locking the screen. + μLauncher will use those privileges only for locking the screen.
(You really should not trust a random app you just downloaded with such a claim, but you can check the source code.)
@@ -363,11 +370,11 @@ Ok Color Choose color - I am aware that this will grant far-reaching privileges to µLauncher. + I am aware that this will grant far-reaching privileges to μLauncher. I am aware that other options exist (using device administrator privileges or the power button). - I consent to µLauncher using the accessibility service to provide functionality unrelated to accessibility. - I consent to µLauncher not collecting any data. - far-reaching privileges to µLauncher.
µLauncher will use these privileges only to lock the screen. µLauncher will never collect any data. In particular, µLauncher does not use the accessibility service to collect any data.]]>
+ I consent to μLauncher using the accessibility service to provide functionality unrelated to accessibility. + I consent to μLauncher not collecting any data. + far-reaching privileges to μLauncher.
μLauncher will use these privileges only to lock the screen. μLauncher will never collect any data. In particular, μLauncher does not use the accessibility service to collect any data.]]>
Activating the Accessibility Service Activate Accessibility Service Cancel