From ed9fc728ee64cc47e6a7fc9c6a264ad9aafcc96b Mon Sep 17 00:00:00 2001 From: tibbi Date: Mon, 19 Sep 2022 18:44:30 +0200 Subject: [PATCH] refresh icons on uninstall --- .../launcher/activities/MainActivity.kt | 90 ++++++++++++++++++- .../launcher/adapters/LaunchersAdapter.kt | 7 +- .../launcher/extensions/Activity.kt | 3 +- .../launcher/fragments/AllAppsFragment.kt | 71 +-------------- .../launcher/helpers/Constants.kt | 2 + .../launcher/models/AppLauncher.kt | 6 ++ 6 files changed, 105 insertions(+), 74 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/activities/MainActivity.kt index 79c2fb4..7281c98 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/activities/MainActivity.kt @@ -1,10 +1,12 @@ package com.simplemobiletools.launcher.activities import android.animation.ObjectAnimator +import android.annotation.SuppressLint import android.content.Context import android.content.Intent import android.content.pm.PackageManager import android.content.res.Configuration +import android.graphics.Bitmap import android.graphics.Color import android.net.Uri import android.os.Bundle @@ -14,6 +16,7 @@ import android.view.* import android.view.animation.DecelerateInterpolator import android.widget.PopupMenu import android.widget.RelativeLayout +import androidx.core.graphics.drawable.toBitmap import androidx.core.view.GestureDetectorCompat import androidx.core.view.marginLeft import androidx.core.view.marginTop @@ -21,15 +24,14 @@ import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.ensureBackgroundThread import com.simplemobiletools.launcher.BuildConfig import com.simplemobiletools.launcher.R -import com.simplemobiletools.launcher.extensions.config -import com.simplemobiletools.launcher.extensions.handleAppIconPopupMenu -import com.simplemobiletools.launcher.extensions.homeScreenGridItemsDB -import com.simplemobiletools.launcher.extensions.launchApp +import com.simplemobiletools.launcher.extensions.* import com.simplemobiletools.launcher.fragments.AllAppsFragment import com.simplemobiletools.launcher.fragments.MyFragment import com.simplemobiletools.launcher.fragments.WidgetsFragment import com.simplemobiletools.launcher.helpers.ROW_COUNT +import com.simplemobiletools.launcher.helpers.UNINSTALL_APP_REQUEST_CODE import com.simplemobiletools.launcher.interfaces.FlingListener +import com.simplemobiletools.launcher.models.AppLauncher import com.simplemobiletools.launcher.models.HomeScreenGridItem import kotlinx.android.synthetic.main.activity_main.* @@ -41,6 +43,8 @@ class MainActivity : SimpleActivity(), FlingListener { private var mScreenHeight = 0 private var mIgnoreUpEvent = false private var mIgnoreMoveEvents = false + private var mCachedLaunchers = ArrayList() + private lateinit var mDetector: GestureDetectorCompat override fun onCreate(savedInstanceState: Bundle?) { @@ -81,6 +85,15 @@ class MainActivity : SimpleActivity(), FlingListener { updateStatusbarColor(Color.TRANSPARENT) (all_apps_fragment as AllAppsFragment).setupViews() (widgets_fragment as WidgetsFragment).setupViews() + + ensureBackgroundThread { + if (mCachedLaunchers.isEmpty()) { + mCachedLaunchers = launchersDB.getAppLaunchers() as ArrayList + (all_apps_fragment as AllAppsFragment).gotLaunchers(mCachedLaunchers) + } + + refetchLaunchers() + } } override fun onBackPressed() { @@ -93,6 +106,15 @@ class MainActivity : SimpleActivity(), FlingListener { } } + override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) { + super.onActivityResult(requestCode, resultCode, resultData) + if (requestCode == UNINSTALL_APP_REQUEST_CODE) { + ensureBackgroundThread { + refetchLaunchers() + } + } + } + override fun onConfigurationChanged(newConfig: Configuration) { super.onConfigurationChanged(newConfig) (all_apps_fragment as AllAppsFragment).onConfigurationChanged() @@ -133,6 +155,19 @@ class MainActivity : SimpleActivity(), FlingListener { return true } + private fun refetchLaunchers() { + val launchers = getAllAppLaunchers() + (all_apps_fragment as AllAppsFragment).gotLaunchers(launchers) + + mCachedLaunchers.map { it.packageName }.forEach { packageName -> + if (!launchers.map { it.packageName }.contains(packageName)) { + launchersDB.deleteApp(packageName) + } + } + + mCachedLaunchers = launchers + } + fun startHandlingTouches(touchDownY: Int) { mTouchDownY = touchDownY mCurrentFragmentY = all_apps_fragment.y.toInt() @@ -240,6 +275,30 @@ class MainActivity : SimpleActivity(), FlingListener { hideFragment(all_apps_fragment) } + @SuppressLint("WrongConstant") + fun getAllAppLaunchers(): ArrayList { + val allApps = ArrayList() + val allPackageNames = ArrayList() + val intent = Intent(Intent.ACTION_MAIN, null) + intent.addCategory(Intent.CATEGORY_LAUNCHER) + + val list = packageManager.queryIntentActivities(intent, PackageManager.PERMISSION_GRANTED) + for (info in list) { + val componentInfo = info.activityInfo.applicationInfo + val label = info.loadLabel(packageManager).toString() + val packageName = componentInfo.packageName + val drawable = getDrawableForPackageName(packageName) ?: continue + val placeholderColor = calculateAverageColor(drawable.toBitmap()) + + allPackageNames.add(packageName) + allApps.add(AppLauncher(null, label, packageName, 0, placeholderColor, drawable)) + } + + val launchers = allApps.distinctBy { it.packageName } as ArrayList + launchersDB.insertAll(launchers) + return launchers + } + private fun getDefaultAppPackages() { val homeScreenGridItems = ArrayList() try { @@ -286,4 +345,27 @@ class MainActivity : SimpleActivity(), FlingListener { homeScreenGridItemsDB.insertAll(homeScreenGridItems) } + + // taken from https://gist.github.com/maxjvh/a6ab15cbba9c82a5065d + private fun calculateAverageColor(bitmap: Bitmap): Int { + var red = 0 + var green = 0 + var blue = 0 + val height = bitmap.height + val width = bitmap.width + var n = 0 + val pixels = IntArray(width * height) + bitmap.getPixels(pixels, 0, width, 0, 0, width, height) + var i = 0 + while (i < pixels.size) { + val color = pixels[i] + red += Color.red(color) + green += Color.green(color) + blue += Color.blue(color) + n++ + i += 1 + } + + return Color.rgb(red / n, green / n, blue / n) + } } diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/adapters/LaunchersAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/adapters/LaunchersAdapter.kt index d2cfdb2..20da729 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/adapters/LaunchersAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/adapters/LaunchersAdapter.kt @@ -18,7 +18,6 @@ import com.simplemobiletools.launcher.activities.SimpleActivity import com.simplemobiletools.launcher.extensions.getColumnCount import com.simplemobiletools.launcher.interfaces.AllAppsListener import com.simplemobiletools.launcher.models.AppLauncher -import com.simplemobiletools.launcher.models.HomeScreenGridItem import kotlinx.android.synthetic.main.item_launcher_label.view.* class LaunchersAdapter( @@ -32,6 +31,7 @@ class LaunchersAdapter( private var textColor = activity.getProperTextColor() private var iconPadding = 0 private var wasManualScrollPositionSet = false + private var wereFreshIconsLoaded = false init { calculateIconWidth() @@ -60,9 +60,12 @@ class LaunchersAdapter( } fun updateItems(newItems: ArrayList) { - if (newItems.hashCode() != launchers.hashCode()) { + val oldSum = launchers.sumOf { it.getHashToCompare() } + val newSum = newItems.sumOf { it.getHashToCompare() } + if (oldSum != newSum || !wereFreshIconsLoaded) { launchers = newItems notifyDataSetChanged() + wereFreshIconsLoaded = true } } diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/extensions/Activity.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/extensions/Activity.kt index 6d4b67d..9683c61 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/extensions/Activity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/extensions/Activity.kt @@ -11,6 +11,7 @@ import android.widget.PopupMenu import com.simplemobiletools.commons.extensions.getPopupMenuTheme import com.simplemobiletools.commons.extensions.showErrorToast import com.simplemobiletools.launcher.R +import com.simplemobiletools.launcher.helpers.UNINSTALL_APP_REQUEST_CODE fun Activity.launchApp(packageName: String) { val launchIntent = packageManager.getLaunchIntentForPackage(packageName) @@ -31,7 +32,7 @@ fun Activity.launchAppInfo(packageName: String) { fun Activity.uninstallApp(packageName: String) { Intent(Intent.ACTION_DELETE).apply { data = Uri.fromParts("package", packageName, null) - startActivity(this) + startActivityForResult(this, UNINSTALL_APP_REQUEST_CODE) } } diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/fragments/AllAppsFragment.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/fragments/AllAppsFragment.kt index 89e6086..c699c73 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/fragments/AllAppsFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/fragments/AllAppsFragment.kt @@ -2,23 +2,19 @@ package com.simplemobiletools.launcher.fragments import android.annotation.SuppressLint import android.content.Context -import android.content.Intent -import android.content.pm.PackageManager -import android.graphics.Bitmap -import android.graphics.Color import android.util.AttributeSet import android.view.MotionEvent import android.view.Surface import android.view.WindowManager -import androidx.core.graphics.drawable.toBitmap import com.simplemobiletools.commons.extensions.* -import com.simplemobiletools.commons.helpers.ensureBackgroundThread import com.simplemobiletools.commons.helpers.isRPlus import com.simplemobiletools.commons.views.MyGridLayoutManager import com.simplemobiletools.launcher.R import com.simplemobiletools.launcher.activities.MainActivity import com.simplemobiletools.launcher.adapters.LaunchersAdapter -import com.simplemobiletools.launcher.extensions.* +import com.simplemobiletools.launcher.extensions.getColumnCount +import com.simplemobiletools.launcher.extensions.handleAppIconPopupMenu +import com.simplemobiletools.launcher.extensions.launchApp import com.simplemobiletools.launcher.interfaces.AllAppsListener import com.simplemobiletools.launcher.models.AppLauncher import kotlinx.android.synthetic.main.all_apps_fragment.view.* @@ -31,7 +27,6 @@ class AllAppsFragment(context: Context, attributeSet: AttributeSet) : MyFragment this.activity = activity background.applyColorFilter(activity.getProperBackgroundColor()) setPadding(0, activity.statusBarHeight, 0, 0) - getLaunchers() all_apps_grid.setOnTouchListener { v, event -> if (event.actionMasked == MotionEvent.ACTION_UP || event.actionMasked == MotionEvent.ACTION_CANCEL) { @@ -68,42 +63,7 @@ class AllAppsFragment(context: Context, attributeSet: AttributeSet) : MyFragment return shouldIntercept } - @SuppressLint("WrongConstant") - private fun getLaunchers() { - ensureBackgroundThread { - val cachedLaunchers = context.launchersDB.getAppLaunchers() as ArrayList - gotLaunchers(cachedLaunchers) - - val allApps = ArrayList() - val allPackageNames = ArrayList() - val intent = Intent(Intent.ACTION_MAIN, null) - intent.addCategory(Intent.CATEGORY_LAUNCHER) - - val list = context.packageManager.queryIntentActivities(intent, PackageManager.PERMISSION_GRANTED) - for (info in list) { - val componentInfo = info.activityInfo.applicationInfo - val label = info.loadLabel(context.packageManager).toString() - val packageName = componentInfo.packageName - val drawable = context.getDrawableForPackageName(packageName) ?: continue - val placeholderColor = calculateAverageColor(drawable.toBitmap()) - - allPackageNames.add(packageName) - allApps.add(AppLauncher(null, label, packageName, 0, placeholderColor, drawable)) - } - - val launchers = allApps.distinctBy { it.packageName } as ArrayList - context.launchersDB.insertAll(launchers) - gotLaunchers(launchers) - - cachedLaunchers.map { it.packageName }.forEach { packageName -> - if (!launchers.map { it.packageName }.contains(packageName)) { - context.launchersDB.deleteApp(packageName) - } - } - } - } - - private fun gotLaunchers(appLaunchers: ArrayList) { + fun gotLaunchers(appLaunchers: ArrayList) { val sorted = appLaunchers.sortedBy { it.title.normalizeString().lowercase() }.toMutableList() as ArrayList setupAdapter(sorted) } @@ -166,27 +126,4 @@ class AllAppsFragment(context: Context, attributeSet: AttributeSet) : MyFragment all_apps_popup_menu_anchor.y = y activity?.handleAppIconPopupMenu(all_apps_popup_menu_anchor, packageName) } - - // taken from https://gist.github.com/maxjvh/a6ab15cbba9c82a5065d - private fun calculateAverageColor(bitmap: Bitmap): Int { - var red = 0 - var green = 0 - var blue = 0 - val height = bitmap.height - val width = bitmap.width - var n = 0 - val pixels = IntArray(width * height) - bitmap.getPixels(pixels, 0, width, 0, 0, width, height) - var i = 0 - while (i < pixels.size) { - val color = pixels[i] - red += Color.red(color) - green += Color.green(color) - blue += Color.blue(color) - n++ - i += 1 - } - - return Color.rgb(red / n, green / n, blue / n) - } } diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/helpers/Constants.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/helpers/Constants.kt index 87810e0..7862b83 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/helpers/Constants.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/helpers/Constants.kt @@ -9,3 +9,5 @@ const val WAS_HOME_SCREEN_INIT = "was_home_screen_init" // default home screen grid size const val ROW_COUNT = 6 const val COLUMN_COUNT = 5 + +const val UNINSTALL_APP_REQUEST_CODE = 50 diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/models/AppLauncher.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/models/AppLauncher.kt index 0b2a00d..1cb5715 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/models/AppLauncher.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/models/AppLauncher.kt @@ -29,6 +29,12 @@ data class AppLauncher( fun getBubbleText() = title + fun getHashToCompare() = getStringToCompare().hashCode() + + fun getStringToCompare(): String { + return copy(id = null, drawable = null).toString() + } + override fun compareTo(other: AppLauncher): Int { var result = when { sorting and SORT_BY_TITLE != 0 -> title.normalizeString().lowercase().compareTo(other.title.normalizeString().lowercase())