Fixed app change check cancelling and the installed apps are now loaded in MainActivity for faster app menu opening.

This commit is contained in:
ottoptj 2024-05-21 20:55:24 +03:00
commit ce78b5f37e
4 changed files with 70 additions and 36 deletions

View file

@ -23,6 +23,7 @@ import kotlinx.coroutines.launch
class AppActionMenu {
private val sharedPreferenceManager = SharedPreferenceManager()
private val appUtils = AppUtils()
fun setActionListeners(
activity: AppMenuActivity,
@ -105,7 +106,7 @@ class AppActionMenu {
editText.text.toString()
)
val newPosition = activity.getInstalledApps()
val newPosition = appUtils.getInstalledApps(activity)
.indexOfFirst { it.first.applicationInfo.packageName == appInfo.packageName && it.second.second == workProfile }
activity.updateItem(position, app)
@ -127,7 +128,7 @@ class AppActionMenu {
app.first.applicationInfo.packageName,
app.second.second
)
val newPosition = activity.getInstalledApps()
val newPosition = appUtils.getInstalledApps(activity)
.indexOfFirst { it.first.applicationInfo.packageName == appInfo.packageName && it.second.second == workProfile }
activity.updateItem(position, app)
activity.moveItem(position, newPosition)

View file

@ -35,26 +35,28 @@ class AppMenuActivity : AppCompatActivity(), AppMenuAdapter.OnItemClickListener,
private lateinit var searchView: EditText
private lateinit var adapter: AppMenuAdapter
private lateinit var filteredApps: MutableList<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>
private lateinit var installedApps: List<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>
private lateinit var job: Job
private var job: Job? = null
private var appActionMenu = AppActionMenu()
private lateinit var launcherApps: LauncherApps
private lateinit var installedApps: List<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>
private val sharedPreferenceManager = SharedPreferenceManager()
private val appUtils = AppUtils()
private lateinit var menuMode: String
companion object {
private lateinit var callback: (Pair<Pair<String, Int>, Pair<LauncherActivityInfo, UserHandle>>) -> Unit
private const val MENU_MODE = "app"
fun start(context: Context, param1: String = "app", callback: (Pair<Pair<String, Int>, Pair<LauncherActivityInfo, UserHandle>>) -> Unit) {
private lateinit var currentApps: List<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>
fun start(context: Context, currentApps: List<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>, param1: String = "app", callback: (Pair<Pair<String, Int>, Pair<LauncherActivityInfo, UserHandle>>) -> Unit) {
val intent = Intent(context, AppMenuActivity::class.java).apply {
putExtra(MENU_MODE, param1)
}
context.startActivity(intent)
this.callback = callback
this.currentApps = currentApps
}
}
@ -76,7 +78,7 @@ class AppMenuActivity : AppCompatActivity(), AppMenuAdapter.OnItemClickListener,
recyclerView = findViewById(R.id.recycler_view)
recyclerView.scrollToPosition(0)
installedApps = getInstalledApps()
installedApps = currentApps
filteredApps = mutableListOf()
filteredApps.addAll(installedApps)
val newApps = mutableListOf<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>()
@ -136,10 +138,13 @@ class AppMenuActivity : AppCompatActivity(), AppMenuAdapter.OnItemClickListener,
binding.root.addOnLayoutChangeListener { _, _, top, _, bottom, _, oldTop, _, oldBottom ->
if (bottom - top > oldBottom - oldTop) {
searchView.clearFocus()
startTask()
if (searchView.text.isNullOrEmpty()) {
job?.cancel()
startTask()
}
}
else if (bottom - top < oldBottom - oldTop) {
job.cancel()
else {
job?.cancel()
}
}
@ -162,12 +167,11 @@ class AppMenuActivity : AppCompatActivity(), AppMenuAdapter.OnItemClickListener,
CoroutineScope(Dispatchers.Default).launch {
val cleanQuery = query?.clean()
val newFilteredApps = mutableListOf<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>()
val updatedApps = getInstalledApps()
val updatedApps = appUtils.getInstalledApps(this@AppMenuActivity)
if (cleanQuery.isNullOrEmpty()) {
manualRefresh()
newFilteredApps.addAll(installedApps)
} else {
updatedApps.forEach {
val cleanItemText = sharedPreferenceManager.getAppName(this@AppMenuActivity, it.first.applicationInfo.packageName, it.second.second, it.first.applicationInfo.loadLabel(packageManager)).toString().clean()
@ -190,32 +194,22 @@ class AppMenuActivity : AppCompatActivity(), AppMenuAdapter.OnItemClickListener,
return this.replace("[^a-zA-Z0-9]".toRegex(), "")
}
fun getInstalledApps(): List<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>> {
val allApps = mutableListOf<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>()
val launcherApps = getSystemService(LAUNCHER_APPS_SERVICE) as LauncherApps
for (i in launcherApps.profiles.indices) {
launcherApps.getActivityList(null, launcherApps.profiles[i]).forEach { app ->
if (!sharedPreferenceManager.isAppHidden(this@AppMenuActivity, app.applicationInfo.packageName, i)) {
allApps.add(Pair(app, Pair(launcherApps.profiles[i], i)))
}
}
}
return allApps.sortedBy {
sharedPreferenceManager.getAppName(this, it.first.applicationInfo.packageName,it.second.second, it.first.applicationInfo.loadLabel(packageManager)).toString().lowercase()
}
override fun onStop() {
super.onStop()
job?.cancel()
}
override fun onStop() {
super.onStop()
job.cancel()
override fun onDestroy() {
super.onDestroy()
job?.cancel()
}
override fun onStart() {
super.onStart()
startTask()
// Keyboard is sometimes open when going back to the app, so close it.
val imm =
getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(binding.root.windowToken, 0)
@ -224,6 +218,7 @@ class AppMenuActivity : AppCompatActivity(), AppMenuAdapter.OnItemClickListener,
private fun startTask() {
job = CoroutineScope(Dispatchers.Default).launch {
while (true) {
ensureActive()
manualRefresh()
delay(5000)
}
@ -232,7 +227,7 @@ class AppMenuActivity : AppCompatActivity(), AppMenuAdapter.OnItemClickListener,
fun manualRefresh() {
CoroutineScope(Dispatchers.Default).launch {
val updatedApps = getInstalledApps()
val updatedApps = appUtils.getInstalledApps(this@AppMenuActivity)
val changes = detectChanges(installedApps, updatedApps)
installedApps = updatedApps
withContext(Dispatchers.Main) {
@ -247,6 +242,7 @@ class AppMenuActivity : AppCompatActivity(), AppMenuAdapter.OnItemClickListener,
val oldSet = oldList.map { Pair(it.first.applicationInfo.packageName, it.second.second) }.toSet()
val newSet = newList.map { Pair(it.first.applicationInfo.packageName, it.second.second) }.toSet()
//Detect updates
oldList.forEachIndexed { index, oldItem ->
if (newSet.contains(Pair(oldItem.first.applicationInfo.packageName, oldItem.second.second))) {
val newIndex = newList.indexOfFirst { it.first.applicationInfo.packageName == oldItem.first.applicationInfo.packageName && it.second.second == oldItem.second.second }
@ -271,9 +267,6 @@ class AppMenuActivity : AppCompatActivity(), AppMenuAdapter.OnItemClickListener,
}
}
// Detect updates
changes.addAll(removalChanges.reversed())
return changes

View file

@ -0,0 +1,29 @@
package eu.ottop.yamlauncher
import android.app.Activity
import android.content.pm.LauncherActivityInfo
import android.content.pm.LauncherApps
import android.os.UserHandle
import androidx.appcompat.app.AppCompatActivity
class AppUtils {
private val sharedPreferenceManager = SharedPreferenceManager()
fun getInstalledApps(activity: Activity): List<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>> {
val allApps = mutableListOf<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>()
val launcherApps = activity.getSystemService(AppCompatActivity.LAUNCHER_APPS_SERVICE) as LauncherApps
for (i in launcherApps.profiles.indices) {
launcherApps.getActivityList(null, launcherApps.profiles[i]).forEach { app ->
if (!sharedPreferenceManager.isAppHidden(activity, app.applicationInfo.packageName, i) && app.applicationInfo.packageName != activity.applicationInfo.packageName) {
allApps.add(Pair(app, Pair(launcherApps.profiles[i], i)))
}
}
}
return allApps.sortedBy {
sharedPreferenceManager.getAppName(activity, it.first.applicationInfo.packageName,it.second.second, it.first.applicationInfo.loadLabel(activity.packageManager)).toString().lowercase()
}
}
}

View file

@ -1,8 +1,10 @@
package eu.ottop.yamlauncher
import android.content.Context
import android.content.pm.LauncherActivityInfo
import android.content.pm.LauncherApps
import android.os.Bundle
import android.os.UserHandle
import android.view.GestureDetector
import android.view.MotionEvent
import android.widget.LinearLayout
@ -12,6 +14,9 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.res.ResourcesCompat
import androidx.core.view.children
import eu.ottop.yamlauncher.databinding.ActivityMainBinding
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlin.math.abs
class MainActivity : AppCompatActivity() {
@ -19,7 +24,10 @@ class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var gestureDetector: GestureDetector
private lateinit var launcherApps: LauncherApps
private lateinit var installedApps: List<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>
private val sharedPreferenceManager = SharedPreferenceManager()
private val appUtils = AppUtils()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -28,6 +36,9 @@ class MainActivity : AppCompatActivity() {
setSupportActionBar(null)
launcherApps = getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps
CoroutineScope(Dispatchers.Default).launch {
installedApps = appUtils.getInstalledApps(this@MainActivity)
}
for (i in findViewById<LinearLayout>(R.id.shortcuts).children) {
@ -63,7 +74,7 @@ class MainActivity : AppCompatActivity() {
}
i.setOnLongClickListener {
AppMenuActivity.start(this@MainActivity, "shortcut") { newText ->
AppMenuActivity.start(this@MainActivity, installedApps, "shortcut") { newText ->
if (newText.first.second != 0) {
textView.setCompoundDrawablesWithIntrinsicBounds(ResourcesCompat.getDrawable(resources, R.drawable.ic_work_app, null),null,null,null)
@ -123,7 +134,7 @@ class MainActivity : AppCompatActivity() {
}
fun openAppMenuActivity() {
AppMenuActivity.start(this) {
AppMenuActivity.start(this, installedApps) {
}
}