mirror of
https://github.com/jrpie/Launcher.git
synced 2025-04-12 15:24:31 +02:00
Compare commits
10 commits
6435932651
...
08bf23da18
Author | SHA1 | Date | |
---|---|---|---|
![]() |
08bf23da18 | ||
![]() |
15543b2b9c | ||
![]() |
e6fca45d48 | ||
![]() |
8501e85f2d | ||
![]() |
f8d943904a | ||
![]() |
09f944ec42 | ||
![]() |
91b0c50f83 | ||
![]() |
ef47a8d305 | ||
9c5500aa83 | |||
d69e3caf71 |
30 changed files with 312 additions and 107 deletions
|
@ -100,7 +100,7 @@ dependencies {
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:2.2.0'
|
implementation 'androidx.constraintlayout:constraintlayout:2.2.0'
|
||||||
implementation 'androidx.gridlayout:gridlayout:1.0.0'
|
implementation 'androidx.gridlayout:gridlayout:1.0.0'
|
||||||
implementation 'androidx.palette:palette-ktx: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 'androidx.preference:preference-ktx:1.2.1'
|
||||||
implementation 'com.google.android.material:material:1.12.0'
|
implementation 'com.google.android.material:material:1.12.0'
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")
|
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.actions.TorchManager
|
||||||
import de.jrpie.android.launcher.apps.AppInfo
|
import de.jrpie.android.launcher.apps.AppInfo
|
||||||
import de.jrpie.android.launcher.apps.DetailedAppInfo
|
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.LauncherPreferences
|
||||||
import de.jrpie.android.launcher.preferences.migratePreferencesToNewVersion
|
import de.jrpie.android.launcher.preferences.migratePreferencesToNewVersion
|
||||||
import de.jrpie.android.launcher.preferences.resetPreferences
|
import de.jrpie.android.launcher.preferences.resetPreferences
|
||||||
|
|
||||||
class Application : android.app.Application() {
|
class Application : android.app.Application() {
|
||||||
val apps = MutableLiveData<List<DetailedAppInfo>>()
|
val apps = MutableLiveData<List<DetailedAppInfo>>()
|
||||||
|
val privateSpaceLocked = MutableLiveData<Boolean>()
|
||||||
|
|
||||||
private val profileAvailabilityBroadcastReceiver = object : BroadcastReceiver() {
|
private val profileAvailabilityBroadcastReceiver = object : BroadcastReceiver() {
|
||||||
override fun onReceive(context: Context?, intent: Intent?) {
|
override fun onReceive(context: Context?, intent: Intent?) {
|
||||||
|
@ -144,6 +146,7 @@ class Application : android.app.Application() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadApps() {
|
private fun loadApps() {
|
||||||
|
privateSpaceLocked.postValue(isPrivateSpaceLocked(this))
|
||||||
AsyncTask.execute { apps.postValue(getApps(packageManager, applicationContext)) }
|
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.actions.Gesture
|
||||||
import de.jrpie.android.launcher.apps.AppInfo
|
import de.jrpie.android.launcher.apps.AppInfo
|
||||||
import de.jrpie.android.launcher.apps.DetailedAppInfo
|
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.preferences.LauncherPreferences
|
||||||
import de.jrpie.android.launcher.ui.tutorial.TutorialActivity
|
import de.jrpie.android.launcher.ui.tutorial.TutorialActivity
|
||||||
|
|
||||||
|
@ -48,14 +50,15 @@ fun isDefaultHomeScreen(context: Context): Boolean {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setDefaultHomeScreen(context: Context, checkDefault: Boolean = false) {
|
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
|
// Launcher is already the default home app
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
|
||||||
&& context is Activity
|
&& 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)
|
val roleManager = context.getSystemService(RoleManager::class.java)
|
||||||
context.startActivityForResult(
|
context.startActivityForResult(
|
||||||
|
@ -78,16 +81,6 @@ fun getUserFromId(userId: Int?, context: Context): UserHandle {
|
||||||
return profiles.firstOrNull { it.hashCode() == userId } ?: profiles[0]
|
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) {
|
fun openInBrowser(url: String, context: Context) {
|
||||||
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
|
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 launcherApps = context.getSystemService(Service.LAUNCHER_APPS_SERVICE) as LauncherApps
|
||||||
val userManager = context.getSystemService(Service.USER_SERVICE) as UserManager
|
val userManager = context.getSystemService(Service.USER_SERVICE) as UserManager
|
||||||
|
|
||||||
|
val privateSpaceUser = getPrivateSpaceUser(context)
|
||||||
|
|
||||||
// TODO: shortcuts - launcherApps.getShortcuts()
|
// TODO: shortcuts - launcherApps.getShortcuts()
|
||||||
val users = userManager.userProfiles
|
val users = userManager.userProfiles
|
||||||
for (user in users) {
|
for (user in users) {
|
||||||
|
@ -127,7 +122,7 @@ fun getApps(packageManager: PackageManager, context: Context): MutableList<Detai
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// hide apps from private space
|
// 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
|
launcherApps.getLauncherUserInfo(user)?.userType == UserManager.USER_TYPE_PROFILE_PRIVATE
|
||||||
) {
|
) {
|
||||||
continue
|
continue
|
||||||
|
@ -135,7 +130,7 @@ fun getApps(packageManager: PackageManager, context: Context): MutableList<Detai
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
launcherApps.getActivityList(null, user).forEach {
|
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(
|
val detailedAppInfo = DetailedAppInfo(
|
||||||
app,
|
app,
|
||||||
ri.loadLabel(packageManager),
|
ri.loadLabel(packageManager),
|
||||||
ri.activityInfo.loadIcon(packageManager)
|
ri.activityInfo.loadIcon(packageManager),
|
||||||
|
false
|
||||||
)
|
)
|
||||||
loadList.add(detailedAppInfo)
|
loadList.add(detailedAppInfo)
|
||||||
}
|
}
|
||||||
|
@ -186,5 +182,5 @@ fun getDeviceInfo(): String {
|
||||||
fun copyToClipboard(context: Context, text: String) {
|
fun copyToClipboard(context: Context, text: String) {
|
||||||
val clipboardManager = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
val clipboardManager = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||||
val clipData = ClipData.newPlainText("Debug Info", text)
|
val clipData = ClipData.newPlainText("Debug Info", text)
|
||||||
clipboardManager.setPrimaryClip(clipData);
|
clipboardManager.setPrimaryClip(clipData)
|
||||||
}
|
}
|
|
@ -273,7 +273,7 @@ enum class Gesture(
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun byId(id: String): Gesture? {
|
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
|
package de.jrpie.android.launcher.actions
|
||||||
|
|
||||||
import android.content.ActivityNotFoundException
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.LauncherApps
|
|
||||||
import android.graphics.Rect
|
import android.graphics.Rect
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.media.AudioManager
|
import android.media.AudioManager
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.SystemClock
|
import android.os.SystemClock
|
||||||
import android.os.UserManager
|
|
||||||
import android.provider.Settings
|
|
||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
import android.widget.Toast
|
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.Application
|
||||||
import de.jrpie.android.launcher.R
|
import de.jrpie.android.launcher.R
|
||||||
import de.jrpie.android.launcher.apps.AppFilter
|
import de.jrpie.android.launcher.apps.AppFilter
|
||||||
import de.jrpie.android.launcher.getPrivateSpaceUser
|
import de.jrpie.android.launcher.apps.isPrivateSpaceSupported
|
||||||
import de.jrpie.android.launcher.isDefaultHomeScreen
|
import de.jrpie.android.launcher.apps.togglePrivateSpaceLock
|
||||||
import de.jrpie.android.launcher.preferences.LauncherPreferences
|
import de.jrpie.android.launcher.preferences.LauncherPreferences
|
||||||
import de.jrpie.android.launcher.ui.list.ListActivity
|
import de.jrpie.android.launcher.ui.list.ListActivity
|
||||||
import de.jrpie.android.launcher.ui.settings.SettingsActivity
|
import de.jrpie.android.launcher.ui.settings.SettingsActivity
|
||||||
|
@ -62,15 +58,26 @@ enum class LauncherAction(
|
||||||
"choose_from_favorites",
|
"choose_from_favorites",
|
||||||
R.string.list_other_list_favorites,
|
R.string.list_other_list_favorites,
|
||||||
R.drawable.baseline_favorite_24,
|
R.drawable.baseline_favorite_24,
|
||||||
{ context -> openAppsList(context, true) },
|
{ context -> openAppsList(context, favorite = true) },
|
||||||
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(
|
||||||
"toggle_private_space_lock",
|
"toggle_private_space_lock",
|
||||||
R.string.list_other_toggle_private_space_lock,
|
R.string.list_other_toggle_private_space_lock,
|
||||||
R.drawable.baseline_security_24,
|
R.drawable.baseline_security_24,
|
||||||
::togglePrivateSpaceLock,
|
::togglePrivateSpaceLock,
|
||||||
available = { Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM }
|
available = { _ -> isPrivateSpaceSupported() }
|
||||||
),
|
),
|
||||||
VOLUME_UP(
|
VOLUME_UP(
|
||||||
"volume_up",
|
"volume_up",
|
||||||
|
@ -107,7 +114,7 @@ enum class LauncherAction(
|
||||||
LOCK_SCREEN(
|
LOCK_SCREEN(
|
||||||
"lock_screen",
|
"lock_screen",
|
||||||
R.string.list_other_lock_screen,
|
R.string.list_other_lock_screen,
|
||||||
R.drawable.baseline_lock_24px,
|
R.drawable.baseline_lock_24,
|
||||||
{ c -> LauncherPreferences.actions().lockMethod().lockOrEnable(c) }
|
{ c -> LauncherPreferences.actions().lockMethod().lockOrEnable(c) }
|
||||||
),
|
),
|
||||||
TORCH(
|
TORCH(
|
||||||
|
@ -128,7 +135,7 @@ enum class LauncherAction(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getIcon(context: Context): Drawable? {
|
override fun getIcon(context: Context): Drawable? {
|
||||||
return context.getDrawable(icon)
|
return AppCompatResources.getDrawable(context, icon)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isAvailable(context: Context): Boolean {
|
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) {
|
private fun expandSettingsPanel(context: Context) {
|
||||||
/* https://stackoverflow.com/a/31898506 */
|
/* https://stackoverflow.com/a/31898506 */
|
||||||
|
@ -283,7 +259,12 @@ private fun openSettings(context: Context) {
|
||||||
context.startActivity(Intent(context, SettingsActivity::class.java))
|
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)
|
val intent = Intent(context, ListActivity::class.java)
|
||||||
intent.putExtra("intention", ListActivity.ListActivityIntention.VIEW.toString())
|
intent.putExtra("intention", ListActivity.ListActivityIntention.VIEW.toString())
|
||||||
intent.putExtra(
|
intent.putExtra(
|
||||||
|
@ -302,6 +283,16 @@ fun openAppsList(context: Context, favorite: Boolean = false, hidden: Boolean =
|
||||||
AppFilter.Companion.AppSetVisibility.HIDDEN
|
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)
|
context.startActivity(intent)
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ class AppFilter(
|
||||||
var query: String,
|
var query: String,
|
||||||
var favoritesVisibility: AppSetVisibility = AppSetVisibility.VISIBLE,
|
var favoritesVisibility: AppSetVisibility = AppSetVisibility.VISIBLE,
|
||||||
var hiddenVisibility: AppSetVisibility = AppSetVisibility.HIDDEN,
|
var hiddenVisibility: AppSetVisibility = AppSetVisibility.HIDDEN,
|
||||||
|
var privateSpaceVisibility: AppSetVisibility = AppSetVisibility.VISIBLE
|
||||||
) {
|
) {
|
||||||
|
|
||||||
operator fun invoke(apps: List<DetailedAppInfo>): List<DetailedAppInfo> {
|
operator fun invoke(apps: List<DetailedAppInfo>): List<DetailedAppInfo> {
|
||||||
|
@ -23,10 +24,12 @@ class AppFilter(
|
||||||
|
|
||||||
val hidden = LauncherPreferences.apps().hidden() ?: setOf()
|
val hidden = LauncherPreferences.apps().hidden() ?: setOf()
|
||||||
val favorites = LauncherPreferences.apps().favorites() ?: setOf()
|
val favorites = LauncherPreferences.apps().favorites() ?: setOf()
|
||||||
|
val private = apps.filter { it.isPrivateSpaceApp }.map { it.app }.toSet()
|
||||||
|
|
||||||
apps = apps.filter { info ->
|
apps = apps.filter { info ->
|
||||||
favoritesVisibility.predicate(favorites, info)
|
favoritesVisibility.predicate(favorites, info)
|
||||||
&& hiddenVisibility.predicate(hidden, info)
|
&& hiddenVisibility.predicate(hidden, info)
|
||||||
|
&& privateSpaceVisibility.predicate(private, info)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LauncherPreferences.apps().hideBoundApps()) {
|
if (LauncherPreferences.apps().hideBoundApps()) {
|
||||||
|
|
|
@ -9,16 +9,17 @@ import de.jrpie.android.launcher.Application
|
||||||
import de.jrpie.android.launcher.preferences.LauncherPreferences
|
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(
|
class DetailedAppInfo(
|
||||||
val app: AppInfo,
|
val app: AppInfo,
|
||||||
val label: CharSequence,
|
val label: CharSequence,
|
||||||
val icon: Drawable,
|
val icon: Drawable,
|
||||||
|
val isPrivateSpaceApp: Boolean,
|
||||||
val isSystemApp: Boolean = false,
|
val isSystemApp: Boolean = false,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
constructor(activityInfo: LauncherActivityInfo) : this(
|
constructor(activityInfo: LauncherActivityInfo, private: Boolean) : this(
|
||||||
AppInfo(
|
AppInfo(
|
||||||
activityInfo.applicationInfo.packageName,
|
activityInfo.applicationInfo.packageName,
|
||||||
activityInfo.name,
|
activityInfo.name,
|
||||||
|
@ -26,6 +27,7 @@ class DetailedAppInfo(
|
||||||
),
|
),
|
||||||
activityInfo.label,
|
activityInfo.label,
|
||||||
activityInfo.getBadgedIcon(0),
|
activityInfo.getBadgedIcon(0),
|
||||||
|
private,
|
||||||
activityInfo.applicationInfo.flags.and(ApplicationInfo.FLAG_SYSTEM) != 0
|
activityInfo.applicationInfo.flags.and(ApplicationInfo.FLAG_SYSTEM) != 0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -51,7 +53,9 @@ class DetailedAppInfo(
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun fromAppInfo(appInfo: AppInfo, context: Context): DetailedAppInfo? {
|
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 = "custom_names", type = HashMap.class, serializer = MapAppInfoStringPreferenceSerializer.class),
|
||||||
@Preference(name = "hide_bound_apps", type = boolean.class, defaultValue = "false"),
|
@Preference(name = "hide_bound_apps", type = boolean.class, defaultValue = "false"),
|
||||||
@Preference(name = "hide_paused_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 = {
|
@PreferenceGroup(name = "list", prefix = "settings_list_", suffix = "_key", value = {
|
||||||
@Preference(name = "layout", type = ListLayout.class, defaultValue = "DEFAULT")
|
@Preference(name = "layout", type = ListLayout.class, defaultValue = "DEFAULT")
|
||||||
|
|
|
@ -68,9 +68,9 @@ private fun Action.Companion.legacyFromPreference(id: String): Action? {
|
||||||
val actionId = preferences.getString("$id.app", "")!!
|
val actionId = preferences.getString("$id.app", "")!!
|
||||||
var u: Int? = preferences.getInt(
|
var u: Int? = preferences.getInt(
|
||||||
"$id.user",
|
"$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)
|
return Action.legacyFromId(actionId, u)
|
||||||
}
|
}
|
||||||
|
@ -80,9 +80,9 @@ private fun migrateAppInfoStringMap(key: String) {
|
||||||
MapAppInfoStringPreferenceSerializer().serialize(
|
MapAppInfoStringPreferenceSerializer().serialize(
|
||||||
preferences.getStringSet(key, setOf())?.mapNotNull { entry ->
|
preferences.getStringSet(key, setOf())?.mapNotNull { entry ->
|
||||||
try {
|
try {
|
||||||
val obj = JSONObject(entry);
|
val obj = JSONObject(entry)
|
||||||
val info = AppInfo.legacyDeserialize(obj.getString("key"))
|
val info = AppInfo.legacyDeserialize(obj.getString("key"))
|
||||||
val value = obj.getString("value");
|
val value = obj.getString("value")
|
||||||
Pair(info, value)
|
Pair(info, value)
|
||||||
} catch (_: JSONException) {
|
} catch (_: JSONException) {
|
||||||
null
|
null
|
||||||
|
|
|
@ -4,7 +4,6 @@ import android.content.Context
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import de.jrpie.android.launcher.preferences.LauncherPreferences
|
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.Background
|
||||||
import de.jrpie.android.launcher.preferences.theme.ColorTheme
|
import de.jrpie.android.launcher.preferences.theme.ColorTheme
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ import kotlinx.serialization.json.Json
|
||||||
class SetAppInfoPreferenceSerializer :
|
class SetAppInfoPreferenceSerializer :
|
||||||
PreferenceSerializer<java.util.Set<AppInfo>?, java.util.Set<java.lang.String>?> {
|
PreferenceSerializer<java.util.Set<AppInfo>?, java.util.Set<java.lang.String>?> {
|
||||||
@Throws(PreferenceSerializationException::class)
|
@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>
|
return value?.map(AppInfo::serialize)?.toHashSet() as java.util.Set<java.lang.String>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ class SetAppInfoPreferenceSerializer :
|
||||||
class MapAppInfoStringPreferenceSerializer :
|
class MapAppInfoStringPreferenceSerializer :
|
||||||
PreferenceSerializer<java.util.HashMap<AppInfo, String>?, java.util.Set<java.lang.String>?> {
|
PreferenceSerializer<java.util.HashMap<AppInfo, String>?, java.util.Set<java.lang.String>?> {
|
||||||
|
|
||||||
@Serializable()
|
@Serializable
|
||||||
private class MapEntry(val key: AppInfo, val value: String)
|
private class MapEntry(val key: AppInfo, val value: String)
|
||||||
|
|
||||||
@Throws(PreferenceSerializationException::class)
|
@Throws(PreferenceSerializationException::class)
|
||||||
|
|
|
@ -216,7 +216,7 @@ class HomeActivity : UIObject, AppCompatActivity(),
|
||||||
if (e1 == null) return false
|
if (e1 == null) return false
|
||||||
|
|
||||||
|
|
||||||
val displayMetrics: DisplayMetrics = DisplayMetrics()
|
val displayMetrics = DisplayMetrics()
|
||||||
windowManager.defaultDisplay.getMetrics(displayMetrics)
|
windowManager.defaultDisplay.getMetrics(displayMetrics)
|
||||||
|
|
||||||
val width = displayMetrics.widthPixels
|
val width = displayMetrics.widthPixels
|
||||||
|
|
|
@ -11,15 +11,20 @@ import android.view.View
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import android.window.OnBackInvokedDispatcher
|
import android.window.OnBackInvokedDispatcher
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.appcompat.content.res.AppCompatResources
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.FragmentManager
|
import androidx.fragment.app.FragmentManager
|
||||||
import androidx.fragment.app.FragmentPagerAdapter
|
import androidx.fragment.app.FragmentPagerAdapter
|
||||||
import androidx.viewpager.widget.ViewPager
|
import androidx.viewpager.widget.ViewPager
|
||||||
import com.google.android.material.tabs.TabLayout
|
import com.google.android.material.tabs.TabLayout
|
||||||
|
import de.jrpie.android.launcher.Application
|
||||||
import de.jrpie.android.launcher.R
|
import de.jrpie.android.launcher.R
|
||||||
import de.jrpie.android.launcher.REQUEST_UNINSTALL
|
import de.jrpie.android.launcher.REQUEST_UNINSTALL
|
||||||
import de.jrpie.android.launcher.actions.LauncherAction
|
import de.jrpie.android.launcher.actions.LauncherAction
|
||||||
import de.jrpie.android.launcher.apps.AppFilter
|
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.databinding.ListBinding
|
||||||
import de.jrpie.android.launcher.preferences.LauncherPreferences
|
import de.jrpie.android.launcher.preferences.LauncherPreferences
|
||||||
import de.jrpie.android.launcher.ui.UIObject
|
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)
|
// TODO: Better solution for this intercommunication functionality (used in list-fragments)
|
||||||
var intention = ListActivity.ListActivityIntention.VIEW
|
var intention = ListActivity.ListActivityIntention.VIEW
|
||||||
var favoritesVisibility: AppFilter.Companion.AppSetVisibility = AppFilter.Companion.AppSetVisibility.VISIBLE
|
var favoritesVisibility: AppFilter.Companion.AppSetVisibility = AppFilter.Companion.AppSetVisibility.VISIBLE
|
||||||
|
var privateSpaceVisibility: AppFilter.Companion.AppSetVisibility =
|
||||||
|
AppFilter.Companion.AppSetVisibility.VISIBLE
|
||||||
var hiddenVisibility: AppFilter.Companion.AppSetVisibility = AppFilter.Companion.AppSetVisibility.HIDDEN
|
var hiddenVisibility: AppFilter.Companion.AppSetVisibility = AppFilter.Companion.AppSetVisibility.HIDDEN
|
||||||
var forGesture: String? = null
|
var forGesture: String? = null
|
||||||
|
|
||||||
|
@ -44,6 +51,30 @@ class ListActivity : AppCompatActivity(), UIObject {
|
||||||
private lateinit var binding: ListBinding
|
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) {
|
enum class ListActivityIntention(val titleResource: Int) {
|
||||||
VIEW(R.string.list_title_view), /* view list of apps */
|
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 */
|
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")
|
favoritesVisibility = bundle.getSerializable("favoritesVisibility")
|
||||||
as? AppFilter.Companion.AppSetVisibility ?: favoritesVisibility
|
as? AppFilter.Companion.AppSetVisibility ?: favoritesVisibility
|
||||||
|
privateSpaceVisibility = bundle.getSerializable("privateSpaceVisibility")
|
||||||
|
as? AppFilter.Companion.AppSetVisibility ?: privateSpaceVisibility
|
||||||
hiddenVisibility = bundle.getSerializable("hiddenVisibility")
|
hiddenVisibility = bundle.getSerializable("hiddenVisibility")
|
||||||
as? AppFilter.Companion.AppSetVisibility ?: favoritesVisibility
|
as? AppFilter.Companion.AppSetVisibility ?: hiddenVisibility
|
||||||
|
|
||||||
if (intention != ListActivityIntention.VIEW)
|
if (intention != ListActivityIntention.VIEW)
|
||||||
forGesture = bundle.getString("forGesture")
|
forGesture = bundle.getString("forGesture")
|
||||||
|
@ -86,6 +119,31 @@ class ListActivity : AppCompatActivity(), UIObject {
|
||||||
LauncherAction.SETTINGS.launch(this@ListActivity)
|
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.
|
// android:windowSoftInputMode="adjustResize" doesn't work in full screen.
|
||||||
// workaround from https://stackoverflow.com/a/57623505
|
// workaround from https://stackoverflow.com/a/57623505
|
||||||
|
@ -144,6 +202,8 @@ class ListActivity : AppCompatActivity(), UIObject {
|
||||||
if (intention == ListActivityIntention.VIEW) {
|
if (intention == ListActivityIntention.VIEW) {
|
||||||
titleResource = if (hiddenVisibility == AppFilter.Companion.AppSetVisibility.EXCLUSIVE) {
|
titleResource = if (hiddenVisibility == AppFilter.Companion.AppSetVisibility.EXCLUSIVE) {
|
||||||
R.string.list_title_hidden
|
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) {
|
} else if (favoritesVisibility == AppFilter.Companion.AppSetVisibility.EXCLUSIVE) {
|
||||||
R.string.list_title_favorite
|
R.string.list_title_favorite
|
||||||
} else {
|
} else {
|
||||||
|
@ -161,6 +221,12 @@ class ListActivity : AppCompatActivity(), UIObject {
|
||||||
|
|
||||||
override fun setOnClicks() {
|
override fun setOnClicks() {
|
||||||
binding.listClose.setOnClickListener { finish() }
|
binding.listClose.setOnClickListener { finish() }
|
||||||
|
binding.listLock.setOnClickListener {
|
||||||
|
togglePrivateSpaceLock(this)
|
||||||
|
if (privateSpaceVisibility == AppFilter.Companion.AppSetVisibility.EXCLUSIVE) {
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun adjustLayout() {
|
override fun adjustLayout() {
|
||||||
|
|
|
@ -33,7 +33,7 @@ fun AppInfo.openSettings(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun AppInfo.uninstall(activity: android.app.Activity) {
|
fun AppInfo.uninstall(activity: android.app.Activity) {
|
||||||
val packageName = this.packageName.toString()
|
val packageName = this.packageName
|
||||||
val userId = this.user
|
val userId = this.user
|
||||||
|
|
||||||
Log.i(LOG_TAG, "uninstalling $this")
|
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.forGesture
|
||||||
import de.jrpie.android.launcher.ui.list.hiddenVisibility
|
import de.jrpie.android.launcher.ui.list.hiddenVisibility
|
||||||
import de.jrpie.android.launcher.ui.list.intention
|
import de.jrpie.android.launcher.ui.list.intention
|
||||||
|
import de.jrpie.android.launcher.ui.list.privateSpaceVisibility
|
||||||
import de.jrpie.android.launcher.ui.openSoftKeyboard
|
import de.jrpie.android.launcher.ui.openSoftKeyboard
|
||||||
|
|
||||||
|
|
||||||
|
@ -72,6 +73,7 @@ class ListFragmentApps : Fragment(), UIObject {
|
||||||
requireContext(),
|
requireContext(),
|
||||||
"",
|
"",
|
||||||
favoritesVisibility = favoritesVisibility,
|
favoritesVisibility = favoritesVisibility,
|
||||||
|
privateSpaceVisibility = privateSpaceVisibility,
|
||||||
hiddenVisibility = hiddenVisibility
|
hiddenVisibility = hiddenVisibility
|
||||||
),
|
),
|
||||||
layout = LauncherPreferences.list().layout()
|
layout = LauncherPreferences.list().layout()
|
||||||
|
|
|
@ -45,21 +45,6 @@ class SettingsFragmentMeta : Fragment(), UIObject {
|
||||||
super<UIObject>.onStart()
|
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() {
|
override fun setOnClicks() {
|
||||||
|
|
||||||
binding.settingsMetaButtonViewTutorial.setOnClickListener {
|
binding.settingsMetaButtonViewTutorial.setOnClickListener {
|
||||||
|
|
|
@ -21,7 +21,7 @@ class TutorialFragmentConcept : Fragment(), UIObject {
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View {
|
): View {
|
||||||
val binding = TutorialConceptBinding.inflate(inflater, container, false)
|
binding = TutorialConceptBinding.inflate(inflater, container, false)
|
||||||
binding.tutorialConceptBadgeVersion.text = BuildConfig.VERSION_NAME
|
binding.tutorialConceptBadgeVersion.text = BuildConfig.VERSION_NAME
|
||||||
return binding.root
|
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_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
android:layout_marginLeft="8dp"
|
android:layout_marginEnd="8dp"
|
||||||
android:contentDescription="@string/settings"
|
android:contentDescription="@string/settings"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:paddingLeft="16sp"
|
android:paddingLeft="16sp"
|
||||||
|
@ -53,8 +53,8 @@
|
||||||
android:text="@string/list_title_pick"
|
android:text="@string/list_title_pick"
|
||||||
android:textAppearance="@style/TextAppearance.Widget.AppCompat.Toolbar.Title"
|
android:textAppearance="@style/TextAppearance.Widget.AppCompat.Toolbar.Title"
|
||||||
android:textSize="30sp"
|
android:textSize="30sp"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toStartOf="@id/list_lock"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toEndOf="@id/list_settings"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
|
@ -62,7 +62,7 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="8dp"
|
android:layout_marginEnd="8dp"
|
||||||
android:layout_marginRight="8dp"
|
android:layout_marginStart="8dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:includeFontPadding="true"
|
android:includeFontPadding="true"
|
||||||
android:paddingLeft="16sp"
|
android:paddingLeft="16sp"
|
||||||
|
@ -72,6 +72,21 @@
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
custom:type="solid" />
|
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>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
<com.google.android.material.tabs.TabLayout
|
<com.google.android.material.tabs.TabLayout
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
android:gravity="start|center_horizontal"
|
android:gravity="start|center_horizontal"
|
||||||
android:padding="5dp"
|
android:padding="5dp"
|
||||||
android:paddingStart="20dp"
|
android:paddingStart="20dp"
|
||||||
|
android:paddingEnd="20dp"
|
||||||
android:text=""
|
android:text=""
|
||||||
android:textSize="20sp"
|
android:textSize="20sp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
|
|
@ -22,9 +22,7 @@
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="60sp"
|
android:layout_marginStart="60sp"
|
||||||
android:layout_marginLeft="60sp"
|
|
||||||
android:layout_marginEnd="5dp"
|
android:layout_marginEnd="5dp"
|
||||||
android:layout_marginRight="5dp"
|
|
||||||
android:gravity="start"
|
android:gravity="start"
|
||||||
android:text=""
|
android:text=""
|
||||||
android:textSize="20sp"
|
android:textSize="20sp"
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
android:id="@+id/settings_close"
|
android:id="@+id/settings_close"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginRight="8dp"
|
android:layout_marginEnd="8dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:includeFontPadding="true"
|
android:includeFontPadding="true"
|
||||||
android:paddingLeft="16sp"
|
android:paddingLeft="16sp"
|
||||||
|
@ -55,7 +55,7 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
android:layout_marginLeft="8dp"
|
android:layout_marginEnd="8dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:includeFontPadding="true"
|
android:includeFontPadding="true"
|
||||||
android:paddingLeft="16sp"
|
android:paddingLeft="16sp"
|
||||||
|
|
|
@ -2,4 +2,5 @@
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<background android:drawable="@mipmap/ic_launcher_background"/>
|
<background android:drawable="@mipmap/ic_launcher_background"/>
|
||||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
||||||
|
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||||
</adaptive-icon>
|
</adaptive-icon>
|
|
@ -2,4 +2,5 @@
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<background android:drawable="@mipmap/ic_launcher_background"/>
|
<background android:drawable="@mipmap/ic_launcher_background"/>
|
||||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
||||||
|
<monochrome android:drawable="@drawable/ic_launcher_foreground"/>
|
||||||
</adaptive-icon>
|
</adaptive-icon>
|
|
@ -34,10 +34,10 @@
|
||||||
<string name="settings_gesture_right_bottom_edge">Para direita (em baixo)</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_bottom_edge">Para esquerda (em baixo)</string>
|
||||||
<string name="settings_gesture_left_top_edge">Para esquerda (no topo)</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_left_edge">Para cima (borda esquerda)</string>
|
||||||
<string name="settings_gesture_up_right_edge">Para cima (Borda direita)</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_left_edge">Para baixo (borda esquerda)</string>
|
||||||
<string name="settings_gesture_down_right_edge">Para baixo (Borda direita)</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_up">Aumento de volume</string>
|
||||||
<string name="settings_gesture_vol_down">Diminuição de volume</string>
|
<string name="settings_gesture_vol_down">Diminuição de volume</string>
|
||||||
<string name="settings_gesture_double_click">Toque duplo</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_date_visible">Mostrar Data</string>
|
||||||
<string name="settings_clock_localized">Use formato de data localizado</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_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_change_wallpaper">Alterar papel de parede</string>
|
||||||
<string name="settings_launcher_section_display">Exibição</string>
|
<string name="settings_launcher_section_display">Exibição</string>
|
||||||
<string name="settings_display_screen_timeout_disabled">Manter a tela ligada</string>
|
<string name="settings_display_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">O Launcher foi criado para ser minimalista, eficiente e livre de distrações. Ele é livre de pagamentos, anúncios e serviços de rastreamento.</string>
|
||||||
<string name="tutorial_concept_text_2">O app é de código aberto (licença MIT) e está disponível no GitHub! Não deixe de conferir o repositório!</string>
|
<string name="tutorial_concept_text_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_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">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 toque único ou pressionando um botão. Escolha algumas ações no próximo slide.</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_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">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_title">Vamos lá!</string>
|
||||||
<string name="tutorial_finish_text">Tá todo pronto para começar! Espero que isso seja de grande valor para você! - Finn (que criou o Launcher) \te Josia (que fez algumas melhorias e tb mantém o fork do μLauncher)</string>
|
<string name="tutorial_finish_text">Tá todo pronto para começar! 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>
|
<string name="tutorial_finish_button">Começar</string>
|
||||||
|
@ -162,7 +162,7 @@
|
||||||
<string name="screen_lock_method_use_accessibility">Usar o Serviço de acessibilidade</string>
|
<string name="screen_lock_method_use_accessibility">Usar o Serviço de acessibilidade</string>
|
||||||
<string name="screen_lock_method_use_device_admin">Usar o Administrador do dispositivo</string>
|
<string name="screen_lock_method_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="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="list_other_expand_settings_panel">Configurações rápidas</string>
|
||||||
<string name="alert_requires_android_m">Essa funcionalidade requer o Android 6 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="alert_no_torch_found">Nenhuma câmera com lanterna detectada.</string>
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
<string name="settings_apps_custom_names_key" translatable="false">apps.custom_names</string>
|
<string name="settings_apps_custom_names_key" translatable="false">apps.custom_names</string>
|
||||||
<string name="settings_apps_hide_bound_apps_key" translatable="false">apps.hide_bound_apps</string>
|
<string name="settings_apps_hide_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_paused_apps_key" translatable="false">apps.hide_paused_apps</string>
|
||||||
|
<string name="settings_apps_hide_private_space_apps_key" translatable="false">apps.hide_private_space_apps</string>
|
||||||
<string name="settings_list_layout_key" translatable="false">list.layout</string>
|
<string name="settings_list_layout_key" translatable="false">list.layout</string>
|
||||||
<string name="settings_general_choose_home_screen_key" translatable="false">general.select_launcher</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_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_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_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">Layout of app list</string>
|
||||||
|
|
||||||
<string name="settings_list_layout_item_default">Default</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_view">All Apps</string>
|
||||||
<string name="list_title_favorite">Favorite Apps</string>
|
<string name="list_title_favorite">Favorite Apps</string>
|
||||||
<string name="list_title_hidden">Hidden 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_title_pick">Choose App</string>
|
||||||
|
|
||||||
<string name="list_tab_app">Apps</string>
|
<string name="list_tab_app">Apps</string>
|
||||||
|
@ -219,6 +221,7 @@
|
||||||
<string name="list_other_settings">µLauncher Settings</string>
|
<string name="list_other_settings">µLauncher Settings</string>
|
||||||
<string name="list_other_list">All Applications</string>
|
<string name="list_other_list">All Applications</string>
|
||||||
<string name="list_other_list_favorites">Favorite 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_toggle_private_space_lock">Toggle Private Space Lock</string>
|
||||||
<string name="list_other_volume_up">Music: Louder</string>
|
<string name="list_other_volume_up">Music: Louder</string>
|
||||||
<string name="list_other_volume_down">Music: Quieter</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_unlocked">Private space unlocked</string>
|
||||||
<string name="toast_private_space_not_available">Private space is not available</string>
|
<string name="toast_private_space_not_available">Private space is not available</string>
|
||||||
<string name="toast_private_space_default_home_screen">µLauncher needs to be the default home screen to access private space.</string>
|
<string name="toast_private_space_default_home_screen">µLauncher needs to be the default home screen to access private space.</string>
|
||||||
|
<string name="tooltip_lock_private_space">Lock private space</string>
|
||||||
|
<string name="tooltip_unlock_private_space">Unlock private space</string>
|
||||||
<string name="toast_lock_screen_not_supported">Error: Locking the screen using accessibility is not supported on this device. Please use device admin instead.</string>
|
<string name="toast_lock_screen_not_supported">Error: Locking the screen using accessibility is not supported on this device. Please use device admin instead.</string>
|
||||||
<string name="accessibility_service_name">µLauncher - lock screen</string>
|
<string name="accessibility_service_name">µLauncher - lock screen</string>
|
||||||
<string name="accessibility_service_description">
|
<string name="accessibility_service_description">
|
||||||
|
|
|
@ -151,6 +151,11 @@
|
||||||
android:title="@string/settings_apps_hide_paused_apps"
|
android:title="@string/settings_apps_hide_paused_apps"
|
||||||
android:defaultValue="false" />
|
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
|
<DropDownPreference
|
||||||
android:key="@string/settings_list_layout_key"
|
android:key="@string/settings_list_layout_key"
|
||||||
android:title="@string/settings_list_layout"
|
android:title="@string/settings_list_layout"
|
||||||
|
|
Loading…
Add table
Reference in a new issue