diff --git a/.scripts/release.sh b/.scripts/release.sh index f207c87..0c71f4a 100755 --- a/.scripts/release.sh +++ b/.scripts/release.sh @@ -1,5 +1,5 @@ #!/bin/bash -export JAVA_HOME="/usr/lib/jvm/java-21-openjdk/" +export JAVA_HOME="/usr/lib/jvm/java-23-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/app/build.gradle b/app/build.gradle index 1a0a6fb..c75bb3d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -23,8 +23,8 @@ android { minSdkVersion 21 targetSdkVersion 35 compileSdk 35 - versionCode 44 - versionName "0.1.4" + versionCode 40 + versionName "0.1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } @@ -85,17 +85,17 @@ android { // Disables dependency metadata when building Android App Bundles. includeInBundle = false } - lint { + + lintOptions { abortOnError false } - } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation 'androidx.activity:activity-ktx:1.8.0' + 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 a5f8831..93f6ce8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -85,7 +85,7 @@ @@ -97,4 +97,4 @@ - + \ No newline at end of file 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 e6cce23..e674e4e 100644 --- a/app/src/main/java/de/jrpie/android/launcher/Application.kt +++ b/app/src/main/java/de/jrpie/android/launcher/Application.kt @@ -7,8 +7,11 @@ 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 @@ -20,9 +23,6 @@ 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>() @@ -153,8 +153,6 @@ class Application : android.app.Application() { private fun loadApps() { privateSpaceLocked.postValue(isPrivateSpaceLocked(this)) - CoroutineScope(Dispatchers.Default).launch { - apps.postValue(getApps(packageManager, applicationContext)) - } + AsyncTask.execute { 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 afc2c31..57f13a5 100644 --- a/app/src/main/java/de/jrpie/android/launcher/Functions.kt +++ b/app/src/main/java/de/jrpie/android/launcher/Functions.kt @@ -12,6 +12,7 @@ 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 @@ -33,13 +34,17 @@ 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 -const val LOG_TAG = "Launcher" +/* 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 { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { val roleManager = context.getSystemService(RoleManager::class.java) @@ -61,7 +66,7 @@ fun setDefaultHomeScreen(context: Context, checkDefault: Boolean = false) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && context is Activity - && checkDefault // using role manager only works when µLauncher is not already the default. + && !isDefault // using role manager only works when µLauncher is not already the default. ) { val roleManager = context.getSystemService(RoleManager::class.java) context.startActivityForResult( @@ -120,7 +125,7 @@ fun removeUnusedShortcuts(context: Context) { } fun openInBrowser(url: String, context: Context) { - val intent = Intent(Intent.ACTION_VIEW, url.toUri()) + val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) intent.putExtras(Bundle().apply { putBoolean("new_window", true) }) try { context.startActivity(intent) @@ -189,7 +194,7 @@ fun getApps( loadList.add(detailedAppInfo) } } - loadList.sortBy { it.getCustomLabel(context) } + loadList.sortBy { it.getCustomLabel(context).toString() } var end = System.currentTimeMillis() Log.i(LOG_TAG, "${loadList.size} apps loaded (${end - start}ms)") @@ -207,6 +212,14 @@ 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 9a2dc62..ddef92a 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,6 +2,7 @@ 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 @@ -11,7 +12,6 @@ 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,6 +29,10 @@ 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? { @@ -40,23 +44,23 @@ sealed interface Action { } fun resetToDefaultActions(context: Context) { - LauncherPreferences.getSharedPreferences().edit { - val boundActions = HashSet() - Gesture.entries.forEach { gesture -> - context.resources - .getStringArray(gesture.defaultsResource) - .filterNot { boundActions.contains(it) } - .map { Pair(it, Json.decodeFromString(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) + val editor = LauncherPreferences.getSharedPreferences().edit() + val boundActions = HashSet() + Gesture.entries.forEach { gesture -> + context.resources + .getStringArray(gesture.defaultsResource) + .filterNot { boundActions.contains(it) } + .map { Pair(it, Json.decodeFromString(it)) } + .firstOrNull { it.second.isAvailable(context) } + ?.apply { + // allow to bind CHOOSE to multiple gestures + if (second != LauncherAction.CHOOSE) { + boundActions.add(first) } - } + second.bindToGesture(editor, gesture.id) + } } + editor.apply() } fun setActionForGesture(gesture: Gesture, action: Action?) { @@ -64,15 +68,15 @@ sealed interface Action { clearActionForGesture(gesture) return } - LauncherPreferences.getSharedPreferences().edit { - action.bindToGesture(this, gesture.id) - } + val editor = LauncherPreferences.getSharedPreferences().edit() + action.bindToGesture(editor, gesture.id) + editor.apply() } fun clearActionForGesture(gesture: Gesture) { - LauncherPreferences.getSharedPreferences().edit { - remove(gesture.id) - } + LauncherPreferences.getSharedPreferences().edit() + .remove(gesture.id) + .apply() } fun launch( @@ -83,9 +87,6 @@ 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 { @@ -96,5 +97,10 @@ 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 a2434e1..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 @@ -250,7 +250,7 @@ enum class Gesture( "action.back", R.string.settings_gesture_back, R.string.settings_gesture_description_back, - R.array.default_back + R.array.default_up ); enum class Edge { 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 6ba467e..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 @@ -11,9 +11,7 @@ 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 @@ -134,14 +132,6 @@ 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, @@ -152,13 +142,7 @@ enum class LauncherAction( "toggle_torch", R.string.list_other_torch, 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 + ::toggleTorch ), NOP("nop", R.string.list_other_nop, R.drawable.baseline_not_interested_24, {}); @@ -264,15 +248,6 @@ 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/java/de/jrpie/android/launcher/actions/lock/LauncherAccessibilityService.kt b/app/src/main/java/de/jrpie/android/launcher/actions/lock/LauncherAccessibilityService.kt index 7cb32d9..a8ef6f2 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,44 +22,26 @@ 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" - private fun invoke(context: Context, action: String, failureMessageRes: Int) { + fun lockScreen(context: Context) { try { context.startService( Intent( context, LauncherAccessibilityService::class.java ).apply { - this.action = action + action = ACTION_LOCK_SCREEN }) - } catch (_: Exception) { + } catch (e: Exception) { Toast.makeText( context, - context.getString(failureMessageRes), + context.getString(R.string.alert_lock_screen_failed), 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, @@ -76,7 +58,7 @@ class LauncherAccessibilityService : AccessibilityService() { setView(R.layout.dialog_consent_accessibility) setTitle(R.string.dialog_consent_accessibility_title) setPositiveButton(R.string.dialog_consent_accessibility_ok) { _, _ -> - invoke(context, ACTION_REQUEST_ENABLE, R.string.alert_enable_accessibility_failed) + lockScreen(context) } setNegativeButton(R.string.dialog_cancel) { _, _ -> } }.create().also { it.show() }.apply { @@ -112,9 +94,7 @@ 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 93b4cbf..8ae2415 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,10 +6,10 @@ 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 +@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 9534431..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 @@ -15,7 +15,19 @@ import kotlinx.serialization.Serializable */ @Serializable @SerialName("app") -data class AppInfo(val packageName: String, val activityName: String?, val user: Int = INVALID_USER): AbstractAppInfo { +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() + } fun getLauncherActivityInfo( context: Context @@ -26,4 +38,10 @@ data class AppInfo(val packageName: String, val activityName: String?, val user: 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 54230ae..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 @@ -16,7 +16,7 @@ import kotlinx.serialization.Serializable @RequiresApi(Build.VERSION_CODES.N_MR1) @Serializable @SerialName("shortcut") -data class PinnedShortcutInfo( +class PinnedShortcutInfo( val id: String, val packageName: String, val activityName: String, @@ -43,4 +43,25 @@ data 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 24665d7..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 @@ -123,7 +123,6 @@ 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 0f95efd..a21d458 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,7 +17,6 @@ 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) { @@ -53,7 +52,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(android.R.string.ok) { _, _ -> + setPositiveButton(R.string.dialog_select_color_ok) { _, _ -> persistInt(currentColor) summary = currentColor.getHex() } @@ -84,10 +83,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() ?: return - newText.isBlank() && return + val newText = editable?.toString() + newText.isNullOrBlank() && return try { - val newColor = newText.toColorInt() + val newColor = Color.parseColor(newText.toString()) 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 5f7b9d6..e20945a 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,7 +1,6 @@ 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 @@ -28,10 +27,8 @@ enum class ListLayout( GRID( { c -> val displayMetrics = c.resources.displayMetrics - val widthColumnPx = - TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 90f, displayMetrics) - val numColumns = (displayMetrics.widthPixels / widthColumnPx).toInt() - GridLayoutManager(c, numColumns) + val widthSp = displayMetrics.widthPixels / displayMetrics.scaledDensity + GridLayoutManager(c, (widthSp / 90).toInt()) }, 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 a1cb022..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 @@ -13,11 +13,9 @@ 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?): Set? { @@ -102,7 +100,7 @@ private fun migrateAppInfoStringMap(key: String) { } }?.toMap(HashMap()) )?.let { - preferences.edit { putStringSet(key, it) } + preferences.edit().putStringSet(key, it).apply() } } @@ -111,16 +109,16 @@ private fun migrateAppInfoSet(key: String) { .map(AppInfo.Companion::legacyDeserialize) .map(AppInfo::serialize) .toSet() - .let { LauncherPreferences.getSharedPreferences().edit { putStringSet(key, it) } } + .let { LauncherPreferences.getSharedPreferences().edit().putStringSet(key, it).apply() } } private fun migrateAction(key: String) { Action.legacyFromPreference(key)?.let { action -> - LauncherPreferences.getSharedPreferences().edit { - putString(key, Json.encodeToString(action)) - .remove("$key.app") - .remove("$key.user") - } + LauncherPreferences.getSharedPreferences().edit() + .putString(key, Json.encodeToString(action)) + .remove("$key.app") + .remove("$key.user") + .apply() } } 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 2d1152d..a33670b 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,317 +64,318 @@ fun migratePreferencesFromVersionUnknown(context: Context) { return } - LauncherPreferences.getSharedPreferences().edit { + val newPrefs = LauncherPreferences.getSharedPreferences().edit() - migrateBooleanPreference( - oldPrefs, - this, - "startedBefore", - "internal.started_before", - false - ) + migrateBooleanPreference( + oldPrefs, + newPrefs, + "startedBefore", + "internal.started_before", + false + ) - 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 - ) - } + 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() 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 d3088f4..816d94f 100644 --- a/app/src/main/java/de/jrpie/android/launcher/preferences/theme/ColorTheme.kt +++ b/app/src/main/java/de/jrpie/android/launcher/preferences/theme/ColorTheme.kt @@ -5,6 +5,7 @@ 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/Helper.kt b/app/src/main/java/de/jrpie/android/launcher/ui/Helper.kt index 1ca4d2b..b8fc82e 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,14 +27,10 @@ fun View.blink( } // Taken from: https://stackoverflow.com/a/30340794/12787264 -fun ImageView.transformGrayscale(grayscale: Boolean) { - this.colorFilter = if (grayscale) { - ColorMatrixColorFilter(ColorMatrix().apply { - setSaturation(0f) - }) - } else { - null - } +fun ImageView.transformGrayscale() { + this.colorFilter = ColorMatrixColorFilter(ColorMatrix().apply { + setSaturation(0f) + }) } 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 2ab5d9f..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 @@ -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 @@ -37,7 +37,7 @@ import java.util.Locale class HomeActivity : UIObject, AppCompatActivity() { private lateinit var binding: HomeBinding - private var touchGestureDetector: TouchGestureDetector? = null + private lateinit var touchGestureDetector: TouchGestureDetector private var sharedPreferencesListener = SharedPreferences.OnSharedPreferenceChangeListener { _, prefKey -> @@ -56,12 +56,24 @@ class HomeActivity : UIObject, AppCompatActivity() { super.onCreate(savedInstanceState) super.onCreate() + val displayMetrics = DisplayMetrics() + windowManager.defaultDisplay.getMetrics(displayMetrics) + + val width = displayMetrics.widthPixels + val height = displayMetrics.heightPixels + + touchGestureDetector = TouchGestureDetector( + this, + width, + height, + LauncherPreferences.enabled_gestures().edgeSwipeEdgeWidth() / 100f + ) // Initialise layout binding = HomeBinding.inflate(layoutInflater) - setContentView(binding.root) + // Handle back key / gesture on Android 13+, cf. onKeyDown() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { onBackInvokedDispatcher.registerOnBackInvokedCallback( @@ -75,11 +87,6 @@ class HomeActivity : UIObject, AppCompatActivity() { } } - override fun onConfigurationChanged(newConfig: Configuration) { - super.onConfigurationChanged(newConfig) - touchGestureDetector?.updateScreenSize(windowManager) - } - override fun onStart() { super.onStart() @@ -171,28 +178,8 @@ class HomeActivity : UIObject, AppCompatActivity() { override fun onResume() { super.onResume() - /* 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, + touchGestureDetector.edgeWidth = 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() @@ -233,7 +220,7 @@ class HomeActivity : UIObject, AppCompatActivity() { } override fun onTouchEvent(event: MotionEvent): Boolean { - touchGestureDetector?.onTouchEvent(event) + touchGestureDetector.onTouchEvent(event) return true } 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 71908ba..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 @@ -24,7 +24,6 @@ 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 @@ -73,12 +72,9 @@ class PinShortcutActivity : AppCompatActivity(), UIObject { isBound = true request.accept() } - LauncherPreferences.getSharedPreferences().edit { - ShortcutAction(PinnedShortcutInfo(request.shortcutInfo!!)).bindToGesture( - this, - gesture.id - ) - } + 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 { @@ -121,11 +117,11 @@ class PinShortcutActivity : AppCompatActivity(), UIObject { } inner class GestureRecyclerAdapter(val context: Context, val onClick: (Gesture) -> Unit): RecyclerView.Adapter() { - private val gestures = Gesture.entries.filter { it.isEnabled() }.toList() + val gestures = Gesture.entries.filter { it.isEnabled() }.toList() inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - 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) + 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 { 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 8e8ed4e..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,15 +1,10 @@ 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.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 import kotlin.math.abs @@ -19,8 +14,8 @@ import kotlin.math.tan class TouchGestureDetector( private val context: Context, - var width: Int, - var height: Int, + val width: Int, + val height: Int, var edgeWidth: Float ) { private val ANGULAR_THRESHOLD = tan(Math.PI / 6) @@ -36,29 +31,20 @@ 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) } @@ -75,35 +61,16 @@ 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 } @@ -120,40 +87,24 @@ class TouchGestureDetector( } private var paths = HashMap() - - /* 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 gestureIsLongClick = 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.. { - 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) { @@ -320,20 +267,4 @@ class TouchGestureDetector( gesture?.invoke(context) } } - - 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 - systemGestureInsetBottom = insets.bottom - systemGestureInsetLeft = insets.left - systemGestureInsetRight = insets.right - } } \ No newline at end of file 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 51324f4..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 @@ -15,10 +15,8 @@ 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 fe27f0f..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,17 +1,24 @@ 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 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.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 @@ -108,13 +115,10 @@ 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 @@ -181,6 +185,20 @@ 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) { @@ -223,11 +241,11 @@ class ListActivity : AppCompatActivity(), UIObject { updateTitle() - val sectionsPagerAdapter = ListSectionsPagerAdapter(this) - binding.listViewpager.let { - it.adapter = sectionsPagerAdapter - binding.listTabs.setupWithViewPager(it) - } + 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) } } @@ -239,15 +257,9 @@ 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) : - FragmentPagerAdapter(activity.supportFragmentManager) { +class ListSectionsPagerAdapter(private val activity: ListActivity, fm: FragmentManager) : + FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { override fun getItem(position: Int): Fragment { return when (position) { 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 65278ce..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 @@ -2,6 +2,7 @@ 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 @@ -14,8 +15,7 @@ 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.actions.Action -import de.jrpie.android.launcher.actions.Gesture +import de.jrpie.android.launcher.REQUEST_CHOOSE_APP import de.jrpie.android.launcher.apps.AbstractDetailedAppInfo import de.jrpie.android.launcher.apps.AppFilter import de.jrpie.android.launcher.apps.AppInfo @@ -47,7 +47,6 @@ class AppsRecyclerAdapter( private val apps = (activity.applicationContext as Application).apps private val appsListDisplayed: MutableList = mutableListOf() - private val grayscale = LauncherPreferences.theme().monochromeIcons() // temporarily disable auto launch var disableAutoLaunch: Boolean = false @@ -80,19 +79,20 @@ 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() } - viewHolder.textView.text = appLabel + 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) { @@ -195,10 +195,11 @@ 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 22dff02..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 @@ -6,6 +6,7 @@ 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 @@ -13,9 +14,11 @@ 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 @@ -41,13 +44,17 @@ fun AbstractAppInfo.uninstall(activity: Activity) { Log.i(LOG_TAG, "uninstalling $this") - val intent = Intent(Intent.ACTION_DELETE) + val intent = Intent(Intent.ACTION_UNINSTALL_PACKAGE) 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) @@ -95,8 +102,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(android.R.string.cancel) { d, _ -> d.cancel() } - setPositiveButton(android.R.string.ok) { d, _ -> + setNegativeButton(R.string.dialog_cancel) { d, _ -> d.cancel() } + setPositiveButton(R.string.dialog_rename_ok) { d, _ -> setCustomLabel( (d as? AlertDialog) ?.findViewById(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 f176469..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 @@ -1,6 +1,7 @@ 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 @@ -8,8 +9,7 @@ import android.widget.ImageView import android.widget.TextView 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.REQUEST_CHOOSE_APP import de.jrpie.android.launcher.actions.LauncherAction import de.jrpie.android.launcher.ui.list.ListActivity @@ -36,10 +36,7 @@ class OtherRecyclerAdapter(val activity: Activity) : val pos = bindingAdapterPosition val content = othersList[pos] - activity.finish() - val gestureId = (activity as? ListActivity)?.forGesture ?: return - val gesture = Gesture.byId(gestureId) ?: return - Action.setActionForGesture(gesture, content) + (activity as? ListActivity)?.forGesture?.let { returnChoiceIntent(it, content) } } init { @@ -64,4 +61,12 @@ 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 cd59726..fde61a7 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,5 +1,6 @@ package de.jrpie.android.launcher.ui.settings +import android.content.Context import android.content.Intent import android.content.SharedPreferences import android.content.res.Resources @@ -7,14 +8,17 @@ import android.os.Bundle import android.provider.Settings import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment -import androidx.fragment.app.FragmentActivity -import androidx.viewpager2.adapter.FragmentStateAdapter -import com.google.android.material.tabs.TabLayoutMediator +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 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 @@ -45,15 +49,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(EXTRA_TAB, 1) } + .also { it.putExtra("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 @@ -67,14 +71,15 @@ class SettingsActivity : AppCompatActivity(), UIObject { setContentView(binding.root) // set up tabs and swiping in settings - val sectionsPagerAdapter = SettingsSectionsPagerAdapter(this) - binding.settingsViewpager.apply { - adapter = sectionsPagerAdapter - setCurrentItem(intent.getIntExtra(EXTRA_TAB, 0), false) + 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() } - TabLayoutMediator(binding.settingsTabs, binding.settingsViewpager) { tab, position -> - tab.text = sectionsPagerAdapter.getPageTitle(position) - }.attach() } override fun onStart() { @@ -103,21 +108,24 @@ class SettingsActivity : AppCompatActivity(), UIObject { } } - companion object { - private const val EXTRA_TAB = "tab" + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + when (requestCode) { + REQUEST_CHOOSE_APP -> saveListActivityChoice(data) + else -> super.onActivityResult(requestCode, resultCode, data) + } } } private val TAB_TITLES = arrayOf( - R.string.settings_tab_actions, + R.string.settings_tab_app, R.string.settings_tab_launcher, R.string.settings_tab_meta ) -class SettingsSectionsPagerAdapter(private val activity: FragmentActivity) : - FragmentStateAdapter(activity) { +class SettingsSectionsPagerAdapter(private val context: Context, fm: FragmentManager) : + FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { - override fun createFragment(position: Int): Fragment { + override fun getItem(position: Int): Fragment { return when (position) { 0 -> SettingsFragmentActions() 1 -> SettingsFragmentLauncher() @@ -126,11 +134,11 @@ class SettingsSectionsPagerAdapter(private val activity: FragmentActivity) : } } - fun getPageTitle(position: Int): CharSequence { - return activity.resources.getString(TAB_TITLES[position]) + override fun getPageTitle(position: Int): CharSequence { + return context.resources.getString(TAB_TITLES[position]) } - override fun getItemCount(): Int { + override fun getCount(): Int { return 3 } } 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 ae47ce2..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 @@ -16,6 +16,7 @@ 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 @@ -142,7 +143,9 @@ class ActionsRecyclerAdapter(val activity: Activity) : val description = gesture.getDescription(activity) viewHolder.descriptionTextView.text = description - viewHolder.img.transformGrayscale(LauncherPreferences.theme().monochromeIcons()) + + if (LauncherPreferences.theme().monochromeIcons()) + viewHolder.img.transformGrayscale() updateViewHolder(gesture, viewHolder) viewHolder.img.setOnClickListener { chooseApp(gesture) } @@ -178,6 +181,9 @@ 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.startActivity(intent) + activity.startActivityForResult( + intent, + REQUEST_CHOOSE_APP + ) } } 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 dea0bcf..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 @@ -2,6 +2,7 @@ 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 @@ -19,6 +20,7 @@ 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 847639c..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 @@ -1,26 +1,26 @@ 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.view.View import android.window.OnBackInvokedDispatcher import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment -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.databinding.TutorialBinding +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 de.jrpie.android.launcher.REQUEST_CHOOSE_APP 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 -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 +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 /** * The [TutorialActivity] is displayed automatically on new installations. @@ -31,17 +31,10 @@ import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragment5Finish */ class TutorialActivity : AppCompatActivity(), UIObject { - private lateinit var binding: TutorialBinding - - override fun onCreate(savedInstanceState: Bundle?) { super.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( @@ -55,51 +48,15 @@ class TutorialActivity : AppCompatActivity(), UIObject { } } + // Initialise layout + setContentView(R.layout.tutorial) // set up tabs and swiping in settings - 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) - } - } + 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) } override fun getTheme(): Resources.Theme { @@ -111,9 +68,14 @@ class TutorialActivity : AppCompatActivity(), UIObject { super.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() @@ -127,22 +89,26 @@ class TutorialActivity : AppCompatActivity(), UIObject { * * Tabs: (Start | Concept | Usage | Setup | Finish) */ -class TutorialSectionsPagerAdapter(activity: FragmentActivity) : - FragmentStateAdapter(activity) { +class TutorialSectionsPagerAdapter(fm: FragmentManager) : + FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { - override fun getItemCount(): Int { - return 6 - } - - override fun createFragment(position: Int): Fragment { + override fun getItem(position: Int): Fragment { return when (position) { - 0 -> TutorialFragment0Start() - 1 -> TutorialFragment1Concept() - 2 -> TutorialFragment2Usage() - 3 -> TutorialFragment3AppList() - 4 -> TutorialFragment4Setup() - 5 -> TutorialFragment5Finish() + 0 -> TutorialFragmentStart() + 1 -> TutorialFragmentConcept() + 2 -> TutorialFragmentUsage() + 3 -> TutorialFragmentSetup() + 4 -> TutorialFragmentFinish() 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/TutorialFragment3AppList.kt b/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment3AppList.kt deleted file mode 100644 index 78698aa..0000000 --- a/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment3AppList.kt +++ /dev/null @@ -1,30 +0,0 @@ -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/TutorialFragment1Concept.kt b/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragmentConcept.kt similarity index 68% rename from app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment1Concept.kt rename to app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragmentConcept.kt index 876266e..f0fd233 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment1Concept.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragmentConcept.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.Tutorial1ConceptBinding +import de.jrpie.android.launcher.databinding.TutorialConceptBinding import de.jrpie.android.launcher.ui.UIObject /** - * The [TutorialFragment1Concept] is a used as a tab in the TutorialActivity. + * The [TutorialFragmentConcept] is a used as a tab in the TutorialActivity. * * It is used to display info about Launchers concept (open source, efficiency ...) */ -class TutorialFragment1Concept : Fragment(), UIObject { - private lateinit var binding: Tutorial1ConceptBinding +class TutorialFragmentConcept : Fragment(), UIObject { + private lateinit var binding: TutorialConceptBinding override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { - binding = Tutorial1ConceptBinding.inflate(inflater, container, false) + binding = TutorialConceptBinding.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/TutorialFragment5Finish.kt b/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragmentFinish.kt similarity index 80% rename from app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment5Finish.kt rename to app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragmentFinish.kt index 2fd093e..2d01d0a 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment5Finish.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragmentFinish.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.Tutorial5FinishBinding +import de.jrpie.android.launcher.databinding.TutorialFinishBinding import de.jrpie.android.launcher.preferences.LauncherPreferences import de.jrpie.android.launcher.setDefaultHomeScreen import de.jrpie.android.launcher.ui.UIObject /** - * The [TutorialFragment5Finish] is a used as a tab in the TutorialActivity. + * The [TutorialFragmentFinish] is a used as a tab in the TutorialActivity. * * It is used to display further resources and let the user start Launcher */ -class TutorialFragment5Finish : Fragment(), UIObject { +class TutorialFragmentFinish : Fragment(), UIObject { - private lateinit var binding: Tutorial5FinishBinding + private lateinit var binding: TutorialFinishBinding override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { - binding = Tutorial5FinishBinding.inflate(inflater, container, false) + binding = TutorialFinishBinding.inflate(inflater, container, false) return binding.root } diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment4Setup.kt b/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragmentSetup.kt similarity index 74% rename from app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment4Setup.kt rename to app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragmentSetup.kt index 56eb6ca..09ef4c9 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment4Setup.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragmentSetup.kt @@ -9,17 +9,17 @@ import de.jrpie.android.launcher.R import de.jrpie.android.launcher.ui.UIObject /** - * The [TutorialFragment4Setup] is a used as a tab in the TutorialActivity. + * The [TutorialFragmentSetup] is a used as a tab in the TutorialActivity. * * It is used to display info in the tutorial */ -class TutorialFragment4Setup : Fragment(), UIObject { +class TutorialFragmentSetup : Fragment(), UIObject { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - return inflater.inflate(R.layout.tutorial_4_setup, container, false) + return inflater.inflate(R.layout.tutorial_setup, container, false) } override fun onStart() { diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment0Start.kt b/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragmentStart.kt similarity index 59% rename from app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment0Start.kt rename to app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragmentStart.kt index 5ce5920..445ded1 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment0Start.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragmentStart.kt @@ -5,22 +5,24 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment -import de.jrpie.android.launcher.databinding.Tutorial0StartBinding +import de.jrpie.android.launcher.databinding.TutorialStartBinding import de.jrpie.android.launcher.ui.UIObject +import de.jrpie.android.launcher.ui.blink /** - * The [TutorialFragment0Start] is a used as a tab in the TutorialActivity. + * The [TutorialFragmentStart] is a used as a tab in the TutorialActivity. * * It displays info about the app and gets the user into the tutorial */ -class TutorialFragment0Start : Fragment(), UIObject { +class TutorialFragmentStart : Fragment(), UIObject { - private lateinit var binding: Tutorial0StartBinding + private lateinit var binding: TutorialStartBinding override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { - binding = Tutorial0StartBinding.inflate(inflater, container, false) + binding = TutorialStartBinding.inflate(inflater, container, false) + binding.tutorialStartIconRight.blink() return binding.root } diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment2Usage.kt b/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragmentUsage.kt similarity index 75% rename from app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment2Usage.kt rename to app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragmentUsage.kt index 4b24dcd..90db232 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment2Usage.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragmentUsage.kt @@ -9,17 +9,17 @@ import de.jrpie.android.launcher.R import de.jrpie.android.launcher.ui.UIObject /** - * The [TutorialFragment2Usage] is a used as a tab in the TutorialActivity. + * The [TutorialFragmentUsage] 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 TutorialFragment2Usage : Fragment(), UIObject { +class TutorialFragmentUsage : Fragment(), UIObject { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - return inflater.inflate(R.layout.tutorial_2_usage, container, false) + return inflater.inflate(R.layout.tutorial_usage, container, false) } override fun onStart() { 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 5e38b9f..549f10f 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,7 +12,6 @@ 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-mdpi/tutorial_app_list.png b/app/src/main/res/drawable-mdpi/tutorial_app_list.png deleted file mode 100644 index 66ebaaf..0000000 Binary files a/app/src/main/res/drawable-mdpi/tutorial_app_list.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/tutorial_home_screen.png b/app/src/main/res/drawable-mdpi/tutorial_home_screen.png deleted file mode 100644 index ccbce5d..0000000 Binary files a/app/src/main/res/drawable-mdpi/tutorial_home_screen.png and /dev/null differ diff --git a/app/src/main/res/drawable/baseline_apps_24.xml b/app/src/main/res/drawable/baseline_apps_24.xml deleted file mode 100644 index c5a49a0..0000000 --- a/app/src/main/res/drawable/baseline_apps_24.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable/baseline_home_24.xml b/app/src/main/res/drawable/baseline_home_24.xml deleted file mode 100644 index 935d1b6..0000000 --- a/app/src/main/res/drawable/baseline_home_24.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable/baseline_more_horiz_24.xml b/app/src/main/res/drawable/baseline_more_horiz_24.xml new file mode 100644 index 0000000..061fae2 --- /dev/null +++ b/app/src/main/res/drawable/baseline_more_horiz_24.xml @@ -0,0 +1,11 @@ + + + + + diff --git a/app/src/main/res/drawable/baseline_navigate_before_24.xml b/app/src/main/res/drawable/baseline_navigate_before_24.xml deleted file mode 100644 index 4097b26..0000000 --- a/app/src/main/res/drawable/baseline_navigate_before_24.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable/baseline_navigate_next_24.xml b/app/src/main/res/drawable/baseline_navigate_next_24.xml deleted file mode 100644 index 22cef28..0000000 --- a/app/src/main/res/drawable/baseline_navigate_next_24.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable/home_round_screen.png b/app/src/main/res/drawable/home_round_screen.png new file mode 100644 index 0000000..f0237e8 Binary files /dev/null and b/app/src/main/res/drawable/home_round_screen.png differ diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..4f1c4ab --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,10 @@ + + + + diff --git a/app/src/main/res/layout/activity_pin_shortcut.xml b/app/src/main/res/layout/activity_pin_shortcut.xml index 2519374..5e10118 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="@android:string/ok" + android:text="@string/pin_shortcut_button_ok" app:layout_constraintBottom_toBottomOf="parent" /> \ No newline at end of file diff --git a/app/src/main/res/layout/list.xml b/app/src/main/res/layout/list.xml index 8a3b5d9..43c1f4c 100644 --- a/app/src/main/res/layout/list.xml +++ b/app/src/main/res/layout/list.xml @@ -95,11 +95,6 @@ - \ 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 ee57c45..1a9058c 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,7 +15,6 @@ 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="some app" /> \ No newline at end of file diff --git a/app/src/main/res/layout/settings.xml b/app/src/main/res/layout/settings.xml index 987e293..f07402c 100644 --- a/app/src/main/res/layout/settings.xml +++ b/app/src/main/res/layout/settings.xml @@ -73,7 +73,7 @@ - + app:layout_constraintTop_toTopOf="parent" + /> - - - - - - + app:layout_constraintStart_toStartOf="parent" /> \ No newline at end of file diff --git a/app/src/main/res/layout/tutorial_3_app_list.xml b/app/src/main/res/layout/tutorial_3_app_list.xml deleted file mode 100644 index ae7eda1..0000000 --- a/app/src/main/res/layout/tutorial_3_app_list.xml +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/tutorial_1_concept.xml b/app/src/main/res/layout/tutorial_concept.xml similarity index 75% rename from app/src/main/res/layout/tutorial_1_concept.xml rename to app/src/main/res/layout/tutorial_concept.xml index 9b85552..9b8495b 100644 --- a/app/src/main/res/layout/tutorial_1_concept.xml +++ b/app/src/main/res/layout/tutorial_concept.xml @@ -8,7 +8,7 @@ android:paddingRight="32sp" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".ui.tutorial.tabs.TutorialFragment1Concept"> + tools:context=".ui.tutorial.tabs.TutorialFragmentConcept"> + app:layout_constraintVertical_bias="0.19999999" /> - - diff --git a/app/src/main/res/layout/tutorial_5_finish.xml b/app/src/main/res/layout/tutorial_finish.xml similarity index 92% rename from app/src/main/res/layout/tutorial_5_finish.xml rename to app/src/main/res/layout/tutorial_finish.xml index dedf53f..eea44af 100644 --- a/app/src/main/res/layout/tutorial_5_finish.xml +++ b/app/src/main/res/layout/tutorial_finish.xml @@ -7,7 +7,7 @@ android:paddingRight="32sp" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".ui.tutorial.tabs.TutorialFragment5Finish"> + tools:context=".ui.tutorial.tabs.TutorialFragmentFinish"> + tools:context=".ui.tutorial.tabs.TutorialFragmentSetup"> - + tools:context=".ui.tutorial.tabs.TutorialFragmentStart"> + + + \ No newline at end of file diff --git a/app/src/main/res/layout/tutorial_2_usage.xml b/app/src/main/res/layout/tutorial_usage.xml similarity index 92% rename from app/src/main/res/layout/tutorial_2_usage.xml rename to app/src/main/res/layout/tutorial_usage.xml index d395eee..29bc475 100644 --- a/app/src/main/res/layout/tutorial_2_usage.xml +++ b/app/src/main/res/layout/tutorial_usage.xml @@ -7,7 +7,7 @@ android:layout_height="match_parent" android:paddingLeft="32sp" android:paddingRight="32sp" - tools:context=".ui.tutorial.tabs.TutorialFragment2Usage"> + tools:context=".ui.tutorial.tabs.TutorialFragmentUsage"> - - لا يمكن فتح التطبيق - هل تريد تعديل اعداداته؟ - افتح الاعدادات لاختيار أمر لهذه الإيماءة - الاعدادات - الأوامر - المشغل - بيانات - رجوع - أعلى - لأعلى بأصبعين - اسحب لأعلى بأصبعين - أنقر ثم اسحب لأعلى - اضغط على زر الرجوع - اسحب لأعلى - نقرة + أعلى - أسفل - اسحب لأسفل - نقرة + لأسفل - لأسفل بأصبعين - يسار - اسحب من اليسار - نقرة + يسار - أنقر ثم اسحب إلى اليسار - يسار بأصبعين - يمين - اسحب إلى اليمين - نقرة + يمين - أنقر ثم اسحب إلى اليمين - يمين بأصبعين - اسحب إلى اليمين بأصبعين - يمين (في الأعلى) - يمين (في الأسفل) - اسحب إلى اليمين من أسفل الشاشة - يسار (في الأعلى) - اسحب إلى اليسار من أعلى الشاشة - أعلى (الحافة اليسرى) - اسحب إلى الأعلى من حافة الشاشة اليسرى - أعلى (الحافة اليمنى) - أسفل (الحافة اليسرى) - اسحب إلى الأسفل من حافة الشاشة اليسرى - أسفل (الحافة اليمنى) - أعلى اليسار -> وسط اليمين -> أسفل اليسار - أسفل اليسار -> وسط اليمين -> أعلى اليسار - أعلى اليمين -> وسط اليسار -> أسفل اليمين - أعلى اليسار -> الأسفل الوسط -> أعلى اليمين - V (معكوس) - أعلى اليمين -> الأسفل الوسط -> أعلى اليسار - أسفل اليسار -> أعلى الوسط -> أسفل اليمين - Λ (معكوس) - زر رفع الصوت - اضغط على زر رفع الصوت - زر خفض الصوت - اضغط على زر خفض الصوت - نقرة مزدوجة - نقرة مطولة - أنقر مطولًا في مكان فارغ على الشاشة - التاريخ - أنقر على التاريخ - الوقت - أنقر على الوقت - اختر تطبيق - ثبت تطبيقات - المظهر - السمة - ]]> - (معكوس)]]> - - - V - Λ - داكن - فاتح - متغير - ظل النص - شفاف - مظلل - مُموه - لون ثابت - الخط - خط النظام - بدون تذييل - مذيل - أحادي المسافة - أيقونات تطبيقات أحادية اللون - اللون - أظهر الوقت - أظهر التاريخ - استخدم تنسيق التاريخ المحلي - إقلب مكان التاريخ مع الوقت - اختر خلفية - العرض - حافظ على بقاء الشاشة قيد التشغيل - إخفِ شريط الحالة - تدوير الشاشة - الوظائف - أوامر السحب بأصبعين - اسحب باستخدام أصبعين - أوامر السحب من الحواف - عرض الحواف - إظهار نتائج البحث - اضغط مسافة لتعطيل هذه الميزة مؤقتًا - ابحث في الويب - أظهر لوحة المفاتيح عند البحث - الحساسية - التطبيقات - التطبيقات المخفية - - إخفِ المساحة الخاصة من قائمة التطبيقات - تخطيط قائمة التطبيقات - الافتراضي - نص - شبكة - تعيين μauncher كشاشة المنزل - معلومات التطبيق - إعادة تعيين الإعدادات - أنت على وشك تجاهل كل تفضيلاتك، هل تريد الإكمال؟ - عرض شيفرة المصدر - الإبلاغ عن خطأ - النسخ إلى الحافظة - يرجى عدم الإبلاغ عن الثغرات الأمنية علنًا على Github ، استخدم ما يلي بدلاً من ذلك: - الإبلاغ عن ثغرة أمنية - إنشاء تقرير - اتصل بمطور النسخة - انضم إلى دردشة μauncher - تبرع - سياسة الخصوصية - كل التطبيقات - التطبيقات المفضلة - التطبيقات المخفية - المساحة الخاصة - اختر تطبيق - التطبيقات - أخرى - إلغاء التثبيت - إزالة من المفضلة - إخفِ - أظهر - إعادة التسمية - بحث - بحث (بدون تشغيل تلقائي) - اعدادات التطبيق - درج التطبيقات - المساحة الخاصة - تبديل قفل المساحة الخاصة - ارفع الصوت - إنضم إلى مجموعة discord! - ضبط مستوى الصوت - الموسيقى: السابق - الموسيقى: تشغيل / ايقاف مؤقت - التطبيقات الحديثة - لا تفعل شيئًا - قفل الشاشة - تبديل الفلاش - شغل شاشة منزل أخرى - أضف اختصارًا - اربط بإيماءة - درس تعليمي - 👋\n\nخذ بضع ثوان لمعرفة كيفية استخدام هذا المشغل! - المفهوم - إنه برنامج مجاني (ترخيص MIT)!\nتأكد من مراجعة المستودع! - النسخة - الاستخدام - تحتوي شاشتك الرئيسية على التاريخ والوقت المحليين. لا الهاء. - كل التطبيقات - بمجرد تطابق تطبيق واحد فقط، يتم تشغيله تلقائيًا.\nيمكن تعطيل ذلك عن طريق اضافة مساحة في بداية استعلام. - الإعداد - اخترنا بعض التطبيقات الافتراضية لك. يمكنك تغييرها الآن إذا كنت تريد: - يمكنك أيضًا تغيير اختيارك لاحقًا. - لنبدأ! - ابدأ - الإعدادات - المزيد من الخيارات - هذه الوظيفة تتطلب أندرويد 6 أو أحدث. - هذه الوظيفة تتطلب أندرويد 15 أو أحدث. - تراجع - تم إخفاء التطبيق. يمكنك جعله مرئيًا مرة أخرى في الإعدادات. - الاعدادات السريعة - يجب أن يكون μlauncher مسؤولًا من أجل قفل الشاشة. - هذا مطلوب لإجراء شاشة القفل. - تمكين إجراء شاشة القفل - لم يتم اكتشاف كاميرا مع فلاش. - خطأ: لا يمكن الوصول إلى الفلاش. - خطأ: فشل في إظهار التطبيقات الحديثة. (إذا قمت للتو بترقية التطبيق ، فحاول تعطيل خدمة الوصول وإعادة تمكينها في إعدادات الهاتف) - خطأ: فشل في تمكين خدمة الوصول. - لم يتم تمكين خدمة الوصول إلى μlauncher. يرجى تمكينه في الإعدادات - المساحة الخاصة مقفلة - المساحة الخاصة مفتوحة - المساحة الخاصة غير متوافرة - قفل المساحة الخاصة - فتح المساحة الخاصة - μLauncher - اختر طريقة القفل - استخدام خدمة إمكانية الوصول - استخدم مسؤول الجهاز - اختر طريقة لقفل الشاشة - اعادة تسمية %1$s - أحمر - شفافية - أزرق - أخضر - اللون - اختر لونًا - أدرك أن هذا سيمنح أذونات كثيرة لـμauncher. - أدرك وجود خيارات أخرى (باستخدام أذونات مسؤول الجهاز أو زر الطاقة). - أوافق لـμlauncher باستخدام خدمة إمكانية الوصول لتوفير الوظائف ليس لها صلة بإمكانية الوصول. - أوافق على أن μlauncher لا يجمع أي بيانات. - يتم تفعيل خدمة إمكانية الوصول - تفعيل خدمة إمكانية الوصول - إلغاء - تراخيص المصادر المفتوحة - تراخيص المصادر المفتوحة - لم يتم العثور على تطبيق للتعامل مع البحث. - لا يمكن فتح عنوان URL: لم يتم العثور على متصفح. - أذونات كثيرة إلى التطبيق: -
    -
  • قفل الشاشة
  • -
  • التطبيقات الحديثة
  • -
- لن يقومμlauncher أبدًا بجمع أي بيانات . على وجه الخصوص ، لا يستخدم μlauncher خدمة إمكانية الوصول لجمع أي بيانات.]]>
- أنقر ثم اسحب لأسفل - الافتراضي - أظهر في قائمة التطبيقات - اسحب لأسفل بأصبعين - أظهر الثواني - الإبلاغ عن خطأ - اسحب إلى اليسار بأصبعين - أنقر مرتين في مكان فارغ على الشاشة - اضغط على زر الرجوع أثناء البحث في قائمة التطبيقات لإظهار البحث على الويب - اسحب إلى اليمين من أعلى الشاشة - يسار (في الأسفل) - اسحب إلى الأعلى من حافة الشاشة اليمنى - أسفل اليمين -> أعلى الوسط -> أسفل اليسار - لا تظهر التطبيقات المرتبطة بإيماءة في قائمة التطبيقات - درج التطبيقات المفضلة - الموسيقى: التالي - تم تصميم μlauncher ليكون فعال، وخالي من الهاء.\n\nلا يحتوي على أي إعلانات ولا يجمع أي بيانات. - أنت مستعد للبدء!\n\nآمل أن يكون هذا ذا قيمة كبيرة بالنسبة لك!\n\n- المطورين - يجب أن يكون μlauncher الشاشة الرئيسية الافتراضية للوصول إلى مساحة خاصة. - اسحب إلى اليسار من أسفل الشاشة - أسفل اليمين -> وسط اليسار -> أعلى اليمين - لم يتم العثور على تطبيق المتجر - إخفِ شريط التنقل - معلومات التطبيق - أضف إلى المفضلة - توسيع لوحة الاشعارات - يمكنك البحث بسرعة من خلال جميع التطبيقات في قائمة التطبيقات.\n\nاسحب لأعلى لفتح القائمة، أو ربطها بإيماءة ما. - خطأ: فشل في قفل الشاشة. (إذا قمت للتو بترقية التطبيق ، فحاول تعطيل خدمة الوصول وإعادة تمكينها في إعدادات الهاتف) - اسحب إلى الأسفل من حافة الشاشة اليمنى - أحادي المسافة مذيل - عكس قائمة التطبيقات - خطأ: لا يمكن توسيع شريط الحالة. يستخدم هذا الإجراء وظيفة ليست جزءًا من نظام أندرويد. لسوء الحظ ، لا يبدو أنه يعمل على جهازك. - خلفية القوائم - إخفِ التطبيقات المتوقفة - أظهر العرض التعليمي للتطبيق - شكرا لك على المساعدة في تحسين μLauncher!\nيرجى إضافة المعلومات التالية إلى تقرير الأخطاء الخاص بك: - اتصل بالمطور الأصلي - اخفض الصوت - يمكنك تشغيل أهم تطبيقاتك بوسطة إيماءات اللمس أو الضغط على الأزرار. - اسحب من حواف الشاشة - خطأ: قفل الشاشة باستخدام إمكانية الوصول غير مدعوم على هذا الجهاز. الرجاء استخدام طريقة مسؤول الجهاز بدلاً من ذلك. - يتيح تعيين μlauncher كخدمة إمكانية الوصول قفل الشاشة وفتح قائمة التطبيقات الحديثة. يرجى ملاحظة أنه يتطلب كمية كبيرة من الأذونات. يجب ألا تمنح مثل هذه الأذونات باستخفاف لأي تطبيق. سوف يستخدم μlauncher خدمة إمكانية الوصول فقط لأداء الإجراءات التالية عند طلب المستخدم: * قفل شاشة * فتح التطبيقات الحديثة μlauncher لن يستخدم أبدًا خدمة إمكانية الوصول لجمع البيانات. يمكنك التحقق من شيفرة المصدر للتأكد. يرجى ملاحظة أنه يمكنك قفل الشاشة من خلال منح أذونات مسؤول الجهاز، لكنها لا تعمل مع بصمات الأصابع وفتح الوجه. -
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index d07ff7d..349d730 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -14,7 +14,7 @@ - --> Einstellungen - Aktionen + Apps Launcher Meta Taschenlampe umschalten Tutorial - 👋\n\nHier eine kurze Erklärung, wie dieser Launcher funktioniert. + Hier eine kurze Erklärung, wie dieser Launcher funktioniert. Konzept - µLauncher bietet eine minimalistische, effiziente und ablenkungsfreie Umgebung.\n\nDie App ist freie Software, enthält keine Werbung und sammelt keinerlei Daten. + µLauncher bietet eine minimalistische, effiziente und ablenkungsfreie digitale Umgebung.\n\nDie App ist freie Software, enthält keine Werbung und sammelt keinerlei Daten. Der Quellcode ist bei GitHub zu finden. Benutzung Der Homescreen zeigt nur das Datum und die Uhrzeit. Keine Ablenkung. - Häufig verwendete Apps können mittels Gesten, z.B. Wischen oder den Lautstärketasten geöffnet werden. + 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. Einrichtung Es wurden Standardapps ausgewählt, die Zuordnung kann hier angepasst werden: Die Auswahl kann in den Einstellungen später jederzeit geändert werden. Los gehts! - 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) + 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) Starten Einstellungen Mehr Optionen @@ -196,19 +202,28 @@ Es wurde keine geeignete Kamera gefunden. Fehler: Kein Zugriff auf die Kamera möglich. Methode zum Sperren des Bildschirms wählen + Ok %1$s umbenennen - μLauncher muss als Standardlauncher eingerichtet sein um auf den privaten Bereich zugreifen zu können. + µLauncher muss als Standardlauncher eingerichtet sein um auf den privaten Bereich zugreifen zu können. Fehler: Auf diesem Gerät kann der Bildschirm nicht mittels Bedienungshilfe gesperrt werden. Bitte stattdessen Geräteadministrator verwenden. - μLauncher - Bildschirm sperren + µLauncher - Bildschirm sperren Fehler: Bildschirm konnte nicht gesperrt werden. Die Bedienungshilfe ist nicht aktiviert. Bitte in den Einstellungen aktivieren Methode zum Sperren wählen Bedienungshilfe verwenden Geräteadministrator verwenden - μ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. + + µ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. + Methode zum Sperren auswählen - 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:

@@ -252,61 +267,16 @@ Transparenz Blau Grün + Ok Farbe Farbe wählen Open Source Lizenzen Open Source Lizenzen Keine App gefunden um die Suche durchzuführen. URL kann nicht geöffnet werden: kein Browser gefunden. - Mir ist bewusst, dass μLauncher hierdurch weitreichende Berechtigungen erhält. + Mir ist bewusst, dass µLauncher hierdurch weitreichende Berechtigungen erhält. Mir ist bewusst, dass Alternativen existieren (Geräteadministrator oder der Power-Button). - Ich willige ein, dass μLauncher eine Bedienungshilfe für Zwecke verwendet, die nicht unter Barrierefreiheit fallen. + Ich willige ein, dass µLauncher eine Bedienungshilfe für Zwecke verwendet, die nicht unter Barrierefreiheit fallen. Ich willige ein, dass µLauncher keine Daten sammelt. Bedienungshilfe aktivieren - 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: - Zurück - Zurück-Taste oder -Geste - (Rückwärts)]]> - Unten links -> mitte rechts -> oben links - - - V - Oben links -> unten mitte -> oben rechts - V (Rückwärts) - Unten rechts -> mitte links -> oben rechts - Λ - Unten links -> oben mitte -> unten rechts - Oben rechts -> unten mitte -> oben links - Λ (Rückwärts) - Unten rechts -> oben mtte -> unten links - Sicherheitslücke melden - Privaten Bereich nicht in der App Liste anzeigen - Privater Bereich - Shortcut hinzufügen - An Geste binden - In Appliste anzeigen - Privaten Bereich entsperren - Statusleiste verstecken - Navigationsleiste verstecken - Privaten Bereich sperren - Version - Alle Apps - Sobald nur noch eine App passt, wird diese automatisch gestartet.\nDas lässt sich unterdrücken, indem der Suche ein Leerzeichen vorangestellt wird. - ]]> - Oben rechts -> mitte links -> unten rechts - Oben links -> mitte rechts -> unten links - 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). - weitreichende Zugriffsrechte .
μLauncher wird diese ausschließlich zum Sperren des Bildschirms verwenden. μLauncher wird niemals irgendwelche Daten sammeln. Insbesondere werden mittels der Bedienungshilfe keine Daten gesammelt.]]>
- Tippen und hoch - Tippen, dann nach oben wischen - Tippen und nach unten - Tippen, dann nach unten wischen - Tippen und links - Tippen, dann nach links wischen - Tippen und rechts - Tippen, dann nach rechts wischen - Sicherheitslücken bitte nicht öffentlich bei GitHub melden, sondern auf dem folgenden Weg: - Privater Bereich - Musik: Wiedergabe / Pause - Appliste umkehren diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 1a04590..f0a80c6 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -16,13 +16,14 @@ --> No se pudo abrir la aplicación ¿Desea cambiar la configuración? - Abra la configuración para elegir una acción para este gesto + Abra la configuración para elegir una aplicación para esta acción Configuración + Aplicaciones Launcher Meta - Arriba + Deslizar Arriba Doble Arriba - Abajo + Deslizar Abajo Doble Abajo - Izquierda + Deslizar Izquierda Doble Izquierda - Derecha + Deslizar Derecha Doble Derecha - Tecla para subir el volumen - Tecla para bajar el volumen + Subir Volumen + Bajar Volumen Doble Click Click Largo - Fecha - reloj + Toca la fecha + Toca el reloj Elegir Aplicación + Todas las aplicaciones Instalar aplicaciones No se encontró la Store Seleccionar Launcher Información de la aplicación - Ver el tutorial de µLauncher + Su dispositivo no posee esta caracrerística. Desea cambiar los detalles de la aplicación? + Ver tutorial de Launcher Configuración por defecto Todas sus preferencias se eliminarán. Desea continuar? Reportar un error @@ -91,11 +96,13 @@ Otros Desinstalar Información - Buscar - Configuración de μLauncher + Se eliminó la aplicación + No se pudo eliminar la aplicación + Buscar Aplicaciones + Configuración de Launcher Aplicaciones - Subir el volumen - Bajar volumen + Música: Subir + Música: Bajar Música: Siguiente Música: Anterior Nada @@ -105,214 +112,19 @@ - --> Tutorial - 👋\n\n¡Tómate unos segundos para aprender a utilizar este Launcher! + Tómate unos segundos para aprender a usar este launcher Concepto - μLauncher está diseñado para ser mínimo, eficiente y libre de distracciones.\n\nNo contiene anuncios ni recopila datos. - ¡Es software libre (licencia MIT)!\n¡No olvides visitar el repositorio! + Launcher está diseñado para ser minimalista, eficiente y libre de distracciones.\n\nEs gratis y libre de anuncios y servicios de rastreo. + La aplicación es de código abierto (licencia MIT) y está disponible en GitHub!\n\nNo olvides echarle un vistazo al repositorio! Uso Tu pantalla de inicio contiene la fecha y hora local. Sin distracciones. - Puede iniciar sus aplicaciones más importantes con gestos táctiles o presionando botones. + Puedes iniciar tus aplicaciones con solo presionar o deslizar una vez. Elige algunas en la siguiente pantalla. Puesta a punto - Elegimos algunas aplicaciones predeterminadas para ti. Puedes cambiarlos ahora si lo deseas: + Elegimos algunas aplicaciones por defecto para ti, si lo deseas puedes cambiarlas ahora. También puedes cambiar tu selección más tarde. Vamos! - ¡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) + Estás listo para iniciar!\n\n Esperamos que esto te sea de gran ayuda!\n\n- Finn M Glas\n(el desarrollador) Iniciar Configuración Más opciones - atrás - Toca + Derecha Toca y desliza hacia la derecha - Desliza el dedo hacia la izquierda en la parte inferior de la pantalla - Desliza hacia abajo en el borde derecho de la pantalla - Botón de retroceso / gesto de retroceso - Desliza el dedo hacia arriba en el borde izquierdo de la pantalla - Desliza el dedo hacia arriba en el borde derecho de la pantalla - Desliza el dedo hacia abajo en el borde izquierdo de la pantalla - Dinámico - Color - Toca y desliza hacia arriba - Toque + Izquierda - Desliza el dedo hacia la derecha en la parte inferior de la pantalla - Desliza el dedo hacia la izquierda en la parte superior de la pantalla - Abajo (borde izquierdo) - Presione el botón para subir el volumen - Presione la barra espaciadora para desactivar esta función temporalmente. - Aplicaciones - Arriba a la izquierda -> Abajo en el medio -> Arriba a la derecha - Presione regresar mientras busca en la lista de aplicaciones para iniciar una búsqueda web. - Error: No se puede acceder a la antorcha. - Fondo (lista de aplicaciones y configuración) - Tema de color - Fuente - Iconos de aplicaciones monocromáticos - Derecha (arriba) - Derecha (Abajo) - Izquierda (arriba) - nunca recopilará ningún dato. En particular, μLauncher no utiliza el servicio de accesibilidad para recopilar ningún dato.]]> - 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. - Ocultar el espacio privado de la lista de aplicaciones - Diseño de la lista de aplicaciones - Espacio privado - No se detectó ninguna cámara con linterna. - Activar o desactivar el bloqueo del espacio privado - Activar o desactivar la antorcha - Ocultar aplicaciones pausadas - Aplicaciones ocultas - Cambiar el nombre de %1$s - Cancelar - V - Informar un error - mostrar - μLauncher debe ser la pantalla de inicio predeterminada para acceder al espacio privado. - No informe vulnerabilidades de seguridad públicamente en GitHub, sino utilice lo siguiente: - Informar sobre una vulnerabilidad de seguridad - Crear informe - Únete al chat de μLauncher - Donar - Ajustar el volumen - Expandir el panel de notificaciones - El espacio privado no está disponible - Desliza hacia arriba - Haga doble clic en un área vacía - Presione el botón para bajar el volumen - Haga clic largo en un área vacía - Haga clic en la fecha - Haga clic en el reloj - Mostrar la hora - Sombra de texto - Ocultar la barra de estado - Ocultar la barra de navegación - Deslizar con dos dedos - predeterminado - Aplicaciones favoritas - Aplicaciones ocultas - Deshacer - Doy mi consentimiento para que μLauncher utilice el servicio de accesibilidad para proporcionar una funcionalidad no relacionada con la accesibilidad. - Buscar (sin inicio automático) - Soy consciente de que esto otorgará privilegios de gran alcance a μLauncher. - Soy consciente de que existen otras opciones (utilizando privilegios de administrador del dispositivo o el botón de encendido). - Licencias de código abierto - Licencias de código abierto - versión - Todas las aplicaciones - Elija el método para bloquear -
- - Administrador del dispositivo - No funciona con desbloqueo por huella dactilar ni reconocimiento facial. - -
-
- - Servicio de Accesibilidad - Requiere privilegios excesivos. - μLauncher utilizará esos privilegios solo para bloquear la pantalla. -
- (Realmente no deberías confiar en una aplicación aleatoria que acabas de descargar con tal afirmación, pero puedes consultar el código fuente). -
- 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 reactivar posteriormente. - -



- Puede cambiar su selección más tarde en la configuración. - ]]>
- Utilice el servicio de accesibilidad - Usar el administrador del dispositivo - Elija el método para bloquear la pantalla - Rojo - alfa - Azul - Verde - Sans serif - Serif - Monoespaciado - Serif monoespaciado - Mostrar la fecha - Utilice el formato de fecha localizado - Mostrar segundos - Cambiar fecha y hora - Girar la pantalla - Acciones de deslizamiento de borde - Desliza el dedo por el borde de la pantalla - Ancho del borde - No mostrar aplicaciones que estén vinculadas a un gesto en la lista de aplicaciones - Ver el código fuente - ¡Gracias por ayudarnos a mejorar μLauncher!\nConsidere agregar la siguiente información a su informe de error: - Copiar al portapapeles - Añadir a favoritos - Eliminar de favoritos - Esconder - Renombrar - Aplicaciones favoritas - Espacio privado - Puede buscar rápidamente entre todas las aplicaciones en la lista de aplicaciones.\n\nDesliza hacia arriba para abrirlo o asigne un gesto diferente. - Una vez que sólo coincide una aplicación, se inicia automáticamente.\nEsto se puede desactivar anteponiendo un espacio a la consulta. - 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. - Esta funcionalidad requiere Android 6 o posterior. - Esta funcionalidad requiere Android 15 o posterior. - Aplicación oculta. Puedes hacerlo visible nuevamente en la configuración. - Configuración rápida - μLauncher debe ser administrador del dispositivo para poder bloquear la pantalla. - Esto es necesario para la acción de la pantalla de bloqueo. - Habilitar la acción de bloqueo de pantalla - 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) - El servicio de accesibilidad de μLauncher no está habilitado. Por favor, habilítelo en la configuración - Espacio privado bloqueado - Espacio privado desbloqueado - Bloquear el espacio privado - Desbloquear espacio privado - Error: El bloqueo de la pantalla mediante accesibilidad no es compatible con este dispositivo. En su lugar, utilice el administrador del dispositivo. - μLauncher - pantalla de bloqueo - Color - Elige el color - Doy mi consentimiento para que μLauncher no recopile ningún dato. - Activación del servicio de accesibilidad - Activar el servicio de accesibilidad - No se encontró ninguna aplicación para gestionar la búsqueda. - No se puede abrir la URL: no se encontró ningún navegador. - Acciones - Toca + Arriba - Desliza hacia arriba con dos dedos - Desliza hacia abajo - Toque + Abajo - Toca y desliza hacia abajo - Desliza hacia abajo con dos dedos - Desliza hacia la izquierda - Toca y desliza hacia la izquierda - Desliza dos dedos hacia la izquierda - Desliza hacia la derecha - Toque + Derecha - Desliza con dos dedos hacia la derecha - Desliza el dedo hacia la derecha en la parte superior de la pantalla - Izquierda (Abajo) - Arriba (borde izquierdo) - Arriba (borde derecho) - Abajo (borde derecho) - Arriba a la izquierda -> centro a la derecha -> abajo a la izquierda - Abajo a la izquierda -> centro a la derecha -> arriba a la izquierda - Arriba a la derecha -> centro a la izquierda -> abajo a la derecha - Abajo a la derecha -> centro a la izquierda -> arriba a la derecha - V (Reversa) - Arriba a la derecha -> Abajo en el medio -> Arriba a la izquierda - Λ - Abajo a la izquierda -> arriba en el medio -> abajo a la derecha - Λ (Inverso) - Abajo a la derecha -> arriba en el medio -> abajo a la izquierda - Atenuación - Sólido - Valor predeterminado del sistema - Transparente - Difuminar - Buscar en la web - texto - Red - Música: Reproducir / Pausa - Pantalla de bloqueo - Agregar acceso directo - Vincular al gesto - Mostrar en la lista de aplicaciones - Invertir la lista de aplicaciones - + \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index c1d11b3..388e089 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -14,6 +14,7 @@ - --> Réglages + Applications Launcher Meta Choisir μLauncher comme application d\'écran d\'accueil par défaut Informations sur l\'application + Votre appareil ne prend pas en charge cette fonctionnalité. Souhaitez-vous plutôt accéder aux détails de l\'application ? Regarder le tutoriel Réinitialiser Vous allez réinitialiser tous vos paramètres. Souhaitez-vous poursuivre ? @@ -83,6 +88,8 @@ Autre Désinstaller Informations + Application supprimée + Impossible de désinstaller l\'application Chercher des applications Réglages d\'µLauncher Toutes les Applications @@ -168,6 +175,7 @@ Je suis conscient que cela accordera des privilèges importants à µLauncher. Choisir une couleur Activation du service d\'accessibilité + Ok Couleur Je consent à µLauncher utilisation du service d’accessibilité pour fournir une fonction non liée à l’accessibilité. Je consent à la non-collecte de données par µLauncher. @@ -214,6 +222,7 @@ Plein Renommer %1$s Utiliser le service d’accessibilité + Ok Chercher sur le web Appuyer sur entrée en cherchant une application pour lancer une recherche web. Annuler @@ -222,4 +231,4 @@ Balayer vers le bas au bord gauche de l\'écran Balayer au bord de l\'écran Couleur - + \ 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 318ad43..320bfc6 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -2,7 +2,7 @@ Scorri verso destra sul bordo inferiore dello schermo Aspetto - Scegliere + Scegliere l\'applicazione Tema Questo launcher è progettato per essere minimale, efficiente e privo di distrazioni. Non contiene pagamenti, pubblicità o servizi di tracciamento. Predefinito @@ -34,10 +34,12 @@



Puoi cambiare le tue scelte in seguito nelle impostazioni. ]]>
+ Il tuo dispositivo non supporta questa funzione. Vuoi aprire la pagina di dettaglio dell\'applicazione? Impossibile aprire l\'applicazione Desideri modificare le impostazioni? Apri le impostazioni per abbinare un\'azione a questo gesto Impostazioni + Applicazioni Launcher Meta Scorri verso il basso con due dita @@ -81,6 +83,7 @@ Premi il pulsante di aumento del volume Riduci il volume Premi il pulsante per ridurre il volume + Vedi tutte le applicazioni Installa le applicazioni Icone monocromatiche Mostra l\'ora @@ -109,8 +112,10 @@ Font Inverti data e ora Scegli uno sfondo + Cambia immagine di sfondo Schermo Mantieni lo schermo acceso + Schermo intero Ruota lo schermo Funzionalità Apri automaticamente la tastiera per cercare @@ -176,6 +181,7 @@ Nascondi Mostra Rinomina + Le applicazioni selezionate sono state rimosse Cerca Impostazioni μLauncher Espandi il pannello notifiche @@ -189,7 +195,9 @@ Utilizzo La schermata principale contiene solo data e ora. Nessuna distrazione. Questa funzione richiede Android 6 o successivi. + Ok Rinomina %1$s + Impossibile rimuovere l\'applicazione Dinamico Colore Due dita verso l\'alto @@ -203,6 +211,7 @@ Trasparente Blu Verde + Ok Colore Scegli colore Attiva Servizi di Accessibilità @@ -228,4 +237,4 @@ 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-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 6d081f0..a6b3dae 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -1,195 +1,2 @@ - - アプリを開けません - 設定を変更しますか? - 設定 - ランチャー - その他 - このジェスチャのアクションを選択するには設定を開きます - 上にスワイプ - タップしてから上にスワイプ - Double Up - Tap + Up - Up - Back - 2本指で上にスワイプ - Down - 下にスワイプ - Tap + Down - タップしてから下にスワイプ - Double Down - 2本指で下にスワイプ - Left - 左にスワイプ - Tap + Left - タップしてから左にスワイプ - Double Left - 2本指で左にスワイプ - Right - 右にスワイプ - タップしてから右にスワイプ - Double Right - Right (Top) - 画面の上部で右にスワイプ - Right (Bottom) - 画面の下部で右にスワイプ - Left (Bottom) - 画面の下部で左にスワイプ - Left (Top) - 画面の上部で左にスワイプ - Up (Left Edge) - Up (Right Edge) - 画面の右端で上にスワイプ - Down (Left Edge) - 画面の左端で下にスワイプ - Down (Right Edge) - ]]> - 左上 -> 右中 -> 左下 - (Reverse)]]> - 左下 -> 右中 -> 左上 - - 右上 -> 左中 -> 右下 - - V - 左上 -> 中下 -> 右上 - V (Reverse) - 右上 -> 中下 -> 左上 - Λ - 左下 -> 中上 -> 右下 - Λ (Reverse) - 右下 -> 中上 -> 左下 - Volume Down - 音量ダウンボタンを押す - Double Click - 空白部分をダブルタップ - Long Click - Date - 日付をタップ - Time - 時刻をタップ - アプリを選択 - 外観 - カラーテーマ - デフォルト - ダーク - ダイナミック - 文字の影 - 透明 - ブラー - ソリッド - フォント - システムデフォルト - モノクロのアプリアイコン - - - 時刻を表示 - 日付を表示 - ローカライズされた日付形式を使用する - 秒を表示 - 日付と時刻を反転 - 壁紙を選択 - 表示 - 画面オンを維持 - 画面の回転 - 2本指でスワイプ - Edgeスワイプアクション - 画面端でスワイプ - アプリリストで検索中にリターンキーを押すとWeb検索が起動します。 - Webで検索 - 検索時にキーボードを表示 - アプリ - ジェスチャーに設定されたアプリをアプリ一覧に表示しない - 一時停止されたアプリを隠す - アプリ一覧のレイアウト - アプリ一覧を反転 - デフォルト - テキスト - グリッド - ランチャーのチュートリアルを見る - 設定をリセット - すべての設定を破棄します。続行しますか? - ソースコードを見る - バグを報告 - クリップボードにコピー - セキュリティ上の脆弱性をGitHubに公開しないでください。代わりに以下を使用してください。 - セキュリティ上の脆弱性を報告 - レポートを作成 - µLauncherのチャットに入る - プライバシーポリシー - Discordに参加してください! - 非表示のアプリ - プライベートスペース - アプリを選択 - アプリ - その他 - アンインストール - アプリ情報 - お気に入りから削除 - 隠す - 名称を変更 - 検索 - 検索(自動起動なし) - µLauncherの設定 - すべてのアプリ - プライベートスペースのロックを切り替え - 音楽: うるさい - 音楽: ひっそり - 音楽: 次 - 音楽: 前 - 通知パネルを表示 - なにもしねぇ - 画面をロック - ライトを切り替え - ショートカットを追加 - ジェシュチャーに設定 - アプリ一覧に表示 - チュートリアル - コンセプト - 使い方 - ホーム画面には現地の日付と時刻が表示されます。邪魔されることはありません。 - 1回のスワイプまたはボタンのタップでアプリを起動できます。次のスライドでいくつか選択してください。 - セットアップ - 選択内容は後で変更することもできます。 - さあ行きましょう! - 始める - 設定 - 戻るボタン / 戻るジェスチャ - ライト - Doubleスワイプアクション - 検索結果を起動 - お気に入りのアプリ - 音量アップボタンを押す - 空白部分をロングタップ - 機能性 - µLauncherの改善にご協力いただきありがとうございます。\nバグレポートに次の情報を追加することを検討してください。 - お気に入りに追加 - 画面の左端で上にスワイプ - 画面の右端で下にスワイプ - アプリをインストール - 始める準備はできました!これがあなたにとって大きな価値となることを願っています! \t- Finn(Launcherの作成者)とJosia(いくつかの改良を行い、フォーク μLauncher を保守) - Tap + Right - 2本指で右にスワイプ - 非表示のアプリ - μLauncherホーム画面に設定 - フォークの開発者に問い合わせ - オリジナルの開発者に問い合わせる - お気に入りのアプリ - 音楽: 再生 / 一時停止 - 薄暗い - 感度 - アプリ情報 - Volume Up - すべてのアプリ - 表示 - 右下 -> 左中 -> 右上 - 背景(アプリ一覧と設定) - 端の幅 - この機能を一時的に無効にするにはスペースキーを押します。 - プライベートスペース - アプリ一覧からプライベートスペースを隠す - バグを報告 - このランチャーの使い方を学ぶのにほんの数秒しかかかりません - Launcherは、最小限かつ効率的で、邪魔にならないように設計されています。支払い、広告、追跡サービスは一切ありません。 - このアプリはオープンソース(MIT ライセンス)であり、GitHub で入手できます!リポジトリを必ずチェックしてください! - デフォルトのアプリをいくつか選択しました。必要に応じて今すぐ変更できます。 - + \ No newline at end of file diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml deleted file mode 100644 index 0a45d57..0000000 --- a/app/src/main/res/values-lt/strings.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - Norite pakeisti nustatymus? - Nustatymai - Veiksmai - Paleidimo programėlė - Apie - Atgal - Grįžimo mygtukas / grįžimo gestas - Perbraukimas aukštyn - Bakstelėkite + aukštyn - Nepavyksta paleisti programėlės - Atidarykite nustatymus norėdami pasirinkti šio gesto veiksmą - Aukštyn - Bakstelėjimas ir perbraukimas aukštyn - diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index fcdd9e8..6a6149c 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -14,6 +14,7 @@ - --> Configurações + Apps Launcher Meta Definir o μLauncher como tela inicial Informações do aplicativo - Ver tutorial do µLauncher + Seu dispositivo não é compatível com esse recurso. Gerenciar detalhes do app em vez disso? + Ver tutorial do launcher Redefinir configuraçãos Você vai descartar todas as suas preferências. Continuar? Reportar um bug @@ -95,11 +100,13 @@ Outros Desinstalar Informações do aplicativo + O app selecionado foi removido + Não foi possível remover o app Busque - Configurações do μLauncher + Configurações do µLauncher Todos os apps - Aumentar volume - Diminuir volume + Música: Mais alto + Música: Mais silencioso Música: Próximo Música: Anterior Não faça nada @@ -109,18 +116,18 @@ - --> Tutorial - 👋\n\nTire alguns segundos para aprender a usar este Launcher! + Tire alguns segundos para aprender a usar este Launcher! Conceito - 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. - É um software livre (sob licença MIT)!\nNão deixe de conferir o repositório! + O Launcher foi criado para ser minimalista, eficiente e livre de distrações. Ele é livre de pagamentos, anúncios e serviços de rastreamento. + O app é de código aberto (licença MIT) e está disponível no GitHub! Não deixe de conferir o repositório! Uso Sua tela inicial contém a data e hora local. Sem distrações. - Você pode iniciar seus aplicativos com gestos de toque ou apertando um botão. + Você pode iniciar seus aplicativos com um gesto único ou apertando um botão. Escolha algumas ações no próximo slide. Configurar Selecionamos alguns aplicativos padrão para você. Se quiser, você pode alterá-los agora: Você pode alterar suas escolhas mais tarde. Vamos lá! - 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) + Tá todo pronto para começar! Espero que isso seja de grande valor para você! - Finn (que criou o Launcher) \te Josia (que fez algumas melhorias e tb mantém o fork do μLauncher) Começar Configurações Mais opções @@ -147,11 +154,11 @@ 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) O Serviço de acessibilidade do μLauncher não está ativado. Entre em configurações para ativar Não mostrar apps com um gesto atribuído na lista de aplicativos - O μLauncher precisa virar um Administrador do dispositivo para poder bloquear a tela. + O µLauncher precisa tornar-se o Administrador do dispositivo para poder bloquear a tela. Isto é necessário para realizar a ação de bloqueio da tela. Permitir a ação de bloqueio da tela Erro: Não é possível acessar a lanterna. - μLauncher + µLauncher - bloqueio da tela Usar o Serviço de acessibilidade Usar o Administrador do dispositivo Escolha um método de bloqueio @@ -160,7 +167,7 @@ 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 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. + 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. Escolha um método de bloqueio Há dois métodos para bloquear a tela. @@ -174,9 +181,9 @@

Serviço de acessibilidade

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.
- (Você realmente não deveria confiar num app aleatório que você baixou e tá pedindo estas permissões, mas pode verificar o código-fonte.) + (Você realmente não deveria confiar num app aleatório que você baixou que tá pedindo estas permissões, mas pode verificar o código-fonte.)
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 reativado depois. @@ -210,7 +217,7 @@ Deslize na borda da tela Largura da borda Ver código-fonte - Entre no chat do μLauncher + Entre no chat do µLauncher Bloquear a tela Sombra no texto Transparente @@ -225,6 +232,7 @@ Texto Grade Renomear + beleza Renomear %1$s Serif monospace Serif @@ -236,18 +244,14 @@ Verde Cor Escola a cor - Autorizo o μLauncher a usar Serviço de acessibilidade para acessar funcionalidades não relacionadas com a acessibilidade. - Não autorizo ao μLauncher coletar quaisquer dados. + Autorizo a utilização do Serviço de acessibilidade para disponibilizar funcionalidades não relacionadas com a acessibilidade. + Não autorizo ao µLauncher a coleta de quaisquer dados. Ativação do Serviço de acessibilidade Ativar o Serviço de acessibilidade Cancelar - permissões elevadas ao μLauncher.
μLauncher usará estas permissões apenas para executar as seguintes ações: -
    -
  • Bloquear a tela
  • -
  • Apps recentes
  • -
- μLaunchernunca coletará nenhum dado. Sobretudo, o μLauncher não implementa o Serviço de acessibilidade para coletar os dados.]]>
- Estou ciente de que isto concederá permissões elevadas ao μLauncher. + permissões elevadas ao µLauncher.
µLauncher usará estas permissões apenas para bloquear a tela. µLauncher nunca coletará nenhum dado. Sobretudo, o µLauncher não implementa o Serviço de acessibilidade para coletar dados.]]>
+ beleza + Estou ciente de que isto concederá permissões elevadas ao µLauncher. Estou ciente de que existem outras opções (permissões de Administrador do aparelho ou o botão de ligar). Pesquise na internet Ao buscar na lista de apps toque no Enter para iniciar uma pesquisa na internet. @@ -260,13 +264,13 @@ Espaço privado trancado Espaço privado liberado Espaço privado indisponível - O μLauncher precisa ser definido como a tela inicial padrão para poder usar Espaço privado. + O µLauncher precisa ser definido como a tela inicial padrão para poder usar Espaço privado. Copiar para memória Não relate vulnerabilidades de segurança publicamente no GitHub, use o seguinte: Relatar vulnerabilidade de segurança Criar relatório Relatar um bug - Obrigado por ajudar a melhorar o μLauncher!\nConsidere adicionar as seguintes informações ao relatório dos bugs: + Obrigado 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. @@ -305,18 +309,6 @@ Música: Reproduzir / Pausar Canto inferior direito -> centro esquerdo -> canto superior direito Inferior direito -> superior médio -> inferior esquerdo - Inverter a lista de apps - Doar - Ajustar volume - Ocultar barra de status - Ocultar barra de navegação - Versão - Todos apps - Você pode encontrar rápido todos os apps na lista de aplicativos.\n\nDeslize para cima para abrir ou definir um gesto específico. - Quando apenas um aplicativo corresponde, vai ser iniciado automaticamente.\nIsso pode ser desativado acrescentando um espaço durante a busca. - Ações - Apps recentes - Erro: Falha ao ativar o Serviço de acessibilidade. - Usar outro iniciador - 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) + Lista de apps inversa + Ok diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 8c5a2e7..bfd0cfe 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -52,6 +52,7 @@ Ayarlarını değiştirmek ister misiniz? Bu harekete bir eylem atamak için ayarları açın Ayarlar + Uygulamalar Başlatıcı Daha Fazlası Yukarı @@ -104,6 +105,7 @@ Saat Saate tıklayın Uygulama Seçin + Tüm uygulamaları göster Uygulamaları yükle Mağaza bulunamadı Görünüş @@ -118,6 +120,8 @@ Hiçbir şey yapma Kaynak kodunu göster Hatayı bildirin + Seçilen uygulama kaldırıldı + Uygulama kaldırılamadı Uygulamaları Ara Tüm Uygulamalar Favori Uygulamalar @@ -130,8 +134,10 @@ Saniyeleri gösteri Tarih ile zamanı yer değiştir Duvar kağıdı seç + Duvar kağıdını değiştir Ekran Ekranı açık tut + Tam ekran kullan Ekranı döndür İşlevsellik Ekranın köşesinden kaydırın @@ -159,6 +165,7 @@ Metin Izgara Uygulama Detayı + Sizin cihazınız bu özelliği desteklemiyor. Onun yerine uygulama detaylarını düzenleyin? Ayarları Sıfırlayın Tüm tercihlerinizi bir kenara bırakacaksınız. Devam mı? Tek uzay @@ -191,6 +198,7 @@ Hata: Fenere erişilemiyor. Ekranı kilitleme yöntemini seçin İptal + OK Yeniden Adlandır %1$s Dinamik Renk @@ -198,6 +206,7 @@ Alfa Mavi Yeşil + OK Renk Renk seçin - + \ No newline at end of file diff --git a/app/src/main/res/values-w820dp/dimens.xml b/app/src/main/res/values-w820dp/dimens.xml new file mode 100644 index 0000000..63fc816 --- /dev/null +++ b/app/src/main/res/values-w820dp/dimens.xml @@ -0,0 +1,6 @@ + + + 64dp + diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 608e57b..793ef9d 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -5,89 +5,96 @@ 更多选项 设置 外观 - 色调风格 + 主题 显示 其他 - 上滑 - 下滑 + + 无法打开应用 要更改其设置吗? 打开设置,为该手势绑定一个应用程序 + 应用程序 启动器 杂项 - 双指左滑 - 双指上滑 - 双指下滑 + 左滑两次 + 上滑两次 + 下滑两次 - 双指右滑 - 右滑(顶部) - 右滑(底部) - 左滑(底部) - 左滑(顶部) - 上滑(左边缘) - 上滑(右边缘) - 下滑(左边缘) - 下滑(右边缘) - 音量增加键 - 音量降低键 + 右滑两次 + 右(顶部) + 右(底部) + 左(底部) + 左(顶部) + 上(左边缘) + 上(右边缘) + 下(左边缘) + 下(右边缘) + 音量加 + 音量减 双击 长按 - 桌面日期 - 桌面时钟 + 日期 + 时间 选择应用 + 浏览全部应用 安装应用 没有找到应用市场 - 选择壁纸 + 选择一个壁纸 + 换壁纸 保持屏幕常亮 + 使用全屏 功能 - 边缘滑动手势 - 自动启动搜索匹配项 - 自动激活搜索 + 边缘滑动动作 + 零点击启动唯一搜索结果 + 搜索时呼出键盘 灵敏度 应用信息 - 查看 µLauncher 的使用教程 + 您的设备不支持此功能。要不打开应用程序详细? + 查看启动器教程 重置设置 - 该操作将丢弃您的所有配置。是否继续? - 错误反馈 + 你将放弃你所有的配置。继续吗? + 反馈 BUG 联系该 fork 版本的作者 隐私政策 联系原作者 - 加入我们的 Discord 社区! + 加入 Discord! 全部应用 选择应用 - 👋\n\n花几秒钟时间,了解一下如何用这个启动器吧! + 花几秒时间学下咋用这个启动器吧! 概念 - 这是一款自由软件(遵循 MIT 许可)!\n欢迎查看项目仓库! + 该应用是开源的(MIT许可),并在 GitHub 上可用!一定要来看看代码仓库! 使用方法 - 您的桌面仅包含本地日期和时间,没有多余的项目。 + 您的主屏幕仅包含本地日期和时间,没有其它纷纷扰扰。 设置 - 我们为您预设了一些快捷操作。如果您不满意,现在就试试点击右侧图标: - 您也可以稍后更改您的选择。 + 我们为您选择了一些默认应用。如果您愿意,现在可以更改它们: + 您也可以稍后更改选择。 开始! 应用 卸载 应用信息 + 无法移除应用 + 移除了选定的应用 搜索 - μLauncher 设置 + 启动器设置 全部应用 - 增大音量 - 降低音量 + 音乐:大声 + 音乐:小声 音乐:上一首 音乐:下一首 - 不做任何设置 + 啥也不干 教程 - μLauncher 的设计理念是简约、高效,无干扰。\n\n不含广告、且不收集任何数据。 - 您可以通过手势或按键来启动对您来说最重要的应用程序。 - 将 μLauncher 设为默认启动器 - 您已经准备好开始使用本启动器了!\n\n希望本快捷教程能对您有所帮助!\n\n- Finn(Launcher 的作者)和 Josia(对 μLauncher 进行了改进和维护) - 双指滑动手势 + μLauncher 的设计是最小、高效且无干扰。它不付费、无广告、不追踪。 + 您只需滑动屏幕或按下按钮即可启动应用程序。在下一步向导中选择一些应用程序。 + 将 μLauncher 设为默认桌面 + 您已经准备好开始了!我希望这对您很有价值!——Finn(Launcher 作者)和 Josia(做了一些改进并维护了 μLauncher 分支) + 双滑动作 使用本地日期格式 显示时间 显示日期 - 交换日期和时间位置 - 背景(应用程序列表和设置页面) + 翻转日期和时间 + 背景(应用列表和设置) 字体 黑白应用图标 显示秒 @@ -100,12 +107,12 @@ 错误:无法访问闪光灯。 选择锁屏方法 选择锁屏的方法 - 不要在应用程序列表中显示已被绑定到手势操作的应用 + 不要在应用抽屉中显示被绑定到手势的应用 此功能需要 Android 6 或更高版本。 应用程序已隐藏。您可在设置中让它再次显示。 - µLauncher 需要激活“设备管理应用”权限才能够锁定屏幕。 - 这是执行锁屏操作所必需的。 - µLauncher + µLauncher 需要是设备管理员才能够锁定屏幕。 + 这是锁屏动作所必需的。 + µLauncher -锁屏 收藏的应用 添加到收藏夹 从收藏夹中移除 @@ -114,41 +121,42 @@ 撤销 隐藏的应用 隐藏的应用 - 向上滑动 - 使用双指向上滑动 - 向下滑动 - 使用双指向下滑动 - 向左滑动 - 使用双指向左滑动 - 向右滑动 - 使用双指向右滑动 - 在桌面顶部向右滑动 - 在桌面底部向右滑动 - 在桌面底部向左滑动 - 在桌面顶部向左滑动 - 在桌面左边缘向上滑动 - 在桌面右边缘向上滑动 - 在桌面左边缘向下滑动 - 在桌面右边缘向下滑动 - 按下音量增加键 - 按下音量降低键 + 上滑 + 用双指向上滑动 + 下滑 + 双指向下滑动 + 左滑 + 双指向左滑动 + 右滑 + 双指向右滑动 + 在屏幕顶部向右滑动 + 在屏幕底部向右滑动 + 在屏幕底部向左滑动 + 在屏幕顶部向左滑动 + 在屏幕左边缘向上滑动 + 在屏幕右边缘向上滑动 + 在屏幕左边缘向下滑动 + 在屏幕右边缘向下滑动 + 按下音量增大按钮 + 按下音量降低按钮 双击空白区域 长按空白区域 - 点击桌面日期 - 点击桌面时钟 + 点击日期 + 点击时间 查看源代码 - 加入 μLauncher 的聊天群 + 加入 µLauncher 聊天群 收藏的应用 锁屏 文本阴影 - 使用双指进行滑动手势操作 + 双指滑动 + 确定 重命名 %1$s 默认 - 暗色 + 深色 透明 - 变暗 + 昏暗 模糊 - 纯色 + 固实 系统默认 等宽 衬线 @@ -157,131 +165,52 @@ 边缘宽度 重命名 启用锁屏动作 - μLauncher 的“无障碍”服务未启用,请在设置中启用它。 - 错误:此设备不支持使用“无障碍”服务锁定屏幕。请改用激活“设备管理应用”权限。 - 使用“无障碍”服务 - 激活“设备管理应用”权限 + μLauncher 的无障碍服务未启用。请在设置中启用它 + 错误:此设备不支持使用无障碍功能锁定屏幕。请改用设备管理员。 + 使用无障碍服务 + 使用设备管理员 取消 - 亮色 - 启动器设置 - 错误:锁定屏幕失败。(如果您刚刚升级了本启动器,请尝试在手机设置中手动禁用再重新启用“无障碍”服务。) - 在桌面边缘进行滑动手势操作 - 将 µLauncher 设置为“无障碍”服务以允许其锁定屏幕和展示最近应用屏幕。请注意,这会使 µLauncher 获得额外的权限。你永远不应该轻易地授予任何应用程序这样的权限。μLauncher 仅在被用户要求时才会使用“无障碍”服务权限以实现: * 锁定屏幕 * 展示最近应用屏幕。μLauncher 不会使用“无障碍”服务来收集任何数据。您可以审核我们的源代码。请注意,锁定屏幕也可以通过激活 µLauncher 的“设备管理应用”权限来实现,然而,这种方法无法与于指纹解锁和面部解锁兼容。 - 返回操作 + 浅色 + 快速设置 + 错误:锁定屏幕失败。(如果您刚刚升级了应用程序,请尝试在手机设置中手动禁用并重新启用无障碍服务) + 在屏幕边缘滑动 + 将 µLauncher 设为无障碍服务允许其锁定屏幕。请注意,这需要过多的权限。你永远不应该轻易地授予任何应用程序这样的权限。µLauncher 将仅使用无障碍服务功能锁屏。您可以审计源代码。请注意,锁屏也可以通过授予 µLauncher 设备管理员权限来实现,然而,这种方法不适用于以指纹和面部解锁。 + 返回 红色 蓝色 透明度 绿色 + 确定 动态 私人空间 私人空间 - 设置颜色 + 选择颜色 颜色 - 错误反馈 + 报告错误 ]]> 锁定私人空间 V Λ - 纯文本 + 文本 网格 创建报告 解锁私人空间 默认 - 文本颜色 + 颜色 复制到剪贴板 此功能需要 Android 15 或更高版本。 切换私人空间锁 - 激活“无障碍”服务 - 正在激活“无障碍”服务 + 激活无障碍服务 + 正在激活无障碍服务 开源许可证 开源许可证 - 在应用程序列表中显示 + 在应用列表中显示 添加快捷方式 私人空间已锁定 私人空间已解锁 私人空间不可用 - µLauncher 需要作为默认启动器才能访问私人空间。 + µLauncher 需要作为默认的主屏幕来访问私人空间。 没有找到处理搜索的应用。 无法打开 URL:找不到浏览器。 - 我已知晓,这将赋予 μLauncher 广泛且重要的权限。 - 在应用程序列表中隐藏私人空间 - 隐藏已被暂停的应用 - 返回按键 / 返回手势 - 先单击然后再向下滑动 - 在网络上搜索 - (从)右上(滑向)中左(滑向)右下 - 输入搜索内容后,按回车键直接在应用程序列表界面启动网络搜索。 - (从)左下(滑向)中上(滑向)右下 - 选择锁定设备的方式 - 有2种方式可以用来锁定屏幕。 - 遗憾的是,两者都有缺点:

- -

通过激活“设备管理应用”权限

- 该方法无法和指纹解锁和脸部解锁共同使用。 - -
-
- -

通过“无障碍”功能

- 需要更多的权限。 - μLauncher 将这些权限仅用于锁定屏幕。 -
- (对于任何一个从网上下载的应用所做的类似声明,你都不应该抱持“默认为可信”的态度,你可以并应该检查一下它的源代码.) -
- 在某些设备上,激活“无障碍”服务后,启动 PIN 码将不再用于加密数据。 - 如果遇到该问题,可以通过该方法重新激活启动 PIN 码用于数据加密。 - -



- 你可以在设置中随时更改这个选项。 - ]]>
- 搜索(不触发自动启动匹配项) - 广泛且重要的权限。
但 μLauncher 将这些权限用于: -
    -
  • 锁定屏幕
  • -
  • 展示最近应用屏幕
  • -
-µLauncher 绝不会收集任何数据。尤其是,μLauncher 不会使用“无障碍”服务来收集任何数据。]]>
- (从)左上(滑向)中右(滑向)左下 - 单击 + 上滑 - 单击 + 下滑 - 单击 + 左滑 - 先单击然后再向左滑动 - 先单击然后再向上滑动 - 单击 + 右滑 - 先单击然后再向右滑动 - (从)左下(滑向)中右(滑向)左上 - (从)右下(滑向)中左(滑向)右上 - (从)左上(滑向)中下(滑向)右上 - (从)右上(滑向)中下(滑向)左上 - (从)右下(滑向)中上(滑向)左下 - Λ (反向) - V(反向) - (反向)]]> - - 开启后将直接启动搜索所匹配到的应用,可以通过在搜索内容前添加空格来临时停用该功能。 - 应用程序列表样式 - 绑定到手势 - 音乐:播放 / 暂停 - 报告安全漏洞 - 请不要在 Github 上以公开的方式报告安全漏洞,请使用以下方式进行报告: - 感谢您帮助改进 µLauncher!\n请考虑在您的应用程序错误反馈中添加以下信息: - 我已知晓,还有其他替代方法(激活“设备管理应用”权限或通过电源按键)。 - 我同意 μLauncher 不收集任何数据。 - 捐赠 - 调整音量 - 版本 - 所有应用 - 您可以在应用程序列表中快速找到已安装的应用程序。\n\n您可以通过上滑打开应用程序列表,也可以通过绑定其他手势操作来打开应用程序列表。 - 您还可以搜索,当匹配到唯一的应用程序后,该应用将自动启动。\n如果你不想触发自动启动,可以在搜索内容前加上空格以禁用。 - 隐藏状态栏 - 隐藏导航栏 - 倒序排列应用程序 - 我同意 μLauncher 使用无障碍服务来提供与无障碍服务无关的其他功能。 - 快捷操作 - 最近应用屏幕 - 错误:启用“无障碍”服务失败。 - 错误:无法展示最近应用屏幕。(如果您刚刚升级了本启动器,请尝试在手机设置中手动禁用再重新启用“无障碍”服务。) - 启动其他启动器 diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml index 89ec086..33d2e57 100644 --- a/app/src/main/res/values/donottranslate.xml +++ b/app/src/main/res/values/donottranslate.xml @@ -176,7 +176,7 @@ μLauncher +

µLauncher

Modifications to Launcher.

github.com/jrpie/launcher

diff --git a/app/src/main/res/values/ic_launcher_background.xml b/app/src/main/res/values/ic_launcher_background.xml new file mode 100644 index 0000000..beab31f --- /dev/null +++ b/app/src/main/res/values/ic_launcher_background.xml @@ -0,0 +1,4 @@ + + + #000000 + \ 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 21f25f5..4512b62 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -16,7 +16,7 @@ --> Settings - Actions + Apps Launcher Meta @@ -85,9 +85,9 @@ Λ (Reverse) Bottom right -> top mid -> bottom left - Volume Up Key + Volume Up Press the volume up button - Volume Down Key + Volume Down Press the volume down button Double Click Double click an empty area @@ -101,6 +101,8 @@ Choose App + View all apps + Install apps Store not found @@ -146,6 +148,7 @@ Flip date and time Choose a wallpaper + Change wallpaper Display @@ -190,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? @@ -199,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 @@ -237,10 +240,13 @@ Show Rename + Removed the selected application + Unable to remove application + Search Search (no auto launch) - μLauncher Settings + µLauncher Settings All Applications Favorite Applications Private Space @@ -251,16 +257,15 @@ Music: Next Music: Previous Music: Play / Pause - Expand Notifications Panel - Recent Apps - Do Nothing + Expand notifications panel + Do nothing Lock Screen Toggle Torch - Launch Other Home Screen Add Shortcut Bind to gesture + Ok Show in app list Tutorial - 👋\n\nTake a few seconds to learn how to use this Launcher! + Take a few seconds to learn how to use this Launcher! Concept - μ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 + 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! Usage Your home screen contains the local date and time. No distraction. - 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. - + You can launch your apps with a single swipe or button press. Choose some in the next slide. 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!\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) + 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) Start @@ -303,35 +301,28 @@ 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. Error: Can\'t access torch. Error: Failed to lock screen. (If you just upgraded the app, try to disable and re-enable the accessibility service in phone settings) - Error: Failed to show recent apps. (If you just upgraded the app, try to disable and re-enable the accessibility service in phone settings) - Error: Failed to enable the accessibility service. μLauncher\'s accessibility service is not enabled. Please enable it in settings Private space locked Private space unlocked Private space is not available - μLauncher needs to be the default home screen to access private space. + µ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 + µLauncher - lock screen - Setting μLauncher as an accessibility service allows it to lock the screen and open the recent apps menu. + 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 performing the following actions when requested by the user: + µLauncher will use the accessibility service only for locking the screen. You can check the source code to make sure. - * 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. + 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. @@ -349,7 +340,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,23 +354,20 @@ Use Accessibility Service Use Device Admin Choose method for locking the screen + Ok Rename %1$s Red Alpha Blue Green + 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 perform the following actions: -
    -
  • Lock Screen
  • -
  • Recent Apps
  • -
- μ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 diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 20ccb67..5ca2a9e 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -105,6 +105,17 @@ serif + + + + + diff --git a/build.gradle b/build.gradle index 57dd74a..1697c36 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ buildscript { ext.kotlin_version = '2.0.0' - ext.android_plugin_version = '8.9.1' + ext.android_plugin_version = '8.8.1' repositories { google() mavenCentral() @@ -10,7 +10,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:8.9.1' + classpath 'com.android.tools.build:gradle:8.8.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" diff --git a/docs/launcher.md b/docs/launcher.md index cb290a0..37b24a4 100644 --- a/docs/launcher.md +++ b/docs/launcher.md @@ -47,4 +47,3 @@ 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/fastlane/metadata/android/en-US/changelogs/41.txt b/fastlane/metadata/android/en-US/changelogs/41.txt deleted file mode 100644 index 4458a89..0000000 --- a/fastlane/metadata/android/en-US/changelogs/41.txt +++ /dev/null @@ -1,5 +0,0 @@ - * 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 diff --git a/fastlane/metadata/android/en-US/changelogs/42.txt b/fastlane/metadata/android/en-US/changelogs/42.txt deleted file mode 100644 index 39011cf..0000000 --- a/fastlane/metadata/android/en-US/changelogs/42.txt +++ /dev/null @@ -1 +0,0 @@ -* Fixed bug where keyboard does not open automatically diff --git a/fastlane/metadata/android/en-US/changelogs/43.txt b/fastlane/metadata/android/en-US/changelogs/43.txt deleted file mode 100644 index 2bca600..0000000 --- a/fastlane/metadata/android/en-US/changelogs/43.txt +++ /dev/null @@ -1 +0,0 @@ -* Fixed gesture detection in landscape orientation diff --git a/fastlane/metadata/android/en-US/changelogs/44.txt b/fastlane/metadata/android/en-US/changelogs/44.txt deleted file mode 100644 index 6c6c4f7..0000000 --- a/fastlane/metadata/android/en-US/changelogs/44.txt +++ /dev/null @@ -1,11 +0,0 @@ -* 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!) - diff --git a/fastlane/metadata/android/ja-JP/full_description.txt b/fastlane/metadata/android/ja-JP/full_description.txt deleted file mode 100644 index 7d7e6bf..0000000 --- a/fastlane/metadata/android/ja-JP/full_description.txt +++ /dev/null @@ -1,22 +0,0 @@ -µLauncherは、スワイプジェスチャとタップだけでアプリを起動できるホーム画面です。 -必要最小限で、効率的で、気が散らない。 - -ホーム画面には日付、時刻、壁紙のみが表示されます。 -戻るを押すか上にスワイプすると(これは設定可能)、 -インストールされているすべてのアプリのリストが開き、効率的に検索できます。 - - -このアプリは、Finn M Glas氏のアプリ Launcher のフォークです。 - -機能: -* 35種のジェスチャーにアクションを設定できます。 -* アクションは以下のいずれかになります: - - アプリを起動 - - アプリを表示 - - お気に入りのアプリを表示 - - ボリュームを上げる/下げる - - 音楽: 次/前の曲 - - 画面をロック - - ライトの切り替え - - 通知 / クイック設定を表示 -* 仕事用プロファイルに対応しているので、Shelterなどのアプリも使えます。 diff --git a/fastlane/metadata/android/ja-JP/short_description.txt b/fastlane/metadata/android/ja-JP/short_description.txt deleted file mode 100644 index 58b8c41..0000000 --- a/fastlane/metadata/android/ja-JP/short_description.txt +++ /dev/null @@ -1 +0,0 @@ -気が散らない、最小限の Android ホーム画面。 diff --git a/fastlane/metadata/android/ja-JP/title.txt b/fastlane/metadata/android/ja-JP/title.txt deleted file mode 100644 index 4305604..0000000 --- a/fastlane/metadata/android/ja-JP/title.txt +++ /dev/null @@ -1 +0,0 @@ -µLauncher diff --git a/fastlane/metadata/android/zh-CN/full_description.txt b/fastlane/metadata/android/zh-CN/full_description.txt index 89025a5..b4defca 100644 --- a/fastlane/metadata/android/zh-CN/full_description.txt +++ b/fastlane/metadata/android/zh-CN/full_description.txt @@ -1,21 +1,19 @@ -µLauncher 是桌面启动器程序,允许您使用各种滑动手势和按下按钮来启动其他应用。 -它是简约、高效且无干扰的。 +µLauncher 是主屏幕启动程序,允许您使用滑动手势和按下按钮来启动其他应用。 +它是最小、高效且无干扰。 -您的桌面仅显示日期、时间和壁纸。 -按返回按键或向上滑动(可自定义其他手势)即可打开 -应用程序列表,且支持高效地搜索。 +您的主屏幕仅显示日期、时间和壁纸。 +按返回或向上滑动(可以配置)打开 +所有已安装应用的列表,可以高效地搜索。 -本启动器是基于 Finn M Glas 开发的 Launcher 启动器 的一个派生应用程序。 +这是 Finn M Glas 的应用 Launcher 的一个 fork。 -功能: -* 您可以设定 35 个不同的手势操作。如: - - 启动一个应用程序 - - 打开应用程序列表 - - 打开收藏的应用程序列表 - - 调整音量 - - 快速切换 上一首/下一首 音乐 - - 锁定屏幕 - - 开启/关闭 手机闪光灯 - - 展开通知栏 / 快捷设定栏 -* 兼容工作空间配置,因此支持使用 Shelter 等应用。 +显著变化: +* 边缘手势:可分为屏幕边缘滑动和中心滑动的设置。 +* 与工作配置文件兼容,因此可以使用 Shelter 等应用。 +* 此应用使用系统壁纸而不是自定义解决方案。 +* 字体已更改为 Hack。 +* Material 图标所取代了 Font Awesome 图标。 +* 移除了主屏幕上的齿轮按钮。按返回按钮会打开应用列表,可以从那里访问应用设置。 +* 搜索算法已修改为优先匹配应用名称开头的内容,即当搜索“te”时,“termux”会排在“notes”之前。 +* 搜索栏已移动到屏幕底部 diff --git a/fastlane/metadata/android/zh-CN/short_description.txt b/fastlane/metadata/android/zh-CN/short_description.txt index 66d4684..d49c27c 100644 --- a/fastlane/metadata/android/zh-CN/short_description.txt +++ b/fastlane/metadata/android/zh-CN/short_description.txt @@ -1 +1 @@ -无干扰的简约风格启动器。 +无干扰的最小主屏幕应用启动器。 diff --git a/gradle.properties b/gradle.properties index 4093087..519dc7f 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=true -android.nonFinalResIds=true +android.nonTransitiveRClass=false +android.nonFinalResIds=false org.gradle.configuration-cache=true diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e2847c8..df97d72 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.11.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME