diff --git a/README.md b/README.md index e934a8f..ed3b512 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,10 @@ 基于 **无障碍** + **高级选择器** + **订阅规则** 的自定义屏幕点击 APP +## 安装 + +- [releases](https://github.com/gkd-kit/gkd/releases) + ## 功能 根据 [高级选择器](https://github.com/gkd-kit/selector) + [订阅规则](https://github.com/gkd-kit/subscription), diff --git a/app/src/main/java/li/songe/gkd/data/BaseSnapshot.kt b/app/src/main/java/li/songe/gkd/data/BaseSnapshot.kt new file mode 100644 index 0000000..5f0afe4 --- /dev/null +++ b/app/src/main/java/li/songe/gkd/data/BaseSnapshot.kt @@ -0,0 +1,15 @@ +package li.songe.gkd.data + +interface BaseSnapshot { + val id: Long + + val appId: String? + val activityId: String? + val appName: String? + val appVersionCode: Int? + val appVersionName: String? + + val screenHeight: Int + val screenWidth: Int + val isLandscape: Boolean +} \ No newline at end of file diff --git a/app/src/main/java/li/songe/gkd/data/ComplexSnapshot.kt b/app/src/main/java/li/songe/gkd/data/ComplexSnapshot.kt new file mode 100644 index 0000000..e3e6a7a --- /dev/null +++ b/app/src/main/java/li/songe/gkd/data/ComplexSnapshot.kt @@ -0,0 +1,67 @@ +package li.songe.gkd.data + +import com.blankj.utilcode.util.AppUtils +import com.blankj.utilcode.util.ScreenUtils +import kotlinx.serialization.Serializable +import li.songe.gkd.service.GkdAbService +import li.songe.gkd.service.activityIdFlow + +@Serializable +data class ComplexSnapshot( + override val id: Long, + + override val appId: String?, + override val activityId: String?, + override val appName: String?, + override val appVersionCode: Int?, + override val appVersionName: String?, + + override val screenHeight: Int, + override val screenWidth: Int, + override val isLandscape: Boolean, + + val device: DeviceInfo, + val nodes: List, +) : BaseSnapshot + + +fun createComplexSnapshot(): ComplexSnapshot { + val currentAbNode = GkdAbService.currentAbNode + val appId = currentAbNode?.packageName?.toString() + val currentActivityId = activityIdFlow.value + val appInfo = if (appId == null) null else AppUtils.getAppInfo(appId) + + return ComplexSnapshot( + id = System.currentTimeMillis(), + + appId = appId, + activityId = currentActivityId, + appName = appInfo?.name, + appVersionCode = appInfo?.versionCode, + appVersionName = appInfo?.versionName, + + screenHeight = ScreenUtils.getScreenHeight(), + screenWidth = ScreenUtils.getScreenWidth(), + isLandscape = ScreenUtils.isLandscape(), + device = DeviceInfo.instance, + nodes = NodeInfo.info2nodeList(currentAbNode) + ) +} + +fun ComplexSnapshot.toSnapshot(): Snapshot { + return Snapshot( + id = id, + + appId = appId, + activityId = activityId, + appName = appName, + appVersionCode = appVersionCode, + appVersionName = appVersionName, + + screenHeight = screenHeight, + screenWidth = screenWidth, + isLandscape = isLandscape, + ) +} + + diff --git a/app/src/main/java/li/songe/gkd/data/DeviceInfo.kt b/app/src/main/java/li/songe/gkd/data/DeviceInfo.kt index 310e7c8..a7d3156 100644 --- a/app/src/main/java/li/songe/gkd/data/DeviceInfo.kt +++ b/app/src/main/java/li/songe/gkd/data/DeviceInfo.kt @@ -5,14 +5,23 @@ import kotlinx.serialization.Serializable @Serializable data class DeviceInfo( - val device: String = Build.DEVICE, - val model: String = Build.MODEL, - val manufacturer: String = Build.MANUFACTURER, - val brand: String = Build.BRAND, - val sdkInt: Int = Build.VERSION.SDK_INT, - val release: String = Build.VERSION.RELEASE, -){ - companion object{ - val instance by lazy { DeviceInfo() } + val device: String, + val model: String, + val manufacturer: String, + val brand: String, + val sdkInt: Int, + val release: String, +) { + companion object { + val instance by lazy { + DeviceInfo( + device = Build.DEVICE, + model = Build.MODEL, + manufacturer = Build.MANUFACTURER, + brand = Build.BRAND, + sdkInt = Build.VERSION.SDK_INT, + release = Build.VERSION.RELEASE, + ) + } } } diff --git a/app/src/main/java/li/songe/gkd/data/FileStatus.kt b/app/src/main/java/li/songe/gkd/data/FileStatus.kt deleted file mode 100644 index b44a8ea..0000000 --- a/app/src/main/java/li/songe/gkd/data/FileStatus.kt +++ /dev/null @@ -1,7 +0,0 @@ -package li.songe.gkd.data - -sealed class FileStatus { - object NotFound : FileStatus() - data class Failure(val e: Exception) : FileStatus() - data class Ok(val data: T) : FileStatus() -} diff --git a/app/src/main/java/li/songe/gkd/data/Snapshot.kt b/app/src/main/java/li/songe/gkd/data/Snapshot.kt index 4e96cd4..0261062 100644 --- a/app/src/main/java/li/songe/gkd/data/Snapshot.kt +++ b/app/src/main/java/li/songe/gkd/data/Snapshot.kt @@ -7,53 +7,30 @@ import androidx.room.Entity import androidx.room.Insert import androidx.room.PrimaryKey import androidx.room.Query -import androidx.room.TypeConverters import androidx.room.Update -import com.blankj.utilcode.util.AppUtils -import com.blankj.utilcode.util.ScreenUtils import kotlinx.coroutines.flow.Flow import kotlinx.serialization.Serializable -import li.songe.gkd.service.GkdAbService -import li.songe.gkd.db.IgnoreConverters import li.songe.gkd.debug.SnapshotExt -import li.songe.gkd.service.activityIdFlow import java.io.File -@TypeConverters(IgnoreConverters::class) @Entity( tableName = "snapshot", ) @Serializable data class Snapshot( - @PrimaryKey @ColumnInfo(name = "id") val id: Long = System.currentTimeMillis(), - @ColumnInfo(name = "app_id") val appId: String? = null, - @ColumnInfo(name = "activity_id") val activityId: String? = null, - @ColumnInfo(name = "app_name") val appName: String? = AppUtils.getAppName(appId), - @ColumnInfo(name = "app_version_code") val appVersionCode: Int? = appId?.let { - AppUtils.getAppVersionCode( - appId - ) - }, - @ColumnInfo(name = "app_version_name") val appVersionName: String? = appId?.let { - AppUtils.getAppVersionName( - appId - ) - }, + @PrimaryKey @ColumnInfo(name = "id") override val id: Long, - @ColumnInfo(name = "screen_height") val screenHeight: Int = ScreenUtils.getScreenHeight(), - @ColumnInfo(name = "screen_width") val screenWidth: Int = ScreenUtils.getScreenWidth(), + @ColumnInfo(name = "app_id") override val appId: String?, + @ColumnInfo(name = "activity_id") override val activityId: String?, + @ColumnInfo(name = "app_name") override val appName: String?, + @ColumnInfo(name = "app_version_code") override val appVersionCode: Int?, + @ColumnInfo(name = "app_version_name") override val appVersionName: String?, - @ColumnInfo(name = "is_landscape") val isLandscape: Boolean = ScreenUtils.isLandscape(), + @ColumnInfo(name = "screen_height") override val screenHeight: Int, + @ColumnInfo(name = "screen_width") override val screenWidth: Int, + @ColumnInfo(name = "is_landscape") override val isLandscape: Boolean, - @ColumnInfo(name = "device") val device: String = DeviceInfo.instance.device, - @ColumnInfo(name = "model") val model: String = DeviceInfo.instance.model, - @ColumnInfo(name = "manufacturer") val manufacturer: String = DeviceInfo.instance.manufacturer, - @ColumnInfo(name = "brand") val brand: String = DeviceInfo.instance.brand, - @ColumnInfo(name = "sdk_int") val sdkInt: Int = DeviceInfo.instance.sdkInt, - @ColumnInfo(name = "release") val release: String = DeviceInfo.instance.release, - - @ColumnInfo(name = "_1") val nodes: List = emptyList(), -) { + ) : BaseSnapshot { val screenshotFile by lazy { File( @@ -63,23 +40,7 @@ data class Snapshot( ) } - companion object { - fun current( - includeNode: Boolean = true, - ): Snapshot { - val currentAbNode = GkdAbService.currentAbNode - val appId = currentAbNode?.packageName?.toString() - val currentActivityId = activityIdFlow.value - return Snapshot( - appId = appId, - activityId = currentActivityId, - nodes = if (includeNode) NodeInfo.info2nodeList(currentAbNode) else emptyList() - ) - } - } - @Dao - @TypeConverters(IgnoreConverters::class) interface SnapshotDao { @Update suspend fun update(vararg objects: Snapshot): Int @@ -94,3 +55,8 @@ data class Snapshot( fun query(): Flow> } } + + + + + diff --git a/app/src/main/java/li/songe/gkd/db/IgnoreConverters.kt b/app/src/main/java/li/songe/gkd/db/IgnoreConverters.kt deleted file mode 100644 index 3443eae..0000000 --- a/app/src/main/java/li/songe/gkd/db/IgnoreConverters.kt +++ /dev/null @@ -1,14 +0,0 @@ -package li.songe.gkd.db - -import androidx.room.TypeConverter -import li.songe.gkd.data.NodeInfo - -object IgnoreConverters { - @TypeConverter - @JvmStatic - fun listToCol(list: List): String = "" - - @TypeConverter - @JvmStatic - fun colToList(value: String): List = emptyList() -} \ No newline at end of file diff --git a/app/src/main/java/li/songe/gkd/debug/SnapshotExt.kt b/app/src/main/java/li/songe/gkd/debug/SnapshotExt.kt index 0d895bd..a1d5ca6 100644 --- a/app/src/main/java/li/songe/gkd/debug/SnapshotExt.kt +++ b/app/src/main/java/li/songe/gkd/debug/SnapshotExt.kt @@ -7,14 +7,15 @@ import com.blankj.utilcode.util.ZipUtils import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.withContext import kotlinx.coroutines.withTimeoutOrNull import kotlinx.serialization.encodeToString import li.songe.gkd.app +import li.songe.gkd.data.ComplexSnapshot import li.songe.gkd.data.RpcError -import li.songe.gkd.data.Snapshot +import li.songe.gkd.data.createComplexSnapshot +import li.songe.gkd.data.toSnapshot import li.songe.gkd.db.DbSet import li.songe.gkd.service.GkdAbService import li.songe.gkd.util.Singleton @@ -62,9 +63,9 @@ object SnapshotExt { } } - val captureLoading = MutableStateFlow(false) + private val captureLoading = MutableStateFlow(false) - suspend fun captureSnapshot(): Snapshot { + suspend fun captureSnapshot(): ComplexSnapshot { if (captureLoading.value) { throw RpcError("正在截屏,不可重复截屏") } @@ -75,7 +76,7 @@ object SnapshotExt { throw RpcError("无障碍不可用") } - val snapshotDef = coroutineScope { async(Dispatchers.IO) { Snapshot.current() } } + val snapshotDef = coroutineScope { async(Dispatchers.IO) { createComplexSnapshot() } } val bitmapDef = coroutineScope { async(Dispatchers.IO) { GkdAbService.currentScreenshot() ?: withTimeoutOrNull(3_000) { @@ -99,7 +100,7 @@ object SnapshotExt { stream.close() val text = Singleton.json.encodeToString(snapshot) File(getSnapshotPath(snapshot.id)).writeText(text) - DbSet.snapshotDao.insert(snapshot) + DbSet.snapshotDao.insert(snapshot.toSnapshot()) } return snapshot } finally {