feat: app repository for list and launch apps
This commit is contained in:
@@ -0,0 +1,41 @@
|
|||||||
|
package top.yeij.hearth.app
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.util.Log
|
||||||
|
|
||||||
|
data class AppInfo(val packageName: String, val label: String, val iconBase64: String?)
|
||||||
|
|
||||||
|
interface AppSource {
|
||||||
|
fun queryLaunchableApps(): List<AppInfo>
|
||||||
|
fun launch(packageName: String): Boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
class AndroidAppSource(private val context: Context) : AppSource {
|
||||||
|
override fun queryLaunchableApps(): List<AppInfo> {
|
||||||
|
val pm = context.packageManager
|
||||||
|
val intent = Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER)
|
||||||
|
return pm.queryIntentActivities(intent, 0).map { ri ->
|
||||||
|
val pkg = ri.activityInfo.packageName
|
||||||
|
AppInfo(pkg, ri.loadLabel(pm).toString(), null /* 图标 base64 在 Task 5 补 */)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun launch(packageName: String): Boolean {
|
||||||
|
val i = context.packageManager.getLaunchIntentForPackage(packageName) ?: return false
|
||||||
|
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
|
context.startActivity(i)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AppRepository(private val source: AppSource) {
|
||||||
|
private val gson = com.google.gson.Gson()
|
||||||
|
|
||||||
|
fun listApps(): String {
|
||||||
|
Log.d("HearthBridge", "listApps: ${source.queryLaunchableApps().size} apps")
|
||||||
|
return gson.toJson(source.queryLaunchableApps())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun launchApp(packageName: String): Boolean = source.launch(packageName)
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package top.yeij.hearth.app
|
||||||
|
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
|
import org.junit.Assert.assertTrue
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class AppRepositoryTest {
|
||||||
|
@Test
|
||||||
|
fun listApps_returnsLauncherAppsJson() {
|
||||||
|
val repo = AppRepository(FakeAppSource(listOf(FakeApp("com.x.music", "音乐"))))
|
||||||
|
val json = repo.listApps()
|
||||||
|
assertTrue(json.contains("\"packageName\":\"com.x.music\""))
|
||||||
|
assertTrue(json.contains("\"label\":\"音乐\""))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun launchApp_unknownPackage_returnsFalse() {
|
||||||
|
val repo = AppRepository(FakeAppSource(emptyList()))
|
||||||
|
assertEquals(false, repo.launchApp("com.nope"))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package top.yeij.hearth.app
|
||||||
|
|
||||||
|
// 测试用假源:返回固定应用列表,避免依赖 Android Context/PackageManager
|
||||||
|
// Test fake source: returns a fixed app list, avoiding dependency on Android Context/PackageManager
|
||||||
|
class FakeAppSource(private val apps: List<AppInfo>) : AppSource {
|
||||||
|
override fun queryLaunchableApps(): List<AppInfo> = apps
|
||||||
|
|
||||||
|
override fun launch(packageName: String): Boolean = apps.any { it.packageName == packageName }
|
||||||
|
}
|
||||||
|
|
||||||
|
// 测试用 AppInfo 构造辅助函数
|
||||||
|
// Test helper to construct an AppInfo
|
||||||
|
fun FakeApp(packageName: String, label: String): AppInfo = AppInfo(packageName, label, null)
|
||||||
Reference in New Issue
Block a user