mirror of
https://github.com/jrpie/Launcher.git
synced 2025-04-04 19:34:30 +02:00
Compare commits
9 commits
bafd1ff4f8
...
15543b2b9c
Author | SHA1 | Date | |
---|---|---|---|
![]() |
15543b2b9c | ||
![]() |
e6fca45d48 | ||
![]() |
8501e85f2d | ||
![]() |
f8d943904a | ||
![]() |
09f944ec42 | ||
![]() |
91b0c50f83 | ||
![]() |
ef47a8d305 | ||
9c5500aa83 | |||
d69e3caf71 |
33 changed files with 380 additions and 130 deletions
|
@ -100,7 +100,7 @@ dependencies {
|
|||
implementation 'androidx.constraintlayout:constraintlayout:2.2.0'
|
||||
implementation 'androidx.gridlayout:gridlayout:1.0.0'
|
||||
implementation 'androidx.palette:palette-ktx:1.0.0'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.3.2'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.4.0'
|
||||
implementation 'androidx.preference:preference-ktx:1.2.1'
|
||||
implementation 'com.google.android.material:material:1.12.0'
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")
|
||||
|
|
|
@ -17,12 +17,14 @@ import androidx.preference.PreferenceManager
|
|||
import de.jrpie.android.launcher.actions.TorchManager
|
||||
import de.jrpie.android.launcher.apps.AppInfo
|
||||
import de.jrpie.android.launcher.apps.DetailedAppInfo
|
||||
import de.jrpie.android.launcher.apps.isPrivateSpaceLocked
|
||||
import de.jrpie.android.launcher.preferences.LauncherPreferences
|
||||
import de.jrpie.android.launcher.preferences.migratePreferencesToNewVersion
|
||||
import de.jrpie.android.launcher.preferences.resetPreferences
|
||||
|
||||
class Application : android.app.Application() {
|
||||
val apps = MutableLiveData<List<DetailedAppInfo>>()
|
||||
val privateSpaceLocked = MutableLiveData<Boolean>()
|
||||
|
||||
private val profileAvailabilityBroadcastReceiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
|
@ -144,6 +146,7 @@ class Application : android.app.Application() {
|
|||
}
|
||||
|
||||
private fun loadApps() {
|
||||
privateSpaceLocked.postValue(isPrivateSpaceLocked(this))
|
||||
AsyncTask.execute { apps.postValue(getApps(packageManager, applicationContext)) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,8 @@ import de.jrpie.android.launcher.actions.Action
|
|||
import de.jrpie.android.launcher.actions.Gesture
|
||||
import de.jrpie.android.launcher.apps.AppInfo
|
||||
import de.jrpie.android.launcher.apps.DetailedAppInfo
|
||||
import de.jrpie.android.launcher.apps.getPrivateSpaceUser
|
||||
import de.jrpie.android.launcher.apps.isPrivateSpaceSupported
|
||||
import de.jrpie.android.launcher.preferences.LauncherPreferences
|
||||
import de.jrpie.android.launcher.ui.tutorial.TutorialActivity
|
||||
|
||||
|
@ -48,14 +50,15 @@ fun isDefaultHomeScreen(context: Context): Boolean {
|
|||
}
|
||||
|
||||
fun setDefaultHomeScreen(context: Context, checkDefault: Boolean = false) {
|
||||
if (checkDefault && isDefaultHomeScreen(context)) {
|
||||
val isDefault = isDefaultHomeScreen(context)
|
||||
if (checkDefault && isDefault) {
|
||||
// Launcher is already the default home app
|
||||
return
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
|
||||
&& context is Activity
|
||||
&& checkDefault // using role manager only works when µLauncher is not already the default.
|
||||
&& !isDefault // using role manager only works when µLauncher is not already the default.
|
||||
) {
|
||||
val roleManager = context.getSystemService(RoleManager::class.java)
|
||||
context.startActivityForResult(
|
||||
|
@ -78,16 +81,6 @@ fun getUserFromId(userId: Int?, context: Context): UserHandle {
|
|||
return profiles.firstOrNull { it.hashCode() == userId } ?: profiles[0]
|
||||
}
|
||||
|
||||
fun getPrivateSpaceUser(context: Context): UserHandle? {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.VANILLA_ICE_CREAM) {
|
||||
return null
|
||||
}
|
||||
val userManager = context.getSystemService(Context.USER_SERVICE) as UserManager
|
||||
val launcherApps = context.getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps
|
||||
return userManager.userProfiles.firstOrNull { u ->
|
||||
launcherApps.getLauncherUserInfo(u)?.userType == UserManager.USER_TYPE_PROFILE_PRIVATE
|
||||
}
|
||||
}
|
||||
|
||||
fun openInBrowser(url: String, context: Context) {
|
||||
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
|
||||
|
@ -116,6 +109,8 @@ fun getApps(packageManager: PackageManager, context: Context): MutableList<Detai
|
|||
val launcherApps = context.getSystemService(Service.LAUNCHER_APPS_SERVICE) as LauncherApps
|
||||
val userManager = context.getSystemService(Service.USER_SERVICE) as UserManager
|
||||
|
||||
val privateSpaceUser = getPrivateSpaceUser(context)
|
||||
|
||||
// TODO: shortcuts - launcherApps.getShortcuts()
|
||||
val users = userManager.userProfiles
|
||||
for (user in users) {
|
||||
|
@ -127,7 +122,7 @@ fun getApps(packageManager: PackageManager, context: Context): MutableList<Detai
|
|||
continue
|
||||
}
|
||||
// hide apps from private space
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM &&
|
||||
if (isPrivateSpaceSupported() &&
|
||||
launcherApps.getLauncherUserInfo(user)?.userType == UserManager.USER_TYPE_PROFILE_PRIVATE
|
||||
) {
|
||||
continue
|
||||
|
@ -135,7 +130,7 @@ fun getApps(packageManager: PackageManager, context: Context): MutableList<Detai
|
|||
}
|
||||
}
|
||||
launcherApps.getActivityList(null, user).forEach {
|
||||
loadList.add(DetailedAppInfo(it))
|
||||
loadList.add(DetailedAppInfo(it, it.user == privateSpaceUser))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -150,7 +145,8 @@ fun getApps(packageManager: PackageManager, context: Context): MutableList<Detai
|
|||
val detailedAppInfo = DetailedAppInfo(
|
||||
app,
|
||||
ri.loadLabel(packageManager),
|
||||
ri.activityInfo.loadIcon(packageManager)
|
||||
ri.activityInfo.loadIcon(packageManager),
|
||||
false
|
||||
)
|
||||
loadList.add(detailedAppInfo)
|
||||
}
|
||||
|
@ -186,5 +182,5 @@ fun getDeviceInfo(): String {
|
|||
fun copyToClipboard(context: Context, text: String) {
|
||||
val clipboardManager = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||
val clipData = ClipData.newPlainText("Debug Info", text)
|
||||
clipboardManager.setPrimaryClip(clipData);
|
||||
clipboardManager.setPrimaryClip(clipData)
|
||||
}
|
|
@ -273,7 +273,7 @@ enum class Gesture(
|
|||
|
||||
companion object {
|
||||
fun byId(id: String): Gesture? {
|
||||
return Gesture.values().firstOrNull { it.id == id }
|
||||
return Gesture.entries.firstOrNull { it.id == id }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,24 +1,20 @@
|
|||
package de.jrpie.android.launcher.actions
|
||||
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.LauncherApps
|
||||
import android.graphics.Rect
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.media.AudioManager
|
||||
import android.os.Build
|
||||
import android.os.SystemClock
|
||||
import android.os.UserManager
|
||||
import android.provider.Settings
|
||||
import android.view.KeyEvent
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.widget.AppCompatDrawableManager
|
||||
import androidx.appcompat.content.res.AppCompatResources
|
||||
import de.jrpie.android.launcher.Application
|
||||
import de.jrpie.android.launcher.R
|
||||
import de.jrpie.android.launcher.apps.AppFilter
|
||||
import de.jrpie.android.launcher.getPrivateSpaceUser
|
||||
import de.jrpie.android.launcher.isDefaultHomeScreen
|
||||
import de.jrpie.android.launcher.apps.isPrivateSpaceSupported
|
||||
import de.jrpie.android.launcher.apps.togglePrivateSpaceLock
|
||||
import de.jrpie.android.launcher.preferences.LauncherPreferences
|
||||
import de.jrpie.android.launcher.ui.list.ListActivity
|
||||
import de.jrpie.android.launcher.ui.settings.SettingsActivity
|
||||
|
@ -62,15 +58,26 @@ enum class LauncherAction(
|
|||
"choose_from_favorites",
|
||||
R.string.list_other_list_favorites,
|
||||
R.drawable.baseline_favorite_24,
|
||||
{ context -> openAppsList(context, true) },
|
||||
{ context -> openAppsList(context, favorite = true) },
|
||||
true
|
||||
),
|
||||
CHOOSE_FROM_PRIVATE_SPACE(
|
||||
"choose_from_private_space",
|
||||
R.string.list_other_list_private_space,
|
||||
R.drawable.baseline_security_24,
|
||||
{ context ->
|
||||
openAppsList(context, private = true)
|
||||
},
|
||||
available = { _ ->
|
||||
isPrivateSpaceSupported()
|
||||
}
|
||||
),
|
||||
TOGGLE_PRIVATE_SPACE_LOCK(
|
||||
"toggle_private_space_lock",
|
||||
R.string.list_other_toggle_private_space_lock,
|
||||
R.drawable.baseline_security_24,
|
||||
::togglePrivateSpaceLock,
|
||||
available = { Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM }
|
||||
available = { _ -> isPrivateSpaceSupported() }
|
||||
),
|
||||
VOLUME_UP(
|
||||
"volume_up",
|
||||
|
@ -107,7 +114,7 @@ enum class LauncherAction(
|
|||
LOCK_SCREEN(
|
||||
"lock_screen",
|
||||
R.string.list_other_lock_screen,
|
||||
R.drawable.baseline_lock_24px,
|
||||
R.drawable.baseline_lock_24,
|
||||
{ c -> LauncherPreferences.actions().lockMethod().lockOrEnable(c) }
|
||||
),
|
||||
TORCH(
|
||||
|
@ -128,7 +135,7 @@ enum class LauncherAction(
|
|||
}
|
||||
|
||||
override fun getIcon(context: Context): Drawable? {
|
||||
return context.getDrawable(icon)
|
||||
return AppCompatResources.getDrawable(context, icon)
|
||||
}
|
||||
|
||||
override fun isAvailable(context: Context): Boolean {
|
||||
|
@ -230,37 +237,6 @@ private fun expandNotificationsPanel(context: Context) {
|
|||
}
|
||||
}
|
||||
|
||||
private fun togglePrivateSpaceLock(context: Context) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.VANILLA_ICE_CREAM) {
|
||||
Toast.makeText(
|
||||
context,
|
||||
context.getString(R.string.alert_requires_android_v),
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
return
|
||||
}
|
||||
val userManager = context.getSystemService(Context.USER_SERVICE) as UserManager
|
||||
val privateSpaceUser = getPrivateSpaceUser(context)
|
||||
if (privateSpaceUser == null) {
|
||||
Toast.makeText(context, context.getString(R.string.toast_private_space_not_available), Toast.LENGTH_LONG).show()
|
||||
|
||||
if (!isDefaultHomeScreen(context)) {
|
||||
Toast.makeText(context, context.getString(R.string.toast_private_space_default_home_screen), Toast.LENGTH_LONG).show()
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
context.startActivity(Intent(Settings.ACTION_PRIVACY_SETTINGS))
|
||||
} catch (_: ActivityNotFoundException) {}
|
||||
return
|
||||
}
|
||||
if (userManager.isQuietModeEnabled(privateSpaceUser)) {
|
||||
userManager.requestQuietModeEnabled(false, privateSpaceUser)
|
||||
return
|
||||
}
|
||||
userManager.requestQuietModeEnabled(true, privateSpaceUser)
|
||||
Toast.makeText(context, context.getString(R.string.toast_private_space_locked), Toast.LENGTH_LONG).show()
|
||||
}
|
||||
|
||||
private fun expandSettingsPanel(context: Context) {
|
||||
/* https://stackoverflow.com/a/31898506 */
|
||||
|
@ -283,7 +259,12 @@ private fun openSettings(context: Context) {
|
|||
context.startActivity(Intent(context, SettingsActivity::class.java))
|
||||
}
|
||||
|
||||
fun openAppsList(context: Context, favorite: Boolean = false, hidden: Boolean = false) {
|
||||
fun openAppsList(
|
||||
context: Context,
|
||||
favorite: Boolean = false,
|
||||
hidden: Boolean = false,
|
||||
private: Boolean = false
|
||||
) {
|
||||
val intent = Intent(context, ListActivity::class.java)
|
||||
intent.putExtra("intention", ListActivity.ListActivityIntention.VIEW.toString())
|
||||
intent.putExtra(
|
||||
|
@ -302,6 +283,16 @@ fun openAppsList(context: Context, favorite: Boolean = false, hidden: Boolean =
|
|||
AppFilter.Companion.AppSetVisibility.HIDDEN
|
||||
}
|
||||
)
|
||||
intent.putExtra(
|
||||
"privateSpaceVisibility",
|
||||
if (private) {
|
||||
AppFilter.Companion.AppSetVisibility.EXCLUSIVE
|
||||
} else if (!hidden && LauncherPreferences.apps().hidePrivateSpaceApps()) {
|
||||
AppFilter.Companion.AppSetVisibility.HIDDEN
|
||||
} else {
|
||||
AppFilter.Companion.AppSetVisibility.VISIBLE
|
||||
}
|
||||
)
|
||||
|
||||
context.startActivity(intent)
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ class AppFilter(
|
|||
var query: String,
|
||||
var favoritesVisibility: AppSetVisibility = AppSetVisibility.VISIBLE,
|
||||
var hiddenVisibility: AppSetVisibility = AppSetVisibility.HIDDEN,
|
||||
var privateSpaceVisibility: AppSetVisibility = AppSetVisibility.VISIBLE
|
||||
) {
|
||||
|
||||
operator fun invoke(apps: List<DetailedAppInfo>): List<DetailedAppInfo> {
|
||||
|
@ -23,10 +24,12 @@ class AppFilter(
|
|||
|
||||
val hidden = LauncherPreferences.apps().hidden() ?: setOf()
|
||||
val favorites = LauncherPreferences.apps().favorites() ?: setOf()
|
||||
val private = apps.filter { it.isPrivateSpaceApp }.map { it.app }.toSet()
|
||||
|
||||
apps = apps.filter { info ->
|
||||
favoritesVisibility.predicate(favorites, info)
|
||||
&& hiddenVisibility.predicate(hidden, info)
|
||||
&& privateSpaceVisibility.predicate(private, info)
|
||||
}
|
||||
|
||||
if (LauncherPreferences.apps().hideBoundApps()) {
|
||||
|
|
|
@ -9,16 +9,17 @@ import de.jrpie.android.launcher.Application
|
|||
import de.jrpie.android.launcher.preferences.LauncherPreferences
|
||||
|
||||
/**
|
||||
* Stores information used to create [AppsRecyclerAdapter] rows.
|
||||
* Stores information used to create [de.jrpie.android.launcher.ui.list.apps.AppsRecyclerAdapter] rows.
|
||||
*/
|
||||
class DetailedAppInfo(
|
||||
val app: AppInfo,
|
||||
val label: CharSequence,
|
||||
val icon: Drawable,
|
||||
val isPrivateSpaceApp: Boolean,
|
||||
val isSystemApp: Boolean = false,
|
||||
) {
|
||||
|
||||
constructor(activityInfo: LauncherActivityInfo) : this(
|
||||
constructor(activityInfo: LauncherActivityInfo, private: Boolean) : this(
|
||||
AppInfo(
|
||||
activityInfo.applicationInfo.packageName,
|
||||
activityInfo.name,
|
||||
|
@ -26,6 +27,7 @@ class DetailedAppInfo(
|
|||
),
|
||||
activityInfo.label,
|
||||
activityInfo.getBadgedIcon(0),
|
||||
private,
|
||||
activityInfo.applicationInfo.flags.and(ApplicationInfo.FLAG_SYSTEM) != 0
|
||||
)
|
||||
|
||||
|
@ -51,7 +53,9 @@ class DetailedAppInfo(
|
|||
|
||||
companion object {
|
||||
fun fromAppInfo(appInfo: AppInfo, context: Context): DetailedAppInfo? {
|
||||
return appInfo.getLauncherActivityInfo(context)?.let { DetailedAppInfo(it) }
|
||||
return appInfo.getLauncherActivityInfo(context)?.let {
|
||||
DetailedAppInfo(it, it.user == getPrivateSpaceUser(context))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
118
app/src/main/java/de/jrpie/android/launcher/apps/PrivateSpace.kt
Normal file
118
app/src/main/java/de/jrpie/android/launcher/apps/PrivateSpace.kt
Normal file
|
@ -0,0 +1,118 @@
|
|||
package de.jrpie.android.launcher.apps
|
||||
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.LauncherApps
|
||||
import android.os.Build
|
||||
import android.os.UserHandle
|
||||
import android.os.UserManager
|
||||
import android.provider.Settings
|
||||
import android.widget.Toast
|
||||
import de.jrpie.android.launcher.R
|
||||
import de.jrpie.android.launcher.isDefaultHomeScreen
|
||||
import de.jrpie.android.launcher.setDefaultHomeScreen
|
||||
|
||||
|
||||
/*
|
||||
* Checks whether the device supports private space.
|
||||
*/
|
||||
fun isPrivateSpaceSupported(): Boolean {
|
||||
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM
|
||||
}
|
||||
|
||||
fun getPrivateSpaceUser(context: Context): UserHandle? {
|
||||
if (!isPrivateSpaceSupported()) {
|
||||
return null
|
||||
}
|
||||
val userManager = context.getSystemService(Context.USER_SERVICE) as UserManager
|
||||
val launcherApps = context.getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps
|
||||
return userManager.userProfiles.firstOrNull { u ->
|
||||
launcherApps.getLauncherUserInfo(u)?.userType == UserManager.USER_TYPE_PROFILE_PRIVATE
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the user has created a private space and whether µLauncher can access it.
|
||||
*/
|
||||
fun isPrivateSpaceSetUp(
|
||||
context: Context,
|
||||
showToast: Boolean = false,
|
||||
launchSettings: Boolean = false
|
||||
): Boolean {
|
||||
if (!isPrivateSpaceSupported()) {
|
||||
if (showToast) {
|
||||
Toast.makeText(
|
||||
context,
|
||||
context.getString(R.string.alert_requires_android_v),
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
}
|
||||
return false
|
||||
}
|
||||
val privateSpaceUser = getPrivateSpaceUser(context)
|
||||
if (privateSpaceUser != null) {
|
||||
return true
|
||||
}
|
||||
if (!isDefaultHomeScreen(context)) {
|
||||
if (showToast) {
|
||||
Toast.makeText(
|
||||
context,
|
||||
context.getString(R.string.toast_private_space_default_home_screen),
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
}
|
||||
if (launchSettings) {
|
||||
setDefaultHomeScreen(context)
|
||||
}
|
||||
} else {
|
||||
if (showToast) {
|
||||
Toast.makeText(
|
||||
context,
|
||||
context.getString(R.string.toast_private_space_not_available),
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
}
|
||||
if (launchSettings) {
|
||||
try {
|
||||
context.startActivity(Intent(Settings.ACTION_PRIVACY_SETTINGS))
|
||||
} catch (_: ActivityNotFoundException) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun isPrivateSpaceLocked(context: Context): Boolean {
|
||||
if (!isPrivateSpaceSupported()) {
|
||||
return false
|
||||
}
|
||||
val userManager = context.getSystemService(Context.USER_SERVICE) as UserManager
|
||||
val privateSpaceUser = getPrivateSpaceUser(context) ?: return false
|
||||
return userManager.isQuietModeEnabled(privateSpaceUser)
|
||||
}
|
||||
fun lockPrivateSpace(context: Context, lock: Boolean) {
|
||||
if (!isPrivateSpaceSupported()) {
|
||||
return
|
||||
}
|
||||
val userManager = context.getSystemService(Context.USER_SERVICE) as UserManager
|
||||
val privateSpaceUser = getPrivateSpaceUser(context) ?: return
|
||||
userManager.requestQuietModeEnabled(lock, privateSpaceUser)
|
||||
}
|
||||
|
||||
fun togglePrivateSpaceLock(context: Context) {
|
||||
if (!isPrivateSpaceSetUp(context, showToast = true, launchSettings = true)) {
|
||||
return
|
||||
}
|
||||
|
||||
val lock = isPrivateSpaceLocked(context)
|
||||
lockPrivateSpace(context, !lock)
|
||||
if (!lock) {
|
||||
Toast.makeText(
|
||||
context,
|
||||
context.getString(R.string.toast_private_space_locked),
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
|
@ -30,6 +30,7 @@ import eu.jonahbauer.android.preference.annotations.Preferences;
|
|||
@Preference(name = "custom_names", type = HashMap.class, serializer = MapAppInfoStringPreferenceSerializer.class),
|
||||
@Preference(name = "hide_bound_apps", type = boolean.class, defaultValue = "false"),
|
||||
@Preference(name = "hide_paused_apps", type = boolean.class, defaultValue = "false"),
|
||||
@Preference(name = "hide_private_space_apps", type = boolean.class, defaultValue = "false"),
|
||||
}),
|
||||
@PreferenceGroup(name = "list", prefix = "settings_list_", suffix = "_key", value = {
|
||||
@Preference(name = "layout", type = ListLayout.class, defaultValue = "DEFAULT")
|
||||
|
|
|
@ -68,9 +68,9 @@ private fun Action.Companion.legacyFromPreference(id: String): Action? {
|
|||
val actionId = preferences.getString("$id.app", "")!!
|
||||
var u: Int? = preferences.getInt(
|
||||
"$id.user",
|
||||
AppInfo.INVALID_USER
|
||||
INVALID_USER
|
||||
)
|
||||
u = if (u == AppInfo.INVALID_USER) null else u
|
||||
u = if (u == INVALID_USER) null else u
|
||||
|
||||
return Action.legacyFromId(actionId, u)
|
||||
}
|
||||
|
@ -80,9 +80,9 @@ private fun migrateAppInfoStringMap(key: String) {
|
|||
MapAppInfoStringPreferenceSerializer().serialize(
|
||||
preferences.getStringSet(key, setOf())?.mapNotNull { entry ->
|
||||
try {
|
||||
val obj = JSONObject(entry);
|
||||
val obj = JSONObject(entry)
|
||||
val info = AppInfo.legacyDeserialize(obj.getString("key"))
|
||||
val value = obj.getString("value");
|
||||
val value = obj.getString("value")
|
||||
Pair(info, value)
|
||||
} catch (_: JSONException) {
|
||||
null
|
||||
|
|
|
@ -4,7 +4,6 @@ import android.content.Context
|
|||
import android.content.SharedPreferences
|
||||
import android.util.Log
|
||||
import de.jrpie.android.launcher.preferences.LauncherPreferences
|
||||
import de.jrpie.android.launcher.preferences.PREFERENCE_VERSION
|
||||
import de.jrpie.android.launcher.preferences.theme.Background
|
||||
import de.jrpie.android.launcher.preferences.theme.ColorTheme
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ import kotlinx.serialization.json.Json
|
|||
class SetAppInfoPreferenceSerializer :
|
||||
PreferenceSerializer<java.util.Set<AppInfo>?, java.util.Set<java.lang.String>?> {
|
||||
@Throws(PreferenceSerializationException::class)
|
||||
override fun serialize(value: java.util.Set<AppInfo>?): java.util.Set<java.lang.String>? {
|
||||
override fun serialize(value: java.util.Set<AppInfo>?): java.util.Set<java.lang.String> {
|
||||
return value?.map(AppInfo::serialize)?.toHashSet() as java.util.Set<java.lang.String>
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ class SetAppInfoPreferenceSerializer :
|
|||
class MapAppInfoStringPreferenceSerializer :
|
||||
PreferenceSerializer<java.util.HashMap<AppInfo, String>?, java.util.Set<java.lang.String>?> {
|
||||
|
||||
@Serializable()
|
||||
@Serializable
|
||||
private class MapEntry(val key: AppInfo, val value: String)
|
||||
|
||||
@Throws(PreferenceSerializationException::class)
|
||||
|
|
|
@ -216,7 +216,7 @@ class HomeActivity : UIObject, AppCompatActivity(),
|
|||
if (e1 == null) return false
|
||||
|
||||
|
||||
val displayMetrics: DisplayMetrics = DisplayMetrics()
|
||||
val displayMetrics = DisplayMetrics()
|
||||
windowManager.defaultDisplay.getMetrics(displayMetrics)
|
||||
|
||||
val width = displayMetrics.widthPixels
|
||||
|
|
|
@ -11,15 +11,20 @@ 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.isPrivateSpaceLocked
|
||||
import de.jrpie.android.launcher.apps.isPrivateSpaceSetUp
|
||||
import de.jrpie.android.launcher.apps.togglePrivateSpaceLock
|
||||
import de.jrpie.android.launcher.databinding.ListBinding
|
||||
import de.jrpie.android.launcher.preferences.LauncherPreferences
|
||||
import de.jrpie.android.launcher.ui.UIObject
|
||||
|
@ -30,6 +35,8 @@ import de.jrpie.android.launcher.ui.list.other.ListFragmentOther
|
|||
// TODO: Better solution for this intercommunication functionality (used in list-fragments)
|
||||
var intention = ListActivity.ListActivityIntention.VIEW
|
||||
var favoritesVisibility: AppFilter.Companion.AppSetVisibility = AppFilter.Companion.AppSetVisibility.VISIBLE
|
||||
var privateSpaceVisibility: AppFilter.Companion.AppSetVisibility =
|
||||
AppFilter.Companion.AppSetVisibility.VISIBLE
|
||||
var hiddenVisibility: AppFilter.Companion.AppSetVisibility = AppFilter.Companion.AppSetVisibility.HIDDEN
|
||||
var forGesture: String? = null
|
||||
|
||||
|
@ -44,6 +51,30 @@ class ListActivity : AppCompatActivity(), UIObject {
|
|||
private lateinit var binding: ListBinding
|
||||
|
||||
|
||||
private fun updateLockIcon(locked: Boolean) {
|
||||
binding.listLock.setImageDrawable(
|
||||
AppCompatResources.getDrawable(
|
||||
this,
|
||||
if (locked) {
|
||||
R.drawable.baseline_lock_24
|
||||
} else {
|
||||
R.drawable.baseline_lock_open_24
|
||||
}
|
||||
)
|
||||
)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
binding.listLock.tooltipText = getString(
|
||||
if (locked) {
|
||||
R.string.tooltip_unlock_private_space
|
||||
} else {
|
||||
R.string.tooltip_lock_private_space
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
enum class ListActivityIntention(val titleResource: Int) {
|
||||
VIEW(R.string.list_title_view), /* view list of apps */
|
||||
PICK(R.string.list_title_pick) /* choose app or action to associate to a gesture */
|
||||
|
@ -70,8 +101,10 @@ class ListActivity : AppCompatActivity(), UIObject {
|
|||
|
||||
favoritesVisibility = bundle.getSerializable("favoritesVisibility")
|
||||
as? AppFilter.Companion.AppSetVisibility ?: favoritesVisibility
|
||||
privateSpaceVisibility = bundle.getSerializable("privateSpaceVisibility")
|
||||
as? AppFilter.Companion.AppSetVisibility ?: privateSpaceVisibility
|
||||
hiddenVisibility = bundle.getSerializable("hiddenVisibility")
|
||||
as? AppFilter.Companion.AppSetVisibility ?: favoritesVisibility
|
||||
as? AppFilter.Companion.AppSetVisibility ?: hiddenVisibility
|
||||
|
||||
if (intention != ListActivityIntention.VIEW)
|
||||
forGesture = bundle.getString("forGesture")
|
||||
|
@ -86,6 +119,31 @@ class ListActivity : AppCompatActivity(), UIObject {
|
|||
LauncherAction.SETTINGS.launch(this@ListActivity)
|
||||
}
|
||||
|
||||
binding.listLock.visibility =
|
||||
if (intention != ListActivityIntention.VIEW) {
|
||||
View.GONE
|
||||
} else if (!isPrivateSpaceSetUp(this)) {
|
||||
View.GONE
|
||||
} else if (LauncherPreferences.apps().hidePrivateSpaceApps()) {
|
||||
if (privateSpaceVisibility == AppFilter.Companion.AppSetVisibility.EXCLUSIVE) {
|
||||
View.VISIBLE
|
||||
} else {
|
||||
View.GONE
|
||||
}
|
||||
} else {
|
||||
View.VISIBLE
|
||||
}
|
||||
|
||||
if (privateSpaceVisibility == AppFilter.Companion.AppSetVisibility.EXCLUSIVE) {
|
||||
isPrivateSpaceSetUp(this, showToast = true, launchSettings = true)
|
||||
if (isPrivateSpaceLocked(this)) {
|
||||
togglePrivateSpaceLock(this)
|
||||
}
|
||||
}
|
||||
updateLockIcon(isPrivateSpaceLocked(this))
|
||||
|
||||
val privateSpaceLocked = (this.applicationContext as Application).privateSpaceLocked
|
||||
privateSpaceLocked.observe(this) { updateLockIcon(it) }
|
||||
|
||||
// android:windowSoftInputMode="adjustResize" doesn't work in full screen.
|
||||
// workaround from https://stackoverflow.com/a/57623505
|
||||
|
@ -144,6 +202,8 @@ class ListActivity : AppCompatActivity(), UIObject {
|
|||
if (intention == ListActivityIntention.VIEW) {
|
||||
titleResource = if (hiddenVisibility == AppFilter.Companion.AppSetVisibility.EXCLUSIVE) {
|
||||
R.string.list_title_hidden
|
||||
} else if (privateSpaceVisibility == AppFilter.Companion.AppSetVisibility.EXCLUSIVE) {
|
||||
R.string.list_title_private_space
|
||||
} else if (favoritesVisibility == AppFilter.Companion.AppSetVisibility.EXCLUSIVE) {
|
||||
R.string.list_title_favorite
|
||||
} else {
|
||||
|
@ -161,6 +221,12 @@ class ListActivity : AppCompatActivity(), UIObject {
|
|||
|
||||
override fun setOnClicks() {
|
||||
binding.listClose.setOnClickListener { finish() }
|
||||
binding.listLock.setOnClickListener {
|
||||
togglePrivateSpaceLock(this)
|
||||
if (privateSpaceVisibility == AppFilter.Companion.AppSetVisibility.EXCLUSIVE) {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun adjustLayout() {
|
||||
|
|
|
@ -33,7 +33,7 @@ fun AppInfo.openSettings(
|
|||
}
|
||||
|
||||
fun AppInfo.uninstall(activity: android.app.Activity) {
|
||||
val packageName = this.packageName.toString()
|
||||
val packageName = this.packageName
|
||||
val userId = this.user
|
||||
|
||||
Log.i(LOG_TAG, "uninstalling $this")
|
||||
|
|
|
@ -19,6 +19,7 @@ import de.jrpie.android.launcher.ui.list.favoritesVisibility
|
|||
import de.jrpie.android.launcher.ui.list.forGesture
|
||||
import de.jrpie.android.launcher.ui.list.hiddenVisibility
|
||||
import de.jrpie.android.launcher.ui.list.intention
|
||||
import de.jrpie.android.launcher.ui.list.privateSpaceVisibility
|
||||
import de.jrpie.android.launcher.ui.openSoftKeyboard
|
||||
|
||||
|
||||
|
@ -72,6 +73,7 @@ class ListFragmentApps : Fragment(), UIObject {
|
|||
requireContext(),
|
||||
"",
|
||||
favoritesVisibility = favoritesVisibility,
|
||||
privateSpaceVisibility = privateSpaceVisibility,
|
||||
hiddenVisibility = hiddenVisibility
|
||||
),
|
||||
layout = LauncherPreferences.list().layout()
|
||||
|
|
|
@ -45,21 +45,6 @@ class SettingsFragmentMeta : Fragment(), UIObject {
|
|||
super<UIObject>.onStart()
|
||||
}
|
||||
|
||||
// Rate App
|
||||
// Just copied code from https://stackoverflow.com/q/10816757/12787264
|
||||
// that is how we write good software ^^
|
||||
|
||||
private fun rateIntentForUrl(url: String): Intent {
|
||||
val intent = Intent(
|
||||
Intent.ACTION_VIEW,
|
||||
Uri.parse(String.format("%s?id=%s", url, this.requireContext().packageName))
|
||||
)
|
||||
var flags = Intent.FLAG_ACTIVITY_NO_HISTORY or Intent.FLAG_ACTIVITY_MULTIPLE_TASK
|
||||
flags = flags or Intent.FLAG_ACTIVITY_NEW_DOCUMENT
|
||||
intent.addFlags(flags)
|
||||
return intent
|
||||
}
|
||||
|
||||
override fun setOnClicks() {
|
||||
|
||||
binding.settingsMetaButtonViewTutorial.setOnClickListener {
|
||||
|
|
|
@ -21,7 +21,7 @@ class TutorialFragmentConcept : Fragment(), UIObject {
|
|||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
val binding = TutorialConceptBinding.inflate(inflater, container, false)
|
||||
binding = TutorialConceptBinding.inflate(inflater, container, false)
|
||||
binding.tutorialConceptBadgeVersion.text = BuildConfig.VERSION_NAME
|
||||
return binding.root
|
||||
}
|
||||
|
|
10
app/src/main/res/drawable/baseline_lock_open_24.xml
Normal file
10
app/src/main/res/drawable/baseline_lock_open_24.xml
Normal file
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="?android:textColor"
|
||||
android:pathData="M12,17c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM18,8h-1L17,6c0,-2.76 -2.24,-5 -5,-5S7,3.24 7,6h1.9c0,-1.71 1.39,-3.1 3.1,-3.1 1.71,0 3.1,1.39 3.1,3.1v2L6,8c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,10c0,-1.1 -0.9,-2 -2,-2zM18,20L6,20L6,10h12v10z" />
|
||||
</vector>
|
|
@ -32,7 +32,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:contentDescription="@string/settings"
|
||||
android:gravity="center"
|
||||
android:paddingLeft="16sp"
|
||||
|
@ -53,8 +53,8 @@
|
|||
android:text="@string/list_title_pick"
|
||||
android:textAppearance="@style/TextAppearance.Widget.AppCompat.Toolbar.Title"
|
||||
android:textSize="30sp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/list_lock"
|
||||
app:layout_constraintStart_toEndOf="@id/list_settings"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
|
@ -62,7 +62,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:gravity="center"
|
||||
android:includeFontPadding="true"
|
||||
android:paddingLeft="16sp"
|
||||
|
@ -72,6 +72,21 @@
|
|||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
custom:type="solid" />
|
||||
<ImageView
|
||||
android:id="@+id/list_lock"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:includeFontPadding="true"
|
||||
android:paddingLeft="0sp"
|
||||
android:paddingRight="0sp"
|
||||
android:src="@drawable/baseline_lock_24"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/list_close"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
custom:type="solid" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
android:gravity="start|center_horizontal"
|
||||
android:padding="5dp"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:text=""
|
||||
android:textSize="20sp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
|
|
|
@ -22,9 +22,7 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="60sp"
|
||||
android:layout_marginLeft="60sp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:gravity="start"
|
||||
android:text=""
|
||||
android:textSize="20sp"
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
android:id="@+id/settings_close"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:gravity="center"
|
||||
android:includeFontPadding="true"
|
||||
android:paddingLeft="16sp"
|
||||
|
@ -55,7 +55,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:gravity="center"
|
||||
android:includeFontPadding="true"
|
||||
android:paddingLeft="16sp"
|
||||
|
|
|
@ -2,4 +2,5 @@
|
|||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@mipmap/ic_launcher_background"/>
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
||||
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
|
@ -2,4 +2,5 @@
|
|||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@mipmap/ic_launcher_background"/>
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
||||
<monochrome android:drawable="@drawable/ic_launcher_foreground"/>
|
||||
</adaptive-icon>
|
|
@ -4,7 +4,7 @@
|
|||
<string name="settings_launcher_section_appearance">Aspetto</string>
|
||||
<string name="settings_apps_choose">Scegliere l\'applicazione</string>
|
||||
<string name="settings_theme_color_theme">Tema</string>
|
||||
<string name="tutorial_concept_text">Questo launcher è progettato per essere minimale, efficiente e privo di distrazioni.\n\nNon contiene pagamenti, pubblicità o servizi di tracciamento.</string>
|
||||
<string name="tutorial_concept_text">Questo launcher è progettato per essere minimale, efficiente e privo di distrazioni. Non contiene pagamenti, pubblicità o servizi di tracciamento.</string>
|
||||
<string name="settings_theme_color_theme_item_default">Predefinito</string>
|
||||
<string name="settings_apps_hide_bound_apps">Non mostrare applicazioni collegate a gesti nella lista delle app</string>
|
||||
<string name="settings_list_layout_item_text">Testo</string>
|
||||
|
@ -45,11 +45,11 @@
|
|||
<string name="settings_gesture_description_double_down">Scorri verso il basso con due dita</string>
|
||||
<string name="settings_gesture_left">Sinistra</string>
|
||||
<string name="settings_gesture_description_left">Scorrere verso sinistra</string>
|
||||
<string name="settings_gesture_double_left">Doppio a sinistra</string>
|
||||
<string name="settings_gesture_double_left">Due dita verso sinistra</string>
|
||||
<string name="settings_gesture_description_double_left">Scorrere verso sinistra con due dita</string>
|
||||
<string name="settings_gesture_right">Destra</string>
|
||||
<string name="settings_gesture_description_right">Scorri verso destra</string>
|
||||
<string name="settings_gesture_double_right">Doppio a destra</string>
|
||||
<string name="settings_gesture_double_right">Due dita verso destra</string>
|
||||
<string name="settings_gesture_description_double_right">Scorri a destra con due dita</string>
|
||||
<string name="settings_gesture_right_top_edge">Destra (in alto)</string>
|
||||
<string name="settings_gesture_description_right_top_edge">Scorri verso destra sul bordo superiore dello schermo</string>
|
||||
|
@ -125,12 +125,12 @@
|
|||
<string name="tutorial_setup_text">Abbiamo impostato alcune app predefinite per te. Puoi modificarle ora se lo desideri:</string>
|
||||
<string name="tutorial_setup_text_2">Puoi anche cambiare la tua selezione in seguito.</string>
|
||||
<string name="tutorial_finish_title">Iniziamo!</string>
|
||||
<string name="tutorial_finish_text">Sei pronto per iniziare!\n\nSpero questa applicazione ti risulti preziosa!\n\n- Finn (che ha ideato il launcher)\n\t e Josia (che ha aggiunto qualche miglioramento e mantiene il fork μLauncher)</string>
|
||||
<string name="tutorial_finish_text">Sei pronto per iniziare! Spero questa applicazione ti risulti preziosa! - Finn (che ha ideato il launcher)\n \te Josia (che ha aggiunto qualche miglioramento e mantiene il fork μLauncher)</string>
|
||||
<string name="tutorial_finish_button">Inizia</string>
|
||||
<string name="settings">Impostazioni</string>
|
||||
<string name="ic_menu_alt">Altre opzioni</string>
|
||||
<string name="tutorial_usage_text_2">Puoi aprire le tue app facendo scorrere il dito sullo schermo o premendo un pulsante. Configura i gesti nella prossima slide.</string>
|
||||
<string name="alert_cant_expand_status_bar_panel">Errore: impossibile espandere la barra di stato.\nQuesta azione utilizza funzionalità non incluse nelle API Android pubbliche. Sfortunatamente, non sembra funzionare sul tuo dispositivo.</string>
|
||||
<string name="alert_cant_expand_status_bar_panel">Errore: impossibile espandere la barra di stato. Questa azione utilizza funzionalità non incluse nelle API Android pubbliche. Sfortunatamente, non sembra funzionare sul tuo dispositivo.</string>
|
||||
<string name="snackbar_app_hidden">Applicazione nascosta. Puoi renderla nuovamente visibile nelle impostazioni.</string>
|
||||
<string name="toast_device_admin_not_enabled">µLauncher deve essere autorizzato come amministratore del dispositivo per bloccare lo schermo.</string>
|
||||
<string name="device_admin_description">Abilita il blocco dello schermo</string>
|
||||
|
@ -182,7 +182,7 @@
|
|||
<string name="list_app_hidden_remove">Mostra</string>
|
||||
<string name="list_app_rename">Rinomina</string>
|
||||
<string name="list_removed">Le applicazioni selezionate sono state rimosse</string>
|
||||
<string name="list_apps_search_hint">Cerca tra le applicazioni</string>
|
||||
<string name="list_apps_search_hint">Cerca</string>
|
||||
<string name="list_other_settings">Impostazioni μLauncher</string>
|
||||
<string name="list_other_expand_notifications_panel">Espandi il pannello notifiche</string>
|
||||
<string name="list_other_nop">Non fare niente</string>
|
||||
|
@ -191,11 +191,50 @@
|
|||
<string name="tutorial_title">Tutorial</string>
|
||||
<string name="tutorial_start_text">Prenditi qualche secondo per imparare ad usare questo launcher!</string>
|
||||
<string name="tutorial_concept_title">Concetto</string>
|
||||
<string name="tutorial_concept_text_2">L\'app è open source (sotto licenza MIT) e disponibile su GitHub!\n\nVisita il nostro archivio!</string>
|
||||
<string name="tutorial_concept_text_2">L\'app è open source (sotto licenza MIT) e disponibile su GitHub! Visita il nostro archivio!</string>
|
||||
<string name="tutorial_usage_title">Utilizzo</string>
|
||||
<string name="tutorial_usage_text">La schermata principale contiene solo data e ora. Nessuna distrazione.</string>
|
||||
<string name="alert_requires_android_m">Questa funzione richiede Android 6.0 o successivi.</string>
|
||||
<string name="alert_requires_android_m">Questa funzione richiede Android 6 o successivi.</string>
|
||||
<string name="dialog_rename_ok">Ok</string>
|
||||
<string name="dialog_rename_title">Rinomina %1$s</string>
|
||||
<string name="list_not_removed">Impossibile rimuovere l\'applicazione</string>
|
||||
<string name="settings_theme_color_theme_item_dynamic">Dinamico</string>
|
||||
<string name="settings_clock_color">Colore</string>
|
||||
<string name="settings_gesture_double_up">Due dita verso l\'alto</string>
|
||||
<string name="dialog_consent_accessibility_privileges">Sono consapevole che questo concederà privilegi estesi a µLauncher.</string>
|
||||
<string name="dialog_consent_accessibility_consent">Accetto che µLauncher utilizzi il servizio di accessibilità per fornire funzionalità non correlate all\'accessibilità.</string>
|
||||
<string name="dialog_consent_accessibility_data_collection">Accetto che µLauncher non raccolga alcun dato.</string>
|
||||
<string name="settings_apps_hide_paused_apps">Nascondi le app in pausa</string>
|
||||
<string name="list_other_toggle_private_space_lock">Attiva/Disattiva Blocco Spazio Privato</string>
|
||||
<string name="alert_requires_android_v">Questa funzionalità richiede Android 15 o successivi.</string>
|
||||
<string name="dialog_select_color_red">Rosso</string>
|
||||
<string name="dialog_select_color_alpha">Trasparente</string>
|
||||
<string name="dialog_select_color_blue">Blu</string>
|
||||
<string name="dialog_select_color_green">Verde</string>
|
||||
<string name="dialog_select_color_ok">Ok</string>
|
||||
<string name="dialog_select_color_color_hex">Colore</string>
|
||||
<string name="dialog_choose_color_title">Scegli colore</string>
|
||||
<string name="dialog_consent_accessibility_ok">Attiva Servizi di Accessibilità</string>
|
||||
<string name="dialog_consent_accessibility_other_options">Sono consapevole che esistono altre opzioni (utilizzando i privilegi di amministratore del dispositivo o il pulsante di accensione).</string>
|
||||
<string name="dialog_consent_accessibility_title">Attivazione dei Servizi di Accessibilità</string>
|
||||
<string name="settings_functionality_search_web">Cerca su internet</string>
|
||||
<string name="settings_functionality_search_web_summary">Premi invio durante la ricerca nell\'elenco delle app per avviare una ricerca su internet.</string>
|
||||
<string name="list_apps_search_hint_no_auto_launch">Cerca (senza avvio automatico)</string>
|
||||
<string name="settings_meta_licenses">Licenze Open Source</string>
|
||||
<string name="legal_info_title">Licenze Open Source</string>
|
||||
<string name="dialog_report_bug_title">Segnala un bug</string>
|
||||
<string name="dialog_report_bug_info">Grazie per aver contribuito a migliorare µLauncher!\nSi prega di aggiungere le seguenti informazioni alla segnalazione del bug:</string>
|
||||
<string name="dialog_report_bug_button_clipboard">Copia negli appunti</string>
|
||||
<string name="dialog_report_bug_security_info">Non segnalare pubblicamente le vulnerabilità di sicurezza su GitHub, ma utilizza invece:</string>
|
||||
<string name="dialog_cancel">Annulla</string>
|
||||
<string name="settings_functionality_auto_launch_summary">Premi spazio per disabilitare temporaneamente questa funzionalità.</string>
|
||||
<string name="dialog_report_bug_button_security">Segnala una vulnerabilità di sicurezza</string>
|
||||
<string name="dialog_report_bug_create_report">Crea una segnalazione</string>
|
||||
<string name="toast_private_space_locked">Spazio privato bloccato</string>
|
||||
<string name="toast_private_space_unlocked">Spazio privato sbloccato</string>
|
||||
<string name="toast_private_space_not_available">Spazio privato non disponibile</string>
|
||||
<string name="toast_private_space_default_home_screen">µLauncher deve essere la schermata iniziale predefinita per accedere allo spazio privato.</string>
|
||||
<string name="toast_activity_not_found_browser">Impossibile aprire l\'URL: nessun browser trovato.</string>
|
||||
<string name="toast_activity_not_found_search_web">Non è stata trovata un\'applicazione per gestire la ricerca.</string>
|
||||
<string name="dialog_consent_accessibility_text"><![CDATA[Stai per arrivare il servizio di accessibilità. Questo garantirà <strong>privilegi più ampi</strong> a µLauncher.<br/>µLauncher utilizzerà questi privilegi <strong>solo per bloccare lo schermo</strong>. µLauncher <strong>non raccoglierà mai alcun dato</strong>. In particolare, µLauncher non usa il servizio di accessibilità per raccogliere nessun dato.]]></string>
|
||||
</resources>
|
|
@ -30,14 +30,14 @@
|
|||
<string name="settings_gesture_double_left">2 dedos para esquerda</string>
|
||||
<string name="settings_gesture_right">Para direita</string>
|
||||
<string name="settings_gesture_double_right">2 dedos para direita</string>
|
||||
<string name="settings_gesture_right_top_edge">Para direita (No topo)</string>
|
||||
<string name="settings_gesture_right_top_edge">Para direita (no topo)</string>
|
||||
<string name="settings_gesture_right_bottom_edge">Para direita (em baixo)</string>
|
||||
<string name="settings_gesture_left_bottom_edge">Para esquerda (Em baixo)</string>
|
||||
<string name="settings_gesture_left_top_edge">Para esquerda (No topo)</string>
|
||||
<string name="settings_gesture_up_left_edge">Para cima (Borda esquerda)</string>
|
||||
<string name="settings_gesture_up_right_edge">Para cima (Borda direita)</string>
|
||||
<string name="settings_gesture_down_left_edge">Para baixo (Borda esquerda)</string>
|
||||
<string name="settings_gesture_down_right_edge">Para baixo (Borda direita)</string>
|
||||
<string name="settings_gesture_left_bottom_edge">Para esquerda (em baixo)</string>
|
||||
<string name="settings_gesture_left_top_edge">Para esquerda (no topo)</string>
|
||||
<string name="settings_gesture_up_left_edge">Para cima (borda esquerda)</string>
|
||||
<string name="settings_gesture_up_right_edge">Para cima (borda direita)</string>
|
||||
<string name="settings_gesture_down_left_edge">Para baixo (borda esquerda)</string>
|
||||
<string name="settings_gesture_down_right_edge">Para baixo (borda direita)</string>
|
||||
<string name="settings_gesture_vol_up">Aumento de volume</string>
|
||||
<string name="settings_gesture_vol_down">Diminuição de volume</string>
|
||||
<string name="settings_gesture_double_click">Toque duplo</string>
|
||||
|
@ -62,7 +62,7 @@
|
|||
<string name="settings_clock_date_visible">Mostrar Data</string>
|
||||
<string name="settings_clock_localized">Use formato de data localizado</string>
|
||||
<string name="settings_clock_flip_date_time">Inverter data e hora</string>
|
||||
<string name="settings_theme_wallpaper">Escolha um papel de parede</string>
|
||||
<string name="settings_theme_wallpaper">Escolha papel de parede</string>
|
||||
<string name="settings_launcher_change_wallpaper">Alterar papel de parede</string>
|
||||
<string name="settings_launcher_section_display">Exibição</string>
|
||||
<string name="settings_display_screen_timeout_disabled">Manter a tela ligada</string>
|
||||
|
@ -121,11 +121,11 @@
|
|||
<string name="tutorial_concept_text">O Launcher foi criado para ser minimalista, eficiente e livre de distrações. Ele é livre de pagamentos, anúncios e serviços de rastreamento.</string>
|
||||
<string name="tutorial_concept_text_2">O app é de código aberto (licença MIT) e está disponível no GitHub! Não deixe de conferir o repositório!</string>
|
||||
<string name="tutorial_usage_title">Uso</string>
|
||||
<string name="tutorial_usage_text">Sua tela inicial contém a data e hora local. Sem distração.</string>
|
||||
<string name="tutorial_usage_text_2">Você pode iniciar seus aplicativos com um toque único ou pressionando um botão. Escolha algumas ações no próximo slide.</string>
|
||||
<string name="tutorial_usage_text">Sua tela inicial contém a data e hora local. Sem distrações.</string>
|
||||
<string name="tutorial_usage_text_2">Você pode iniciar seus aplicativos com um gesto único ou apertando um botão. Escolha algumas ações no próximo slide.</string>
|
||||
<string name="tutorial_setup_title">Configurar</string>
|
||||
<string name="tutorial_setup_text">Selecionamos alguns aplicativos padrão para você. Se quiser, você pode alterá-los agora:</string>
|
||||
<string name="tutorial_setup_text_2">Você também pode alterar suas escolhas mais tarde.</string>
|
||||
<string name="tutorial_setup_text_2">Você pode alterar suas escolhas mais tarde.</string>
|
||||
<string name="tutorial_finish_title">Vamos lá!</string>
|
||||
<string name="tutorial_finish_text">Tá todo pronto para começar! Espero que isso seja de grande valor para você! - Finn (que criou o Launcher) \te Josia (que fez algumas melhorias e tb mantém o fork do μLauncher)</string>
|
||||
<string name="tutorial_finish_button">Começar</string>
|
||||
|
@ -162,9 +162,9 @@
|
|||
<string name="screen_lock_method_use_accessibility">Usar o Serviço de acessibilidade</string>
|
||||
<string name="screen_lock_method_use_device_admin">Usar o Administrador do dispositivo</string>
|
||||
<string name="screen_lock_method_dialog_title">Escolha um método de bloqueio</string>
|
||||
<string name="settings_actions_lock_method">Escolha um método de bloqueio da tela</string>
|
||||
<string name="settings_actions_lock_method">Escolha método de bloqueio da tela</string>
|
||||
<string name="list_other_expand_settings_panel">Configurações rápidas</string>
|
||||
<string name="alert_requires_android_m">Essa funcionalidade requer o Android 6.0 ou mais recente.</string>
|
||||
<string name="alert_requires_android_m">Essa funcionalidade requer o Android 6 ou mais recente.</string>
|
||||
<string name="alert_no_torch_found">Nenhuma câmera com lanterna detectada.</string>
|
||||
<string name="toast_lock_screen_not_supported">Erro: O bloqueio da tela via Serviço de acessibilidade não é compatível com este aparelho. Tente usar Administrador do dispositivo como método alternativo.</string>
|
||||
<string name="accessibility_service_description">Definindo µLauncher como Serviço de acessibilidade permite a ele bloquear a tela. Considere que é necessário conceder as permissões elevadas. Você nunca deveria autorizar essas permissões a qualquer aplicativo sem avaliação. O µLauncher usará o Serviço de acessibilidade somente para bloquear a tela. Você pode verificar o código-fonte para ter certeza. O bloqueio da tela também pode ser realizado dando ao µLauncher permissões de Administrador do dispositivo. Apesar de que esse método não funciona com impressão digital e desbloqueio facial.</string>
|
||||
|
@ -260,7 +260,7 @@
|
|||
<string name="legal_info_title">Licenças de código aberto</string>
|
||||
<string name="settings_apps_hide_paused_apps">Ocultar apps pausados</string>
|
||||
<string name="list_other_toggle_private_space_lock">Ativar o Espaço privado</string>
|
||||
<string name="alert_requires_android_v">Essa funcionalidade requer o Android 15.0 ou mais recente.</string>
|
||||
<string name="alert_requires_android_v">Essa funcionalidade requer o Android 15 ou mais recente.</string>
|
||||
<string name="toast_private_space_locked">Espaço privado trancado</string>
|
||||
<string name="toast_private_space_unlocked">Espaço privado liberado</string>
|
||||
<string name="toast_private_space_not_available">Espaço privado indisponível</string>
|
||||
|
@ -271,4 +271,9 @@
|
|||
<string name="dialog_report_bug_create_report">Criar relatório</string>
|
||||
<string name="dialog_report_bug_title">Relatar um bug</string>
|
||||
<string name="dialog_report_bug_info">Obrigado por ajudar a melhorar o µLauncher!\nConsidere adicionar as seguintes informações ao relatório de bug:</string>
|
||||
<string name="settings_functionality_auto_launch_summary">Toque no espaço para temporariamente desativar esta funcionalidade.</string>
|
||||
<string name="toast_activity_not_found_browser">Não foi possível abrir a URL: nenhum navegador encontrado.</string>
|
||||
<string name="toast_activity_not_found_search_web">Nenhum app encontrado para efetuar a pesquisa.</string>
|
||||
<string name="settings_gesture_back">Voltar</string>
|
||||
<string name="settings_gesture_description_back">Botão Voltar / gesto de Voltar</string>
|
||||
</resources>
|
|
@ -14,6 +14,7 @@
|
|||
<string name="settings_apps_custom_names_key" translatable="false">apps.custom_names</string>
|
||||
<string name="settings_apps_hide_bound_apps_key" translatable="false">apps.hide_bound_apps</string>
|
||||
<string name="settings_apps_hide_paused_apps_key" translatable="false">apps.hide_paused_apps</string>
|
||||
<string name="settings_apps_hide_private_space_apps_key" translatable="false">apps.hide_private_space_apps</string>
|
||||
<string name="settings_list_layout_key" translatable="false">list.layout</string>
|
||||
<string name="settings_general_choose_home_screen_key" translatable="false">general.select_launcher</string>
|
||||
|
||||
|
|
|
@ -150,6 +150,7 @@
|
|||
<string name="settings_apps_hidden">Hidden apps</string>
|
||||
<string name="settings_apps_hide_bound_apps">Don\'t show apps that are bound to a gesture in the app list</string>
|
||||
<string name="settings_apps_hide_paused_apps">Hide paused apps</string>
|
||||
<string name="settings_apps_hide_private_space_apps">Hide private space from app list</string>
|
||||
<string name="settings_list_layout">Layout of app list</string>
|
||||
|
||||
<string name="settings_list_layout_item_default">Default</string>
|
||||
|
@ -197,6 +198,7 @@
|
|||
<string name="list_title_view">All Apps</string>
|
||||
<string name="list_title_favorite">Favorite Apps</string>
|
||||
<string name="list_title_hidden">Hidden Apps</string>
|
||||
<string name="list_title_private_space">Private Space</string>
|
||||
<string name="list_title_pick">Choose App</string>
|
||||
|
||||
<string name="list_tab_app">Apps</string>
|
||||
|
@ -219,6 +221,7 @@
|
|||
<string name="list_other_settings">µLauncher Settings</string>
|
||||
<string name="list_other_list">All Applications</string>
|
||||
<string name="list_other_list_favorites">Favorite Applications</string>
|
||||
<string name="list_other_list_private_space">Private Space</string>
|
||||
<string name="list_other_toggle_private_space_lock">Toggle Private Space Lock</string>
|
||||
<string name="list_other_volume_up">Music: Louder</string>
|
||||
<string name="list_other_volume_down">Music: Quieter</string>
|
||||
|
@ -273,6 +276,8 @@
|
|||
<string name="toast_private_space_unlocked">Private space unlocked</string>
|
||||
<string name="toast_private_space_not_available">Private space is not available</string>
|
||||
<string name="toast_private_space_default_home_screen">µLauncher needs to be the default home screen to access private space.</string>
|
||||
<string name="tooltip_lock_private_space">Lock private space</string>
|
||||
<string name="tooltip_unlock_private_space">Unlock private space</string>
|
||||
<string name="toast_lock_screen_not_supported">Error: Locking the screen using accessibility is not supported on this device. Please use device admin instead.</string>
|
||||
<string name="accessibility_service_name">µLauncher - lock screen</string>
|
||||
<string name="accessibility_service_description">
|
||||
|
|
|
@ -151,6 +151,11 @@
|
|||
android:title="@string/settings_apps_hide_paused_apps"
|
||||
android:defaultValue="false" />
|
||||
|
||||
<SwitchPreference
|
||||
android:key="@string/settings_apps_hide_private_space_apps_key"
|
||||
android:title="@string/settings_apps_hide_private_space_apps"
|
||||
android:defaultValue="false" />
|
||||
|
||||
<DropDownPreference
|
||||
android:key="@string/settings_list_layout_key"
|
||||
android:title="@string/settings_list_layout"
|
||||
|
|
1
fastlane/metadata/android/de-DE/title.txt
Normal file
1
fastlane/metadata/android/de-DE/title.txt
Normal file
|
@ -0,0 +1 @@
|
|||
µLauncher
|
|
@ -1,23 +1,23 @@
|
|||
O µLauncher é uma tela inicial que permite abrir aplicativos através gestos de deslize e botões físicos.
|
||||
O µLauncher é uma tela inicial que permite abrir apps através de gestos e botões físicos.
|
||||
O launcher é minimalista, eficiente e livre de distrações.
|
||||
|
||||
Sua tela inicial exibe apenas a data, hora e papel de parede.
|
||||
A tela inicial mostra apenas a data, hora e papel de parede.
|
||||
|
||||
Ao usar Voltar ou deslize para cima (pode ser configurado depois) você abre a lista
|
||||
com todos os aplicativos instalados, que podem ser encontrados rápido.
|
||||
Ao usar botão Voltar ou gesto pra cima (pode ser redefinido depois)
|
||||
você abre com facilidade e rapidez a lista com todos os apps instalados.
|
||||
|
||||
Esta é uma modificação do app <a href="https://f-droid.org/packages/com.finnmglas.launcher/">Launcher</a>
|
||||
feita por Finn M Glas.
|
||||
O app é uma modificação do <a href="https://f-droid.org/packages/com.finnmglas.launcher/">Launcher</a>
|
||||
feito por Finn M Glas.
|
||||
|
||||
Funcionalidades:
|
||||
* Você pode associar várias ações a 22 gestos diferentes.
|
||||
* Também pode definir algumas das seguintes acções:
|
||||
- Iniciar algum app
|
||||
* Pode definir algumas das seguintes ações:
|
||||
- Iniciar vários apps
|
||||
- Listar todos aplicativos
|
||||
- Listar apps favoritos
|
||||
- Aumentar / diminuir o volume
|
||||
- Música: faixa anterior / seguinte
|
||||
- Música: passar pra faixa anterior / seguinte
|
||||
- Bloquear a tela
|
||||
- Ligar a lanterna
|
||||
- Mostrar notificações / configurações rápidas
|
||||
* Compatível com Perfil de trabalho, desta forma apps como Shelter podem ser usados.
|
||||
* App é compatível com Perfil de trabalho e pode ser usado com apps tipo Shelter.
|
||||
|
|
Loading…
Add table
Reference in a new issue