diff --git a/app/src/main/java/eu/ottop/yamlauncher/AppActionMenu.kt b/app/src/main/java/eu/ottop/yamlauncher/AppActionMenu.kt index 1d97c63..50df8c2 100644 --- a/app/src/main/java/eu/ottop/yamlauncher/AppActionMenu.kt +++ b/app/src/main/java/eu/ottop/yamlauncher/AppActionMenu.kt @@ -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) diff --git a/app/src/main/java/eu/ottop/yamlauncher/AppMenuActivity.kt b/app/src/main/java/eu/ottop/yamlauncher/AppMenuActivity.kt index 8a52989..6f1f58c 100644 --- a/app/src/main/java/eu/ottop/yamlauncher/AppMenuActivity.kt +++ b/app/src/main/java/eu/ottop/yamlauncher/AppMenuActivity.kt @@ -35,26 +35,28 @@ class AppMenuActivity : AppCompatActivity(), AppMenuAdapter.OnItemClickListener, private lateinit var searchView: EditText private lateinit var adapter: AppMenuAdapter private lateinit var filteredApps: MutableList>> - private lateinit var installedApps: List>> - private lateinit var job: Job + private var job: Job? = null private var appActionMenu = AppActionMenu() private lateinit var launcherApps: LauncherApps + private lateinit var installedApps: List>> private val sharedPreferenceManager = SharedPreferenceManager() + private val appUtils = AppUtils() private lateinit var menuMode: String companion object { private lateinit var callback: (Pair, Pair>) -> Unit private const val MENU_MODE = "app" - - fun start(context: Context, param1: String = "app", callback: (Pair, Pair>) -> Unit) { + private lateinit var currentApps: List>> + fun start(context: Context, currentApps: List>>, param1: String = "app", callback: (Pair, Pair>) -> 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>>() @@ -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>>() - 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>> { - val allApps = mutableListOf>>() - 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 diff --git a/app/src/main/java/eu/ottop/yamlauncher/AppUtils.kt b/app/src/main/java/eu/ottop/yamlauncher/AppUtils.kt new file mode 100644 index 0000000..1cdc778 --- /dev/null +++ b/app/src/main/java/eu/ottop/yamlauncher/AppUtils.kt @@ -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>> { + val allApps = mutableListOf>>() + 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() + } + + + } +} \ No newline at end of file diff --git a/app/src/main/java/eu/ottop/yamlauncher/MainActivity.kt b/app/src/main/java/eu/ottop/yamlauncher/MainActivity.kt index 2140e3f..c78a326 100644 --- a/app/src/main/java/eu/ottop/yamlauncher/MainActivity.kt +++ b/app/src/main/java/eu/ottop/yamlauncher/MainActivity.kt @@ -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>> + 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(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) { } }