use LiveData to store app list

This commit is contained in:
Josia Pietsch 2024-12-20 04:18:05 +01:00
parent 3353719cc3
commit 2b7999cfdc
Signed by: jrpie
GPG key ID: E70B571D66986A2D
4 changed files with 84 additions and 30 deletions

View file

@ -1,14 +1,69 @@
package de.jrpie.android.launcher
import android.content.SharedPreferences
import android.content.pm.LauncherApps
import android.content.pm.ShortcutInfo
import android.os.AsyncTask
import android.os.Build
import android.os.Build.VERSION_CODES
import android.os.UserHandle
import androidx.lifecycle.MutableLiveData
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.preferences.LauncherPreferences
class Application : android.app.Application() {
val apps = MutableLiveData<List<DetailedAppInfo>>()
// TODO: only update specific apps
private val launcherAppsCallback = object : LauncherApps.Callback() {
override fun onPackageRemoved(p0: String?, p1: UserHandle?) {
loadApps()
}
override fun onPackageAdded(p0: String?, p1: UserHandle?) {
loadApps()
}
override fun onPackageChanged(p0: String?, p1: UserHandle?) {
loadApps()
}
override fun onPackagesAvailable(p0: Array<out String>?, p1: UserHandle?, p2: Boolean) {
// TODO
}
override fun onPackagesSuspended(packageNames: Array<out String>?, user: UserHandle?) {
// TODO
}
override fun onPackagesUnsuspended(packageNames: Array<out String>?, user: UserHandle?) {
// TODO
}
override fun onPackagesUnavailable(p0: Array<out String>?, p1: UserHandle?, p2: Boolean) {
// TODO
}
override fun onPackageLoadingProgressChanged(
packageName: String,
user: UserHandle,
progress: Float
) {
// TODO
}
override fun onShortcutsChanged(
packageName: String,
shortcuts: MutableList<ShortcutInfo>,
user: UserHandle
) {
// TODO
}
}
var torchManager: TorchManager? = null
private var customAppNames: HashMap<AppInfo, String>? = null
private val listener = SharedPreferences.OnSharedPreferenceChangeListener { _, pref ->
@ -32,10 +87,20 @@ class Application : android.app.Application() {
LauncherPreferences.getSharedPreferences()
.registerOnSharedPreferenceChangeListener(listener)
val launcherApps = getSystemService(LAUNCHER_APPS_SERVICE) as LauncherApps
launcherApps.registerCallback(launcherAppsCallback)
loadApps()
}
fun getCustomAppNames(): HashMap<AppInfo, String> {
return (customAppNames ?: LauncherPreferences.apps().customNames() ?: HashMap())
.also { customAppNames = it }
}
private fun loadApps() {
AsyncTask.execute { apps.postValue(getApps(packageManager, applicationContext)) }
}
}

View file

@ -18,13 +18,9 @@ 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.ui.list.apps.AppsRecyclerAdapter
import de.jrpie.android.launcher.ui.tutorial.TutorialActivity
/* Objects used by multiple activities */
val appsList: MutableList<DetailedAppInfo> = ArrayList()
/* REQUEST CODES */
const val REQUEST_CHOOSE_APP = 1
@ -84,10 +80,10 @@ fun openTutorial(context: Context) {
/**
* [loadApps] is used to speed up the [AppsRecyclerAdapter] loading time,
* as it caches all the apps and allows for fast access to the data.
* Load all apps.
*/
fun loadApps(packageManager: PackageManager, context: Context) {
fun getApps(packageManager: PackageManager, context: Context): MutableList<DetailedAppInfo> {
val start = System.currentTimeMillis()
val loadList = mutableListOf<DetailedAppInfo>()
val launcherApps = context.getSystemService(Service.LAUNCHER_APPS_SERVICE) as LauncherApps
@ -101,7 +97,6 @@ fun loadApps(packageManager: PackageManager, context: Context) {
}
}
// fallback option
if (loadList.isEmpty()) {
Log.w(LOG_TAG, "using fallback option to load packages")
@ -119,8 +114,11 @@ fun loadApps(packageManager: PackageManager, context: Context) {
}
}
loadList.sortBy { it.getCustomLabel(context).toString() }
appsList.clear()
appsList.addAll(loadList)
val end = System.currentTimeMillis()
Log.i(LOG_TAG, "${loadList.size} apps loaded (${end - start}ms)")
return loadList
}

View file

@ -20,7 +20,6 @@ import de.jrpie.android.launcher.actions.Action
import de.jrpie.android.launcher.actions.Gesture
import de.jrpie.android.launcher.actions.LauncherAction
import de.jrpie.android.launcher.databinding.HomeBinding
import de.jrpie.android.launcher.loadApps
import de.jrpie.android.launcher.openTutorial
import de.jrpie.android.launcher.preferences.LauncherPreferences
import de.jrpie.android.launcher.preferences.migratePreferencesToNewVersion
@ -88,9 +87,6 @@ class HomeActivity : UIObject, AppCompatActivity(),
openTutorial(this)
}
// Preload apps to speed up the Apps Recycler
AsyncTask.execute { loadApps(packageManager, applicationContext) }
// Initialise layout
binding = HomeBinding.inflate(layoutInflater)
setContentView(binding.root)

View file

@ -4,7 +4,6 @@ import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.graphics.Rect
import android.os.AsyncTask
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@ -12,16 +11,16 @@ import android.view.inputmethod.InputMethodManager
import android.widget.ImageView
import android.widget.PopupMenu
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.RecyclerView
import de.jrpie.android.launcher.Application
import de.jrpie.android.launcher.R
import de.jrpie.android.launcher.REQUEST_CHOOSE_APP
import de.jrpie.android.launcher.actions.AppAction
import de.jrpie.android.launcher.apps.AppFilter
import de.jrpie.android.launcher.apps.AppInfo
import de.jrpie.android.launcher.apps.DetailedAppInfo
import de.jrpie.android.launcher.appsList
import de.jrpie.android.launcher.getUserFromId
import de.jrpie.android.launcher.loadApps
import de.jrpie.android.launcher.preferences.LauncherPreferences
import de.jrpie.android.launcher.preferences.ListLayout
import de.jrpie.android.launcher.ui.list.ListActivity
@ -47,8 +46,16 @@ class AppsRecyclerAdapter(
) :
RecyclerView.Adapter<AppsRecyclerAdapter.ViewHolder>() {
private val apps = (activity.applicationContext as Application).apps
private val appsListDisplayed: MutableList<DetailedAppInfo> = mutableListOf()
init {
apps.observe(this.activity as AppCompatActivity) {
updateAppsList()
}
updateAppsList()
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
View.OnClickListener {
@ -171,18 +178,6 @@ class AppsRecyclerAdapter(
return viewHolder
}
init {
// Load the apps
if (appsList.size == 0)
loadApps(activity.packageManager, activity)
else {
AsyncTask.execute { loadApps(activity.packageManager, activity) }
notifyDataSetChanged()
}
updateAppsList()
}
fun selectItem(pos: Int, rect: Rect = Rect()) {
if (pos >= appsListDisplayed.size) {
return
@ -205,7 +200,7 @@ class AppsRecyclerAdapter(
fun updateAppsList(triggerAutoLaunch: Boolean = false) {
appsListDisplayed.clear()
appsListDisplayed.addAll(appFilter(appsList))
apps.value?.let { appsListDisplayed.addAll(appFilter(it)) }
if (triggerAutoLaunch &&
appsListDisplayed.size == 1