diff --git a/README.md b/README.md
index 016b362..ce1d0d0 100644
--- a/README.md
+++ b/README.md
@@ -59,6 +59,7 @@ The following gestures are available:
- swipe up / down / left / right,
- swipe with two fingers,
- swipe on the left / right resp. top / bottom edge,
+ - tap, then swipe up / down / left / right,
- draw < / > / V / Λ
- click on date / time,
- double click,
diff --git a/app/build.gradle b/app/build.gradle
index 53dc960..c81509c 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -23,8 +23,8 @@ android {
minSdkVersion 21
targetSdkVersion 35
compileSdk 35
- versionCode 37
- versionName "0.0.21"
+ versionCode 38
+ versionName "0.0.22"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
@@ -95,6 +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.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/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 3096d6d..93f6ce8 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -19,6 +19,16 @@
android:supportsRtl="true"
android:theme="@style/launcherBaseTheme"
tools:ignore="UnusedAttribute">
+
+
+
+
+
+ = VERSION_CODES.N_MR1) {
+ removeUnusedShortcuts(this)
+ }
loadApps()
}
diff --git a/app/src/main/java/de/jrpie/android/launcher/Functions.kt b/app/src/main/java/de/jrpie/android/launcher/Functions.kt
index 5f7e9c9..8fc95a3 100644
--- a/app/src/main/java/de/jrpie/android/launcher/Functions.kt
+++ b/app/src/main/java/de/jrpie/android/launcher/Functions.kt
@@ -9,7 +9,9 @@ import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
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
@@ -18,8 +20,11 @@ import android.os.UserManager
import android.provider.Settings
import android.util.Log
import android.widget.Toast
+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.AppInfo
import de.jrpie.android.launcher.apps.DetailedAppInfo
import de.jrpie.android.launcher.apps.getPrivateSpaceUser
@@ -81,6 +86,34 @@ fun getUserFromId(userId: Int?, context: Context): UserHandle {
return profiles.firstOrNull { it.hashCode() == userId } ?: profiles[0]
}
+@RequiresApi(Build.VERSION_CODES.N_MR1)
+fun removeUnusedShortcuts(context: Context) {
+ val launcherApps = context.getSystemService(Service.LAUNCHER_APPS_SERVICE) as LauncherApps
+ fun getShortcuts(profile: UserHandle): List? {
+ return launcherApps.getShortcuts(
+ ShortcutQuery().apply {
+ setQueryFlags(ShortcutQuery.FLAG_MATCH_PINNED)
+ },
+ profile
+ )
+ }
+
+ val userManager = context.getSystemService(Service.USER_SERVICE) as UserManager
+ val boundActions: Set =
+ Gesture.entries.mapNotNull { Action.forGesture(it) as? ShortcutAction }.map { it.shortcut }
+ .toSet()
+ try {
+ userManager.userProfiles.filter { !userManager.isQuietModeEnabled(it) }.forEach { profile ->
+ getShortcuts(profile)?.groupBy { it.`package` }?.forEach { (p, shortcuts) ->
+ launcherApps.pinShortcuts(p,
+ shortcuts.filter { boundActions.contains(PinnedShortcutInfo(it)) }
+ .map { it.id }.toList(),
+ profile
+ )
+ }
+ }
+ } catch (_: SecurityException) { }
+}
fun openInBrowser(url: String, context: Context) {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
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 a4f25b4..110e4f8 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
@@ -79,6 +79,13 @@ enum class Gesture(
R.array.default_up_right,
R.anim.bottom_up
),
+ TAP_AND_SWIPE_UP(
+ "action.tap_up",
+ R.string.settings_gesture_tap_up,
+ R.string.settings_gesture_description_tap_up,
+ R.array.default_up,
+ R.anim.bottom_up
+ ),
SWIPE_UP_DOUBLE(
"action.double_up",
R.string.settings_gesture_double_up,
@@ -107,6 +114,13 @@ enum class Gesture(
R.array.default_down_right,
R.anim.top_down
),
+ TAP_AND_SWIPE_DOWN(
+ "action.tap_down",
+ R.string.settings_gesture_tap_down,
+ R.string.settings_gesture_description_tap_down,
+ R.array.default_down,
+ R.anim.bottom_up
+ ),
SWIPE_DOWN_DOUBLE(
"action.double_down",
R.string.settings_gesture_double_down,
@@ -135,6 +149,13 @@ enum class Gesture(
R.array.default_messengers,
R.anim.right_left
),
+ TAP_AND_SWIPE_LEFT(
+ "action.tap_left",
+ R.string.settings_gesture_tap_left,
+ R.string.settings_gesture_description_tap_left,
+ R.array.default_messengers,
+ R.anim.right_left
+ ),
SWIPE_LEFT_DOUBLE(
"action.double_left",
R.string.settings_gesture_double_left,
@@ -163,6 +184,13 @@ enum class Gesture(
R.array.default_right_bottom,
R.anim.left_right
),
+ TAP_AND_SWIPE_RIGHT(
+ "action.tap_right",
+ R.string.settings_gesture_tap_right,
+ R.string.settings_gesture_description_tap_right,
+ R.array.default_right,
+ R.anim.left_right
+ ),
SWIPE_RIGHT_DOUBLE(
"action.double_right",
R.string.settings_gesture_double_right,
@@ -279,6 +307,17 @@ enum class Gesture(
}
}
+ fun getTapComboVariant(): Gesture {
+ return when (this) {
+ SWIPE_UP -> TAP_AND_SWIPE_UP
+ SWIPE_DOWN -> TAP_AND_SWIPE_DOWN
+ SWIPE_LEFT -> TAP_AND_SWIPE_LEFT
+ SWIPE_RIGHT -> TAP_AND_SWIPE_RIGHT
+ else -> this
+ }
+
+ }
+
fun isDoubleVariant(): Boolean {
return when (this) {
SWIPE_UP_DOUBLE,
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
new file mode 100644
index 0000000..8517b1a
--- /dev/null
+++ b/app/src/main/java/de/jrpie/android/launcher/actions/ShortcutAction.kt
@@ -0,0 +1,57 @@
+package de.jrpie.android.launcher.actions
+
+import android.app.Service
+import android.content.Context
+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 kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
+
+@Serializable
+@SerialName("action:shortcut")
+class ShortcutAction(val shortcut: PinnedShortcutInfo) : Action {
+
+ override fun invoke(context: Context, rect: Rect?): Boolean {
+ val launcherApps = context.getSystemService(Service.LAUNCHER_APPS_SERVICE) as LauncherApps
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) {
+ // TODO
+ return false
+ }
+ shortcut.getShortcutInfo(context)?.let {
+ launcherApps.startShortcut(it, rect, null)
+ }
+
+ // TODO: handle null
+ return true
+ }
+
+ override fun label(context: Context): String {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) {
+ return "?"
+ }
+
+ return shortcut.getShortcutInfo(context)?.longLabel?.toString() ?: "?"
+ }
+
+ override fun getIcon(context: Context): Drawable? {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) {
+ return null
+ }
+ val launcherApps = context.getSystemService(Service.LAUNCHER_APPS_SERVICE) as LauncherApps
+ return shortcut.getShortcutInfo(context)?.let { launcherApps.getShortcutBadgedIconDrawable(it, 0) }
+ }
+
+ override fun isAvailable(context: Context): Boolean {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) {
+ return false
+ }
+ return shortcut.getShortcutInfo(context) != null
+ }
+
+ override fun canReachSettings(): Boolean {
+ return false
+ }
+}
\ 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/actions/shortcuts/PinnedShortcutInfo.kt
new file mode 100644
index 0000000..796c737
--- /dev/null
+++ b/app/src/main/java/de/jrpie/android/launcher/actions/shortcuts/PinnedShortcutInfo.kt
@@ -0,0 +1,60 @@
+package de.jrpie.android.launcher.actions.shortcuts
+
+import android.app.Service
+import android.content.ComponentName
+import android.content.Context
+import android.content.pm.LauncherApps
+import android.content.pm.LauncherApps.ShortcutQuery
+import android.content.pm.ShortcutInfo
+import android.os.Build
+import androidx.annotation.RequiresApi
+import de.jrpie.android.launcher.getUserFromId
+import kotlinx.serialization.Serializable
+
+
+@RequiresApi(Build.VERSION_CODES.N_MR1)
+@Serializable
+class PinnedShortcutInfo(
+ val id: String,
+ val packageName: String,
+ val activityName: String,
+ val user: Int
+) {
+
+ constructor(info: ShortcutInfo) : this(info.id, info.`package`, info.activity?.className ?: "", info.userHandle.hashCode())
+
+ 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()
+ }
+
+ 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/ui/PinShortcutActivity.kt b/app/src/main/java/de/jrpie/android/launcher/ui/PinShortcutActivity.kt
new file mode 100644
index 0000000..d19fe04
--- /dev/null
+++ b/app/src/main/java/de/jrpie/android/launcher/ui/PinShortcutActivity.kt
@@ -0,0 +1,128 @@
+package de.jrpie.android.launcher.ui
+
+import android.app.AlertDialog
+import android.app.Service
+import android.content.Context
+import android.content.pm.LauncherApps
+import android.content.pm.LauncherApps.PinItemRequest
+import android.content.res.Resources
+import android.os.Build
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.TextView
+import androidx.activity.enableEdgeToEdge
+import androidx.appcompat.app.AppCompatActivity
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+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.databinding.ActivityPinShortcutBinding
+import de.jrpie.android.launcher.preferences.LauncherPreferences
+
+class PinShortcutActivity : AppCompatActivity(), UIObject {
+ private lateinit var binding: ActivityPinShortcutBinding
+
+ private var isBound = false
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ super.onCreate()
+ enableEdgeToEdge()
+
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
+ finish()
+ return
+ }
+
+ binding = ActivityPinShortcutBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ val launcherApps = getSystemService(Service.LAUNCHER_APPS_SERVICE) as LauncherApps
+
+ val request = launcherApps.getPinItemRequest(intent)
+ if (request == null || request.requestType != PinItemRequest.REQUEST_TYPE_SHORTCUT) {
+ finish()
+ return
+ }
+
+ binding.pinShortcutLabel.text = request.shortcutInfo!!.shortLabel ?: "?"
+ binding.pinShortcutLabel.setCompoundDrawables(
+ launcherApps.getShortcutBadgedIconDrawable(request.shortcutInfo, 0).also {
+ val size = (40 * resources.displayMetrics.density).toInt()
+ it.setBounds(0,0, size, size)
+ }, null, null, null)
+
+ binding.pinShortcutButtonBind.setOnClickListener {
+ AlertDialog.Builder(this, R.style.AlertDialogCustom)
+ .setTitle(getString(R.string.pin_shortcut_button_bind))
+ .setView(R.layout.dialog_select_gesture)
+ .setNegativeButton(android.R.string.cancel, null)
+ .create().also { it.show() }.let { dialog ->
+ val viewManager = LinearLayoutManager(dialog.context)
+ val viewAdapter = GestureRecyclerAdapter (dialog.context) { gesture ->
+ if (!isBound) {
+ isBound = true
+ request.accept()
+ }
+ val editor = LauncherPreferences.getSharedPreferences().edit()
+ ShortcutAction(PinnedShortcutInfo(request.shortcutInfo!!)).bindToGesture(editor, gesture.id)
+ editor.apply()
+ dialog.dismiss()
+ }
+ dialog.findViewById(R.id.dialog_select_gesture_recycler).apply {
+ setHasFixedSize(true)
+ layoutManager = viewManager
+ adapter = viewAdapter
+ }
+ }
+ }
+
+ binding.pinShortcutClose.setOnClickListener { finish() }
+ }
+
+ override fun onStart() {
+ super.onStart()
+ super.onStart()
+ }
+
+ override fun getTheme(): Resources.Theme {
+ return modifyTheme(super.getTheme())
+ }
+
+ inner class GestureRecyclerAdapter(val context: Context, val onClick: (Gesture) -> Unit): RecyclerView.Adapter() {
+ val gestures = Gesture.entries.filter { it.isEnabled() }.toList()
+ inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+ val label = itemView.findViewById(R.id.dialog_select_gesture_row_name)
+ val description = itemView.findViewById(R.id.dialog_select_gesture_row_description)
+ val icon = itemView.findViewById(R.id.dialog_select_gesture_row_icon)
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ val inflater = LayoutInflater.from(parent.context)
+ val view: View = inflater.inflate(R.layout.dialog_select_gesture_row, parent, false)
+ return ViewHolder(view)
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val gesture = gestures[position]
+ holder.label.text = gesture.getLabel(context)
+ holder.description.text = gesture.getDescription(context)
+ holder.icon.setImageDrawable(
+ Action.forGesture(gesture)?.getIcon(context)
+ )
+ holder.itemView.setOnClickListener {
+ onClick(gesture)
+ }
+ }
+
+ 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/TouchGestureDetector.kt b/app/src/main/java/de/jrpie/android/launcher/ui/TouchGestureDetector.kt
index 0ddbfd1..00629a5 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
@@ -240,6 +240,10 @@ class TouchGestureDetector(
gesture = gesture?.getEdgeVariant(Gesture.Edge.BOTTOM)
}
}
+
+ if (timeStart - lastTappedTime < 2 * DOUBLE_TAP_TIMEOUT) {
+ gesture = gesture?.getTapComboVariant()
+ }
gesture?.invoke(context)
}
}
diff --git a/app/src/main/res/drawable/baseline_close_24.xml b/app/src/main/res/drawable/baseline_close_24.xml
index 41350ac..2ab439d 100644
--- a/app/src/main/res/drawable/baseline_close_24.xml
+++ b/app/src/main/res/drawable/baseline_close_24.xml
@@ -1,7 +1,6 @@
diff --git a/app/src/main/res/drawable/baseline_favorite_24.xml b/app/src/main/res/drawable/baseline_favorite_24.xml
index 4f9b020..5a612d2 100644
--- a/app/src/main/res/drawable/baseline_favorite_24.xml
+++ b/app/src/main/res/drawable/baseline_favorite_24.xml
@@ -1,7 +1,6 @@
diff --git a/app/src/main/res/drawable/baseline_favorite_border_24.xml b/app/src/main/res/drawable/baseline_favorite_border_24.xml
index cecc9b0..14875dd 100644
--- a/app/src/main/res/drawable/baseline_favorite_border_24.xml
+++ b/app/src/main/res/drawable/baseline_favorite_border_24.xml
@@ -1,7 +1,6 @@
diff --git a/app/src/main/res/drawable/baseline_flashlight_on_24.xml b/app/src/main/res/drawable/baseline_flashlight_on_24.xml
index e1326ae..16654cd 100644
--- a/app/src/main/res/drawable/baseline_flashlight_on_24.xml
+++ b/app/src/main/res/drawable/baseline_flashlight_on_24.xml
@@ -1,7 +1,6 @@
diff --git a/app/src/main/res/drawable/baseline_lock_24.xml b/app/src/main/res/drawable/baseline_lock_24.xml
index 1e96180..8cb2d1f 100644
--- a/app/src/main/res/drawable/baseline_lock_24.xml
+++ b/app/src/main/res/drawable/baseline_lock_24.xml
@@ -2,9 +2,8 @@
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
- android:viewportHeight="960"
- android:tint="?attr/colorControlNormal">
-
+ android:viewportHeight="960">
+
diff --git a/app/src/main/res/drawable/baseline_lock_open_24.xml b/app/src/main/res/drawable/baseline_lock_open_24.xml
index f0f6ea3..8d8e09b 100644
--- a/app/src/main/res/drawable/baseline_lock_open_24.xml
+++ b/app/src/main/res/drawable/baseline_lock_open_24.xml
@@ -1,7 +1,6 @@
+
-
+
diff --git a/app/src/main/res/drawable/baseline_more_horiz_24.xml b/app/src/main/res/drawable/baseline_more_horiz_24.xml
index a370298..061fae2 100644
--- a/app/src/main/res/drawable/baseline_more_horiz_24.xml
+++ b/app/src/main/res/drawable/baseline_more_horiz_24.xml
@@ -1,5 +1,11 @@
-
+
-
+
diff --git a/app/src/main/res/drawable/baseline_not_interested_24.xml b/app/src/main/res/drawable/baseline_not_interested_24.xml
index 48ab05d..875f546 100644
--- a/app/src/main/res/drawable/baseline_not_interested_24.xml
+++ b/app/src/main/res/drawable/baseline_not_interested_24.xml
@@ -1,7 +1,6 @@
diff --git a/app/src/main/res/drawable/baseline_notifications_24.xml b/app/src/main/res/drawable/baseline_notifications_24.xml
index b695693..ca969df 100644
--- a/app/src/main/res/drawable/baseline_notifications_24.xml
+++ b/app/src/main/res/drawable/baseline_notifications_24.xml
@@ -1,7 +1,6 @@
diff --git a/app/src/main/res/drawable/baseline_search_24.xml b/app/src/main/res/drawable/baseline_search_24.xml
index ca9cbc0..9ba30e3 100644
--- a/app/src/main/res/drawable/baseline_search_24.xml
+++ b/app/src/main/res/drawable/baseline_search_24.xml
@@ -1,7 +1,6 @@
diff --git a/app/src/main/res/drawable/baseline_security_24.xml b/app/src/main/res/drawable/baseline_security_24.xml
index 3c260ff..cd38b06 100644
--- a/app/src/main/res/drawable/baseline_security_24.xml
+++ b/app/src/main/res/drawable/baseline_security_24.xml
@@ -1,6 +1,5 @@
diff --git a/app/src/main/res/drawable/baseline_settings_24.xml b/app/src/main/res/drawable/baseline_settings_24.xml
index 7cb5b17..4200acc 100644
--- a/app/src/main/res/drawable/baseline_settings_24.xml
+++ b/app/src/main/res/drawable/baseline_settings_24.xml
@@ -1,7 +1,6 @@
diff --git a/app/src/main/res/drawable/baseline_settings_applications_24.xml b/app/src/main/res/drawable/baseline_settings_applications_24.xml
index f2d03cc..dd30af7 100644
--- a/app/src/main/res/drawable/baseline_settings_applications_24.xml
+++ b/app/src/main/res/drawable/baseline_settings_applications_24.xml
@@ -1,7 +1,6 @@
diff --git a/app/src/main/res/drawable/baseline_skip_next_24.xml b/app/src/main/res/drawable/baseline_skip_next_24.xml
index 0091e03..9e203e0 100644
--- a/app/src/main/res/drawable/baseline_skip_next_24.xml
+++ b/app/src/main/res/drawable/baseline_skip_next_24.xml
@@ -1,7 +1,6 @@
diff --git a/app/src/main/res/drawable/baseline_skip_previous_24.xml b/app/src/main/res/drawable/baseline_skip_previous_24.xml
index 0029a3e..832a188 100644
--- a/app/src/main/res/drawable/baseline_skip_previous_24.xml
+++ b/app/src/main/res/drawable/baseline_skip_previous_24.xml
@@ -1,7 +1,6 @@
diff --git a/app/src/main/res/drawable/baseline_volume_down_24.xml b/app/src/main/res/drawable/baseline_volume_down_24.xml
index 78b51d3..1a34ad9 100644
--- a/app/src/main/res/drawable/baseline_volume_down_24.xml
+++ b/app/src/main/res/drawable/baseline_volume_down_24.xml
@@ -2,7 +2,6 @@
android:width="24dp"
android:height="24dp"
android:autoMirrored="true"
- android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
diff --git a/app/src/main/res/drawable/baseline_volume_up_24.xml b/app/src/main/res/drawable/baseline_volume_up_24.xml
index 6737fa6..f147499 100644
--- a/app/src/main/res/drawable/baseline_volume_up_24.xml
+++ b/app/src/main/res/drawable/baseline_volume_up_24.xml
@@ -2,7 +2,6 @@
android:width="24dp"
android:height="24dp"
android:autoMirrored="true"
- android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
diff --git a/app/src/main/res/layout/activity_pin_shortcut.xml b/app/src/main/res/layout/activity_pin_shortcut.xml
new file mode 100644
index 0000000..c401b42
--- /dev/null
+++ b/app/src/main/res/layout/activity_pin_shortcut.xml
@@ -0,0 +1,110 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_select_gesture.xml b/app/src/main/res/layout/dialog_select_gesture.xml
new file mode 100644
index 0000000..e8f2a19
--- /dev/null
+++ b/app/src/main/res/layout/dialog_select_gesture.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_select_gesture_row.xml b/app/src/main/res/layout/dialog_select_gesture_row.xml
new file mode 100644
index 0000000..863df99
--- /dev/null
+++ b/app/src/main/res/layout/dialog_select_gesture_row.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index afc92da..320bfc6 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -4,7 +4,7 @@
AspettoScegliere l\'applicazioneTema
- Questo launcher è progettato per essere minimale, efficiente e privo di distrazioni.\n\nNon contiene pagamenti, pubblicità o servizi di tracciamento.
+ Questo launcher è progettato per essere minimale, efficiente e privo di distrazioni. Non contiene pagamenti, pubblicità o servizi di tracciamento.PredefinitoNon mostrare applicazioni collegate a gesti nella lista delle appTesto
@@ -45,11 +45,11 @@
Scorri verso il basso con due ditaSinistraScorrere verso sinistra
- Doppio a sinistra
+ Due dita verso sinistraScorrere verso sinistra con due ditaDestraScorri verso destra
- Doppio a destra
+ Due dita verso destraScorri a destra con due ditaDestra (in alto)Scorri verso destra sul bordo superiore dello schermo
@@ -125,12 +125,12 @@
Abbiamo impostato alcune app predefinite per te. Puoi modificarle ora se lo desideri:Puoi anche cambiare la tua selezione in seguito.Iniziamo!
- Sei pronto per iniziare!\n\nSpero questa applicazione ti risulti preziosa!\n\n- Finn (che ha ideato il launcher)\n\t e Josia (che ha aggiunto qualche miglioramento e mantiene il fork μLauncher)
+ Sei pronto per iniziare! Spero questa applicazione ti risulti preziosa! - Finn (che ha ideato il launcher)\n \te Josia (che ha aggiunto qualche miglioramento e mantiene il fork μLauncher)IniziaImpostazioniAltre opzioniPuoi aprire le tue app facendo scorrere il dito sullo schermo o premendo un pulsante. Configura i gesti nella prossima slide.
- Errore: impossibile espandere la barra di stato.\nQuesta azione utilizza funzionalità non incluse nelle API Android pubbliche. Sfortunatamente, non sembra funzionare sul tuo dispositivo.
+ Errore: impossibile espandere la barra di stato. Questa azione utilizza funzionalità non incluse nelle API Android pubbliche. Sfortunatamente, non sembra funzionare sul tuo dispositivo.Applicazione nascosta. Puoi renderla nuovamente visibile nelle impostazioni.µLauncher deve essere autorizzato come amministratore del dispositivo per bloccare lo schermo.Abilita il blocco dello schermo
@@ -182,7 +182,7 @@
MostraRinominaLe applicazioni selezionate sono state rimosse
- Cerca tra le applicazioni
+ CercaImpostazioni μLauncherEspandi il pannello notificheNon fare niente
@@ -191,11 +191,50 @@
TutorialPrenditi qualche secondo per imparare ad usare questo launcher!Concetto
- L\'app è open source (sotto licenza MIT) e disponibile su GitHub!\n\nVisita il nostro archivio!
+ L\'app è open source (sotto licenza MIT) e disponibile su GitHub! Visita il nostro archivio!UtilizzoLa schermata principale contiene solo data e ora. Nessuna distrazione.
- Questa funzione richiede Android 6.0 o successivi.
+ Questa funzione richiede Android 6 o successivi.OkRinomina %1$sImpossibile rimuovere l\'applicazione
+ Dinamico
+ Colore
+ Due dita verso l\'alto
+ Sono consapevole che questo concederà privilegi estesi a µLauncher.
+ Accetto che µLauncher utilizzi il servizio di accessibilità per fornire funzionalità non correlate all\'accessibilità.
+ Accetto che µLauncher non raccolga alcun dato.
+ Nascondi le app in pausa
+ Attiva/Disattiva Blocco Spazio Privato
+ Questa funzionalità richiede Android 15 o successivi.
+ Rosso
+ Trasparente
+ Blu
+ Verde
+ Ok
+ Colore
+ Scegli colore
+ Attiva Servizi di Accessibilità
+ Sono consapevole che esistono altre opzioni (utilizzando i privilegi di amministratore del dispositivo o il pulsante di accensione).
+ Attivazione dei Servizi di Accessibilità
+ Cerca su internet
+ Premi invio durante la ricerca nell\'elenco delle app per avviare una ricerca su internet.
+ Cerca (senza avvio automatico)
+ Licenze Open Source
+ Licenze Open Source
+ Segnala un bug
+ Grazie per aver contribuito a migliorare µLauncher!\nSi prega di aggiungere le seguenti informazioni alla segnalazione del bug:
+ Copia negli appunti
+ Non segnalare pubblicamente le vulnerabilità di sicurezza su GitHub, ma utilizza invece:
+ Annulla
+ Premi spazio per disabilitare temporaneamente questa funzionalità.
+ Segnala una vulnerabilità di sicurezza
+ Crea una segnalazione
+ Spazio privato bloccato
+ Spazio privato sbloccato
+ Spazio privato non disponibile
+ µLauncher deve essere la schermata iniziale predefinita per accedere allo spazio privato.
+ Impossibile aprire l\'URL: nessun browser trovato.
+ Non è stata trovata un\'applicazione per gestire la ricerca.
+ privilegi più ampi a µLauncher. µLauncher utilizzerà questi privilegi solo per bloccare lo schermo. µLauncher non raccoglierà mai alcun dato. In particolare, µLauncher non usa il servizio di accessibilità per raccogliere nessun dato.]]>
\ No newline at end of file
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
index 6a404eb..0dd41ed 100644
--- a/app/src/main/res/values-pt-rBR/strings.xml
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -30,14 +30,14 @@
2 dedos para esquerdaPara direita2 dedos para direita
- Para direita (No topo)
+ Para direita (no topo)Para direita (em baixo)
- Para esquerda (Em baixo)
- Para esquerda (No topo)
- Para cima (Borda esquerda)
- Para cima (Borda direita)
- Para baixo (Borda esquerda)
- Para baixo (Borda direita)
+ Para esquerda (em baixo)
+ Para esquerda (no topo)
+ Para cima (borda esquerda)
+ Para cima (borda direita)
+ Para baixo (borda esquerda)
+ Para baixo (borda direita)Aumento de volumeDiminuição de volumeToque duplo
@@ -62,7 +62,7 @@
Mostrar DataUse formato de data localizadoInverter data e hora
- Escolha um papel de parede
+ Escolha papel de paredeAlterar papel de paredeExibiçãoManter a tela ligada
@@ -121,11 +121,11 @@
O Launcher foi criado para ser minimalista, eficiente e livre de distrações. Ele é livre de pagamentos, anúncios e serviços de rastreamento.O app é de código aberto (licença MIT) e está disponível no GitHub! Não deixe de conferir o repositório!Uso
- Sua tela inicial contém a data e hora local. Sem distração.
- Você pode iniciar seus aplicativos com um toque único ou pressionando um botão. Escolha algumas ações no próximo slide.
+ Sua tela inicial contém a data e hora local. Sem distrações.
+ Você pode iniciar seus aplicativos com um gesto único ou apertando um botão. Escolha algumas ações no próximo slide.ConfigurarSelecionamos alguns aplicativos padrão para você. Se quiser, você pode alterá-los agora:
- Você também pode alterar suas escolhas mais tarde.
+ Você pode alterar suas escolhas mais tarde.Vamos lá!Tá todo pronto para começar! Espero que isso seja de grande valor para você! - Finn (que criou o Launcher) \te Josia (que fez algumas melhorias e tb mantém o fork do μLauncher)Começar
@@ -162,9 +162,9 @@
Usar o Serviço de acessibilidadeUsar o Administrador do dispositivoEscolha um método de bloqueio
- Escolha um método de bloqueio da tela
+ Escolha método de bloqueio da telaConfigurações rápidas
- Essa funcionalidade requer o Android 6.0 ou mais recente.
+ Essa funcionalidade requer o Android 6 ou mais recente.Nenhuma câmera com lanterna detectada.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.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.
@@ -260,7 +260,7 @@
Licenças de código abertoOcultar apps pausadosAtivar o Espaço privado
- Essa funcionalidade requer o Android 15.0 ou mais recente.
+ Essa funcionalidade requer o Android 15 ou mais recente.Espaço privado trancadoEspaço privado liberadoEspaço privado indisponível
@@ -271,4 +271,14 @@
Criar relatórioRelatar um bugObrigado por ajudar a melhorar o µLauncher!\nConsidere adicionar as seguintes informações ao relatório de bug:
+ Toque no espaço para temporariamente desativar esta funcionalidade.
+ Não foi possível abrir a URL: nenhum navegador encontrado.
+ Nenhum app encontrado para efetuar a pesquisa.
+ Voltar
+ Botão Voltar / gesto de Voltar
+ Ocultar espaço privado na lista de apps
+ Espaço privado
+ Espaço privado
+ Trancar espaço privado
+ Liberar espaço privado
\ 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 eb7cd8b..95dc9d4 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -29,18 +29,26 @@
Back button / back gestureUpSwipe up
+ Tap + Up
+ Tap and swipe upDouble UpSwipe up with two fingersDownSwipe down
+ Tap + Down
+ Tap and swipe downDouble DownSwipe down with two fingersLeftSwipe left
+ Tap + Left
+ Tap and swipe leftDouble LeftSwipe left with two fingersRightSwipe right
+ Tap + Right
+ Tap and swipe rightDouble RightSwipe right with two fingersRight (Top)
@@ -62,19 +70,19 @@
]]>Top left -> mid right -> bottom left
- (reverse)]]>
+ (Reverse)]]>Bottom left -> mid right -> top leftTop right -> mid left -> bottom right
-
+ Bottom right -> mid left -> top rightVTop left -> bottom mid -> top right
- V (reverse)
+ V (Reverse)Top right -> bottom mid -> top leftΛBottom left -> top mid -> bottom right
- Λ (reverse)
+ Λ (Reverse)Bottom right -> top mid -> bottom leftVolume Up
@@ -251,6 +259,11 @@
Lock ScreenToggle Torch
+
+ Add Shortcut
+ Bind to gesture
+ Show in app list
+