feat: support Shizuku API to fetch app list

ShizukuApi 增添 getInstalledApplications 方法,包名管理器增添 fetchAppList 方法,優先使用 Shizuku API 獲取應用列表,失敗則回退至標準 PackageManager。
This commit is contained in:
NkBe 2025-11-19 22:18:29 +08:00
parent 83817fba3c
commit c136335aaf
No known key found for this signature in database
GPG Key ID: 525137026FF031DF
2 changed files with 28 additions and 1 deletions

View File

@ -53,15 +53,32 @@ object LSPPackageManager {
private val iconLoader = AppIconLoader(lspApp.resources.getDimensionPixelSize(android.R.dimen.app_icon_size), false, lspApp) private val iconLoader = AppIconLoader(lspApp.resources.getDimensionPixelSize(android.R.dimen.app_icon_size), false, lspApp)
private val appIcon = mutableMapOf<String, ImageBitmap>() private val appIcon = mutableMapOf<String, ImageBitmap>()
suspend fun fetchAppList() { suspend fun fetchAppList() {
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
val pm = lspApp.packageManager val pm = lspApp.packageManager
val collection = mutableListOf<AppInfo>() val collection = mutableListOf<AppInfo>()
pm.getInstalledApplications(PackageManager.GET_META_DATA).forEach { val applicationList: List<ApplicationInfo>
if (ShizukuApi.isPermissionGranted) {
Log.i(TAG, "Fetching app list using Shizuku API")
applicationList = runCatching {
ShizukuApi.getInstalledApplications()
}.getOrElse { t ->
Log.e(TAG, "Shizuku failed to fetch app list, falling back to standard PM", t)
pm.getInstalledApplications(PackageManager.GET_META_DATA)
}
} else {
Log.i(TAG, "Fetching app list using standard PackageManager")
applicationList = pm.getInstalledApplications(PackageManager.GET_META_DATA)
}
applicationList.forEach {
val label = pm.getApplicationLabel(it) val label = pm.getApplicationLabel(it)
collection.add(AppInfo(it, label.toString())) collection.add(AppInfo(it, label.toString()))
appIcon[it.packageName] = iconLoader.loadIcon(it).asImageBitmap() appIcon[it.packageName] = iconLoader.loadIcon(it).asImageBitmap()
} }
collection.sortWith(compareBy(Collator.getInstance(Locale.getDefault()), AppInfo::label)) collection.sortWith(compareBy(Collator.getInstance(Locale.getDefault()), AppInfo::label))
val modules = buildMap { val modules = buildMap {
collection.forEach { if (it.isXposedModule) put(it.app.packageName, it.app.sourceDir) } collection.forEach { if (it.isXposedModule) put(it.app.packageName, it.app.sourceDir) }

View File

@ -51,6 +51,16 @@ object ShizukuApi {
} }
} }
fun getInstalledApplications(): List<ApplicationInfo> {
val userId = Process.myUserHandle().hashCode()
val flags: Long = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
PackageManager.GET_META_DATA.toLong()
}else {
PackageManager.GET_META_DATA.toLong()
}
return iPackageManager.getInstalledApplications(flags, userId).list
}
fun createPackageInstallerSession(params: PackageInstaller.SessionParams): PackageInstaller.Session { fun createPackageInstallerSession(params: PackageInstaller.SessionParams): PackageInstaller.Session {
val sessionId = packageInstaller.createSession(params) val sessionId = packageInstaller.createSession(params)
val iSession = IPackageInstallerSession.Stub.asInterface(iPackageInstaller.openSession(sessionId).asShizukuBinder()) val iSession = IPackageInstallerSession.Stub.asInterface(iPackageInstaller.openSession(sessionId).asShizukuBinder())