Improved app info obtaining logic + returned back to bad recycler updates

This commit is contained in:
ottoptj 2024-08-05 16:04:06 +03:00
commit ff354232e0
2 changed files with 15 additions and 107 deletions

View file

@ -6,6 +6,7 @@ import android.content.pm.LauncherActivityInfo
import android.content.pm.LauncherApps import android.content.pm.LauncherApps
import android.os.UserHandle import android.os.UserHandle
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import java.lang.reflect.InvocationTargetException
class AppUtils { class AppUtils {
@ -47,9 +48,11 @@ class AppUtils {
packageName: String, packageName: String,
profile: Int profile: Int
): ApplicationInfo? { ): ApplicationInfo? {
return try {
launcherApps.getApplicationInfo(packageName, 0, launcherApps.profiles[profile])
} catch (_: Exception) {
null
}
return launcherApps.getActivityList(
packageName, launcherApps.profiles[profile]
).firstOrNull()?.applicationInfo
} }
} }

View file

@ -619,7 +619,7 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
}, 100) }, 100)
handler.postDelayed({ handler.postDelayed({
CoroutineScope(Dispatchers.Default).launch { CoroutineScope(Dispatchers.Default).launch {
refreshAppMenu()
try { try {
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
@ -705,30 +705,22 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
} }
suspend fun refreshAppMenu() { suspend fun refreshAppMenu() {
try {
val updatedApps = appUtils.getInstalledApps(this@MainActivity, launcherApps)
val changes = detectChanges(installedApps, updatedApps)
installedApps = updatedApps
withContext(Dispatchers.Main) {
applyChanges(changes, installedApps)
}
}
catch (_: UninitializedPropertyAccessException) {
}
/*
try { try {
val updatedApps = appUtils.getInstalledApps(this@MainActivity, launcherApps) val updatedApps = appUtils.getInstalledApps(this@MainActivity, launcherApps)
println("update running") println("update running")
withContext(Dispatchers.Main) { if (!listsEqual(installedApps, updatedApps)) {
updateMenu(updatedApps) withContext(Dispatchers.Main) {
updateMenu(updatedApps)
}
installedApps = updatedApps
} }
installedApps = updatedApps
} }
catch (_: UninitializedPropertyAccessException) { catch (_: UninitializedPropertyAccessException) {
}*/ }
} }
private fun closeKeyboard() { private fun closeKeyboard() {
val imm = val imm =
getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
@ -802,7 +794,7 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
searchView.textAlignment = View.TEXT_ALIGNMENT_VIEW_START searchView.textAlignment = View.TEXT_ALIGNMENT_VIEW_START
} }
"center" -> { "center" -> {
searchView.textAlignment = TEXT_ALIGNMENT_CENTER searchView.textAlignment = View.TEXT_ALIGNMENT_CENTER
} }
"right" -> { "right" -> {
searchView.textAlignment = View.TEXT_ALIGNMENT_VIEW_END searchView.textAlignment = View.TEXT_ALIGNMENT_VIEW_END
@ -905,91 +897,4 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
false false
} }
} }
fun detectChanges(oldList: List<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>, newList: List<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>): List<Change> {
val changes = mutableListOf<Change>()
val removalChanges = mutableListOf<Change>()
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 removals
oldList.forEachIndexed { index, oldItem ->
if (!newSet.contains(Pair(oldItem.first.applicationInfo.packageName, oldItem.second.second))) {
removalChanges.add(Change(ChangeType.REMOVE, index))
}
}
// Detect insertions
newList.forEachIndexed { index, newItem ->
if (!oldSet.contains(Pair(newItem.first.applicationInfo.packageName, newItem.second.second))) {
changes.add(Change(ChangeType.INSERT, index))
}
}
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 }
if (oldItem.first.componentName != newList[newIndex].first.componentName) {
changes.add(Change(ChangeType.UPDATE, index))
}
if (index != newIndex) {
changes.add(Change(ChangeType.MOVE, index))
}
}
}
changes.addAll(removalChanges.reversed())
return changes
}
@SuppressLint("NotifyDataSetChanged")
fun applyChanges(changes: List<Change>, updatedApps: List<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>) {
changes.forEach { change ->
when (change.type) {
ChangeType.INSERT -> {
insertItem(change.position, updatedApps[change.position])
}
ChangeType.REMOVE -> {
try {
removeItem(change.position)
}
catch (_: IndexOutOfBoundsException) {
}
}
ChangeType.UPDATE -> {
updateItem(change.position, updatedApps[change.position])
}
ChangeType.MOVE -> {
adapter?.updateApps(updatedApps)
adapter?.notifyDataSetChanged()
println("moved")
}
}
}
}
private fun insertItem(position: Int, app: Pair<LauncherActivityInfo, Pair<UserHandle, Int>>) {
adapter?.addApp(position, app)
adapter?.notifyItemInserted(position)
}
private fun removeItem(position: Int) {
adapter?.removeApp(position)
adapter?.notifyItemRemoved(position)
}
private fun updateItem(position: Int, app: Pair<LauncherActivityInfo, Pair<UserHandle, Int>>) {
adapter?.updateApp(position, app)
adapter?.notifyItemChanged(position)
}
}
data class Change(val type: ChangeType, val position: Int, val newPosition: Int = 0)
enum class ChangeType {
INSERT, REMOVE, UPDATE, MOVE
} }