@@ -4,8 +4,10 @@ import android.content.BroadcastReceiver
44import android.content.Context
55import android.content.Intent
66import android.content.IntentFilter
7+ import android.content.pm.LauncherApps
78import android.content.pm.PackageManager
89import android.graphics.drawable.Drawable
10+ import android.os.UserHandle
911import androidx.core.content.ContextCompat
1012import kotlinx.coroutines.Dispatchers
1113import kotlinx.coroutines.delay
@@ -60,33 +62,58 @@ val visibleAppInfosFlow by lazy {
6062 }
6163}
6264
63- private val willUpdateAppIds by lazy { MutableStateFlow (emptySet<String >()) }
65+ private val willUpdateAppIds = MutableStateFlow (emptySet<String >())
6466
65- private val packageReceiver by lazy {
66- object : BroadcastReceiver () {
67- val actions = arrayOf(
68- Intent .ACTION_PACKAGE_ADDED ,
69- Intent .ACTION_PACKAGE_REPLACED ,
70- Intent .ACTION_PACKAGE_REMOVED
71- )
67+ private fun dispatchAppUpdate (appId : String ) = willUpdateAppIds.update { it + appId }
7268
69+ private fun registerPackageListener () {
70+ val packageReceiver = object : BroadcastReceiver () {
7371 override fun onReceive (context : Context ? , intent : Intent ? ) {
74- // PACKAGE_REMOVED->PACKAGE_ADDED->PACKAGE_REPLACED
7572 val appId = intent?.data?.schemeSpecificPart ? : return
76- willUpdateAppIds.update { it + appId }
73+ dispatchAppUpdate( appId)
7774 }
78- }.apply {
79- val intentFilter = IntentFilter ().apply {
80- actions.forEach { addAction(it) }
75+ }
76+ ContextCompat .registerReceiver(
77+ app,
78+ packageReceiver,
79+ IntentFilter ().apply {
80+ arrayOf(
81+ Intent .ACTION_PACKAGE_ADDED ,
82+ Intent .ACTION_PACKAGE_REPLACED ,
83+ Intent .ACTION_PACKAGE_REMOVED ,
84+ ).forEach { addAction(it) }
8185 addDataScheme(" package" )
86+ },
87+ ContextCompat .RECEIVER_EXPORTED ,
88+ )
89+
90+ // 某些设备 ACTION_PACKAGE_ADDED 接收不到,使用 LauncherApps.Callback 作为补充
91+ val packageCallback = object : LauncherApps .Callback () {
92+ override fun onPackageAdded (packageName : String , user : UserHandle ) {
93+ dispatchAppUpdate(packageName)
8294 }
83- ContextCompat .registerReceiver(
84- app,
85- this ,
86- intentFilter,
87- ContextCompat .RECEIVER_EXPORTED
88- )
95+
96+ override fun onPackageChanged (packageName : String , user : UserHandle ) {
97+ dispatchAppUpdate(packageName)
98+ }
99+
100+ override fun onPackageRemoved (packageName : String , user : UserHandle ) {
101+ dispatchAppUpdate(packageName)
102+ }
103+
104+ override fun onPackagesAvailable (
105+ p0 : Array <String >,
106+ p1 : UserHandle ,
107+ p2 : Boolean
108+ ) = Unit
109+
110+ override fun onPackagesUnavailable (
111+ p0 : Array <String >,
112+ p1 : UserHandle ,
113+ p2 : Boolean
114+ ) = Unit
89115 }
116+ app.launcherApps.registerCallback(packageCallback)
90117}
91118
92119const val PKG_FLAGS = PackageManager .MATCH_UNINSTALLED_PACKAGES
@@ -134,6 +161,7 @@ private fun updatePartAppInfo(
134161 willUpdateAppIds.update { it - appIds }
135162 val newAppMap = HashMap (userAppInfoMapFlow.value)
136163 val newIconMap = HashMap (userAppIconMapFlow.value)
164+ val oldMapSize = newAppMap.size
137165 appIds.forEach { appId ->
138166 val info = app.getPkgInfo(appId)
139167 if (info != null ) {
@@ -151,6 +179,11 @@ private fun updatePartAppInfo(
151179 updateOtherUserAppInfo(newAppMap)
152180 userAppInfoMapFlow.value = newAppMap
153181 userAppIconMapFlow.value = newIconMap
182+ LogUtils .d(
183+ " updatePartAppInfo" ,
184+ " change=${appIds.map { (if (newAppMap.contains(it)) " +" else " -" ) + it }} " ,
185+ " size=${oldMapSize} ->${newAppMap.size} "
186+ )
154187}
155188
156189val appListAuthAbnormalFlow = MutableStateFlow (false )
@@ -224,7 +257,7 @@ fun updateAllAppInfo(): Unit = updateAppMutex.launchTry(appScope, Dispatchers.IO
224257}
225258
226259fun initAppState () {
227- packageReceiver
260+ registerPackageListener()
228261 updateAllAppInfo()
229262 appScope.launchTry {
230263 shizukuContextFlow.drop(1 ).collect {
0 commit comments