mirror of
https://github.com/jrpie/Launcher.git
synced 2025-02-23 06:21:31 +01:00
implement #68: renaming of apps
This commit is contained in:
parent
b8ef2a07c2
commit
fac3991f96
13 changed files with 157 additions and 8 deletions
|
@ -4,10 +4,12 @@ import android.os.Build
|
|||
import android.os.Build.VERSION_CODES
|
||||
import androidx.preference.PreferenceManager
|
||||
import de.jrpie.android.launcher.actions.TorchManager
|
||||
import de.jrpie.android.launcher.apps.AppInfo
|
||||
import de.jrpie.android.launcher.preferences.LauncherPreferences
|
||||
|
||||
class Application : android.app.Application() {
|
||||
var torchManager: TorchManager? = null
|
||||
var customAppNames: HashMap<AppInfo, String> = HashMap()
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
|
||||
|
@ -18,5 +20,13 @@ class Application : android.app.Application() {
|
|||
val preferences = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
LauncherPreferences.init(preferences, this.resources)
|
||||
|
||||
customAppNames = LauncherPreferences.apps().customNames()
|
||||
|
||||
LauncherPreferences.getSharedPreferences()
|
||||
.registerOnSharedPreferenceChangeListener { _, pref ->
|
||||
if (pref == getString(R.string.settings_apps_custom_names_key)) {
|
||||
customAppNames = LauncherPreferences.apps().customNames()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -185,7 +185,7 @@ fun loadApps(packageManager: PackageManager, context: Context) {
|
|||
loadList.add(detailedAppInfo)
|
||||
}
|
||||
}
|
||||
loadList.sortBy { it.label.toString() }
|
||||
loadList.sortBy { it.getCustomLabel(context).toString() }
|
||||
appsList.clear()
|
||||
appsList.addAll(loadList)
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ class AppAction(val appInfo: AppInfo) : Action {
|
|||
}
|
||||
|
||||
override fun label(context: Context): String {
|
||||
return DetailedAppInfo.fromAppInfo(appInfo, context)?.label.toString()
|
||||
return DetailedAppInfo.fromAppInfo(appInfo, context)?.getCustomLabel(context).toString()
|
||||
}
|
||||
|
||||
override fun getIcon(context: Context): Drawable? {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package de.jrpie.android.launcher.apps
|
||||
|
||||
import android.content.Context
|
||||
import de.jrpie.android.launcher.actions.Action
|
||||
import de.jrpie.android.launcher.actions.AppAction
|
||||
import de.jrpie.android.launcher.actions.Gesture
|
||||
|
@ -8,12 +9,14 @@ import java.util.Locale
|
|||
import kotlin.text.Regex.Companion.escape
|
||||
|
||||
class AppFilter(
|
||||
var context: Context,
|
||||
var search: String,
|
||||
var favoritesVisibility: AppSetVisibility = AppSetVisibility.VISIBLE,
|
||||
var hiddenVisibility: AppSetVisibility = AppSetVisibility.HIDDEN,
|
||||
) {
|
||||
operator fun invoke(apps: List<DetailedAppInfo>): List<DetailedAppInfo> {
|
||||
var apps = apps
|
||||
var apps =
|
||||
apps.sortedBy { app -> app.getCustomLabel(context).toString().lowercase(Locale.ROOT) }
|
||||
|
||||
val hidden = LauncherPreferences.apps().hidden() ?: setOf()
|
||||
val favorites = LauncherPreferences.apps().favorites() ?: setOf()
|
||||
|
@ -51,7 +54,7 @@ class AppFilter(
|
|||
val appsSecondary: MutableList<DetailedAppInfo> = ArrayList()
|
||||
val normalizedText: String = normalize(search)
|
||||
for (item in apps) {
|
||||
val itemLabel: String = normalize(item.label.toString())
|
||||
val itemLabel: String = normalize(item.getCustomLabel(context).toString())
|
||||
|
||||
if (itemLabel.startsWith(normalizedText)) {
|
||||
r.add(item)
|
||||
|
|
|
@ -4,6 +4,9 @@ import android.content.Context
|
|||
import android.content.pm.ApplicationInfo
|
||||
import android.content.pm.LauncherActivityInfo
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.util.Log
|
||||
import de.jrpie.android.launcher.Application
|
||||
import de.jrpie.android.launcher.preferences.LauncherPreferences
|
||||
|
||||
/**
|
||||
* Stores information used to create [AppsRecyclerAdapter] rows.
|
||||
|
@ -16,12 +19,36 @@ class DetailedAppInfo(
|
|||
) {
|
||||
|
||||
constructor(activityInfo: LauncherActivityInfo) : this(
|
||||
AppInfo(activityInfo.applicationInfo.packageName, activityInfo.name, activityInfo.user.hashCode()),
|
||||
AppInfo(
|
||||
activityInfo.applicationInfo.packageName,
|
||||
activityInfo.name,
|
||||
activityInfo.user.hashCode()
|
||||
),
|
||||
activityInfo.label,
|
||||
activityInfo.getBadgedIcon(0),
|
||||
activityInfo.applicationInfo.flags.and(ApplicationInfo.FLAG_SYSTEM) != 0
|
||||
)
|
||||
|
||||
fun getCustomLabel(context: Context): CharSequence {
|
||||
val map = (context.applicationContext as? Application)?.customAppNames ?: return label
|
||||
|
||||
return map[app] ?: label
|
||||
}
|
||||
|
||||
fun setCustomLabel(label: CharSequence?) {
|
||||
|
||||
Log.i("Launcher", "Setting custom label for ${this.app} to ${label}.")
|
||||
val map = LauncherPreferences.apps().customNames() ?: HashMap<AppInfo, String>()
|
||||
|
||||
if (label.isNullOrEmpty()) {
|
||||
map.remove(app)
|
||||
} else {
|
||||
map[app] = label.toString()
|
||||
}
|
||||
|
||||
LauncherPreferences.apps().customNames(map)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun fromAppInfo(appInfo: AppInfo, context: Context): DetailedAppInfo? {
|
||||
return appInfo.getLauncherActivityInfo(context)?.let { DetailedAppInfo(it) }
|
||||
|
|
|
@ -1,7 +1,15 @@
|
|||
package de.jrpie.android.launcher.preferences;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import de.jrpie.android.launcher.R;
|
||||
import de.jrpie.android.launcher.apps.AppInfo;
|
||||
|
@ -28,6 +36,7 @@ import eu.jonahbauer.android.preference.annotations.serializer.PreferenceSeriali
|
|||
@PreferenceGroup(name = "apps", prefix = "settings_apps_", suffix = "_key", value = {
|
||||
@Preference(name = "favorites", type = Set.class, serializer = LauncherPreferences$Config.AppInfoSetSerializer.class),
|
||||
@Preference(name = "hidden", type = Set.class, serializer = LauncherPreferences$Config.AppInfoSetSerializer.class),
|
||||
@Preference(name = "custom_names", type = HashMap.class, serializer = LauncherPreferences$Config.MapAppInfoStringSerializer.class),
|
||||
@Preference(name = "hide_bound_apps", type = boolean.class, defaultValue = "false"),
|
||||
}),
|
||||
@PreferenceGroup(name = "gestures", prefix = "settings_gesture_", suffix = "_key", value = {
|
||||
|
@ -96,6 +105,46 @@ public final class LauncherPreferences$Config {
|
|||
|
||||
return deserialized;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MapAppInfoStringSerializer implements PreferenceSerializer<HashMap<AppInfo, String>, Set<String>> {
|
||||
|
||||
@Override
|
||||
public Set<String> serialize(HashMap<AppInfo, String> value) throws PreferenceSerializationException {
|
||||
if (value == null) return null;
|
||||
|
||||
var serialized = new HashSet<String>(value.size());
|
||||
|
||||
for (var entry : value.entrySet()) {
|
||||
JSONObject obj = new JSONObject();
|
||||
try {
|
||||
obj.put("key", entry.getKey().serialize());
|
||||
obj.put("value", entry.getValue());
|
||||
serialized.add(obj.toString());
|
||||
} catch (JSONException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
return serialized;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HashMap<AppInfo, String> deserialize(Set<String> value) throws PreferenceSerializationException {
|
||||
if (value == null) return null;
|
||||
|
||||
var deserialized = new HashMap<AppInfo, String>();
|
||||
|
||||
for (var entry : value) {
|
||||
try {
|
||||
JSONObject obj = new JSONObject(entry);
|
||||
AppInfo info = AppInfo.Companion.deserialize(obj.getString("key"));
|
||||
String s = obj.getString("value");
|
||||
deserialized.put(info, s);
|
||||
} catch (JSONException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
return deserialized;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,14 +5,17 @@ import android.app.Activity
|
|||
import android.content.Intent
|
||||
import android.graphics.Rect
|
||||
import android.os.AsyncTask
|
||||
import android.text.InputType
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.EditText
|
||||
import android.widget.ImageView
|
||||
import android.widget.PopupMenu
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import de.jrpie.android.launcher.R
|
||||
|
@ -44,7 +47,7 @@ class AppsRecyclerAdapter(
|
|||
private val intention: ListActivity.ListActivityIntention
|
||||
= ListActivity.ListActivityIntention.VIEW,
|
||||
private val forGesture: String? = "",
|
||||
private var appFilter: AppFilter = AppFilter("")
|
||||
private var appFilter: AppFilter = AppFilter(activity, "")
|
||||
) :
|
||||
RecyclerView.Adapter<AppsRecyclerAdapter.ViewHolder>() {
|
||||
|
||||
|
@ -69,7 +72,7 @@ class AppsRecyclerAdapter(
|
|||
|
||||
|
||||
override fun onBindViewHolder(viewHolder: ViewHolder, i: Int) {
|
||||
val appLabel = appsListDisplayed[i].label.toString()
|
||||
val appLabel = appsListDisplayed[i].getCustomLabel(activity).toString()
|
||||
val appIcon = appsListDisplayed[i].icon
|
||||
|
||||
viewHolder.textView.text = appLabel
|
||||
|
@ -146,7 +149,10 @@ class AppsRecyclerAdapter(
|
|||
|
||||
if (favorites.contains(appInfo.app)) {
|
||||
favorites.remove(appInfo.app)
|
||||
Log.i("LAUNCHER", "Removing " + appInfo.app.serialize() + " from favorites.")
|
||||
Log.i(
|
||||
"LAUNCHER",
|
||||
"Removing " + appInfo.app.serialize() + " from favorites."
|
||||
)
|
||||
} else {
|
||||
Log.i("LAUNCHER", "Adding " + appInfo.app.serialize() + " to favorites.")
|
||||
favorites.add(appInfo.app)
|
||||
|
@ -181,6 +187,30 @@ class AppsRecyclerAdapter(
|
|||
true
|
||||
}
|
||||
|
||||
R.id.app_menu_rename -> {
|
||||
val builder = AlertDialog.Builder(activity, R.style.AlertDialogCustom)
|
||||
|
||||
val title = activity.getString(R.string.dialog_rename_title, appInfo.label)
|
||||
builder.setTitle(title)
|
||||
builder.setView(R.layout.dialog_rename_app)
|
||||
|
||||
builder.setNegativeButton(R.string.dialog_rename_cancel) { d, _ -> d.cancel() }
|
||||
builder.setPositiveButton(R.string.dialog_rename_ok) { d, _ ->
|
||||
appInfo.setCustomLabel(
|
||||
(d as? AlertDialog)
|
||||
?.findViewById<EditText>(R.id.dialog_rename_app_edit_text)
|
||||
?.text.toString()
|
||||
)
|
||||
}
|
||||
|
||||
val dialog = builder.create()
|
||||
dialog.show()
|
||||
val input = dialog.findViewById<EditText>(R.id.dialog_rename_app_edit_text)
|
||||
input?.setText(appInfo.getCustomLabel(activity))
|
||||
input?.hint = appInfo.label
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,6 +66,7 @@ class ListFragmentApps : Fragment(), UIObject {
|
|||
AppsRecyclerAdapter(
|
||||
requireActivity(), binding.root, intention, forGesture,
|
||||
appFilter = AppFilter(
|
||||
requireContext(),
|
||||
"",
|
||||
favoritesVisibility = favoritesVisibility,
|
||||
hiddenVisibility = hiddenVisibility
|
||||
|
|
18
app/src/main/res/layout/dialog_rename_app.xml
Normal file
18
app/src/main/res/layout/dialog_rename_app.xml
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
style="@style/AlertDialogCustom"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/dialog_rename_app_edit_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="10dp"
|
||||
android:importantForAutofill="no"
|
||||
android:inputType="text"
|
||||
tools:ignore="LabelFor" />
|
||||
|
||||
</LinearLayout>
|
|
@ -6,6 +6,8 @@
|
|||
android:title="@string/list_app_favorite_add" />
|
||||
<item android:id="@+id/app_menu_hidden"
|
||||
android:title="@string/list_app_hidden_add" />
|
||||
<item android:id="@+id/app_menu_rename"
|
||||
android:title="@string/list_app_rename" />
|
||||
<item android:id="@+id/app_menu_delete"
|
||||
android:title="@string/list_app_delete" />
|
||||
</menu>
|
||||
|
|
|
@ -136,6 +136,7 @@
|
|||
<string name="list_app_delete">Deinstallieren</string>
|
||||
<string name="list_app_info">App Info</string>
|
||||
<string name="list_app_hidden_remove">Sichtbar machen</string>
|
||||
<string name="list_app_rename">Umbenennen</string>
|
||||
<string name="list_removed">Die App wurde entfernt</string>
|
||||
<string name="list_not_removed">Die App konnte nicht entfernt werden</string>
|
||||
<string name="list_apps_search_hint">Anwendungen suchen</string>
|
||||
|
@ -188,4 +189,7 @@
|
|||
<string name="device_admin_description">Die Aktion \"Bildschirm sperren\" aktivieren</string>
|
||||
<string name="alert_no_torch_found">Es wurde keine geeignete Kamera gefunden.</string>
|
||||
<string name="alert_torch_access_exception">Fehler: Kein Zugriff auf die Kamera möglich.</string>
|
||||
<string name="dialog_rename_cancel">Abbrechen</string>
|
||||
<string name="dialog_rename_ok">Ok</string>
|
||||
<string name="dialog_rename_title">%1$s umbenennen</string>
|
||||
</resources>
|
|
@ -11,6 +11,7 @@
|
|||
<string name="settings_internal_version_code_key" translatable="false">internal.version_code</string>
|
||||
<string name="settings_apps_favorites_key" translatable="false">apps.favorites</string>
|
||||
<string name="settings_apps_hidden_key" translatable="false">apps.hidden</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_general_choose_home_screen_key" translatable="false">general.select_launcher</string>
|
||||
|
|
|
@ -191,6 +191,7 @@
|
|||
<string name="list_app_favorite_remove">Remove from favorites</string>
|
||||
<string name="list_app_hidden_add">Hide</string>
|
||||
<string name="list_app_hidden_remove">Show</string>
|
||||
<string name="list_app_rename">Rename</string>
|
||||
|
||||
<string name="list_removed">Removed the selected application</string>
|
||||
<string name="list_not_removed">Unable to remove application</string>
|
||||
|
@ -283,4 +284,7 @@
|
|||
<string name="screen_lock_method_use_accessibility">Use Accessibility Service</string>
|
||||
<string name="screen_lock_method_use_device_admin">Use Device Admin</string>
|
||||
<string name="settings_actions_lock_method">Choose method for locking the screen</string>
|
||||
<string name="dialog_rename_cancel">Cancel</string>
|
||||
<string name="dialog_rename_ok">Ok</string>
|
||||
<string name="dialog_rename_title">Rename %1$s</string>
|
||||
</resources>
|
||||
|
|
Loading…
Add table
Reference in a new issue