feat: 截屏快照

This commit is contained in:
lisonge 2023-12-08 23:15:29 +08:00
parent d333f3458a
commit ba4c60dcde
3 changed files with 60 additions and 16 deletions

View File

@ -66,21 +66,28 @@ object SnapshotExt {
private val captureLoading = MutableStateFlow(false)
suspend fun captureSnapshot(): ComplexSnapshot {
suspend fun captureSnapshot(skipScreenshot: Boolean = false): ComplexSnapshot {
if (!GkdAbService.isRunning()) {
throw RpcError("无障碍不可用")
}
if (captureLoading.value) {
throw RpcError("正在截屏,不可重复截屏")
throw RpcError("正在保存快照,不可重复操作")
}
captureLoading.value = true
ToastUtils.showShort("正在捕获快照...")
ToastUtils.showShort("正在保存快照...")
try {
val snapshotDef = coroutineScope { async(Dispatchers.IO) { createComplexSnapshot() } }
val bitmapDef = coroutineScope {
val bitmapDef = coroutineScope {// TODO 也许在分屏模式下可能需要处理
async(Dispatchers.IO) {
if (skipScreenshot) {
LogUtils.d("跳过截屏,即将使用空白图片")
Bitmap.createBitmap(
ScreenUtils.getScreenWidth(),
ScreenUtils.getScreenHeight(),
Bitmap.Config.ARGB_8888
)
} else {
GkdAbService.currentScreenshot() ?: withTimeoutOrNull(3_000) {
if (!ScreenshotService.isRunning()) {
return@withTimeoutOrNull null
@ -95,6 +102,7 @@ object SnapshotExt {
}
}
}
}
var bitmap = bitmapDef.await()
if (storeFlow.value.hideSnapshotStatusBar) {

View File

@ -38,6 +38,7 @@ import li.songe.gkd.data.SubsVersion
import li.songe.gkd.data.SubscriptionRaw
import li.songe.gkd.data.getActionFc
import li.songe.gkd.db.DbSet
import li.songe.gkd.debug.SnapshotExt
import li.songe.gkd.shizuku.useSafeGetTasksFc
import li.songe.gkd.util.client
import li.songe.gkd.util.launchTry
@ -148,10 +149,13 @@ class GkdAbService : CompositionAbService({
newQueryTask()
}
}
val skipAppIds = setOf("com.android.systemui")
onAccessibilityEvent { event ->
if (event == null) return@onAccessibilityEvent
if (event == null || event.packageName == null) return@onAccessibilityEvent
if (!(event.eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED || event.eventType == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED)) return@onAccessibilityEvent
if (skipAppIds.any { id -> id.contentEquals(event.packageName) }) return@onAccessibilityEvent
if (event.eventType == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) {
if (event.eventTime - appChangeTime > 5_000) { // app 启动 5s 内关闭限制
if (event.eventTime - lastContentEventTime < 100) {
@ -346,6 +350,24 @@ class GkdAbService : CompositionAbService({
wm.removeView(aliveView)
}
}
onAccessibilityEvent { e ->
if (!storeFlow.value.captureScreenshot) return@onAccessibilityEvent
e ?: return@onAccessibilityEvent
val appId = e.packageName ?: return@onAccessibilityEvent
val appCls = e.className ?: return@onAccessibilityEvent
if (appId.contentEquals("com.miui.screenshot") &&
e.eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED &&
!e.isFullScreen &&
appCls.contentEquals("android.widget.RelativeLayout") &&
e.text.firstOrNull()?.contentEquals("截屏缩略图") == true // [截屏缩略图, 截长屏, 发送]
) {
LogUtils.d("captureScreenshot", e)
scope.launchTry(Dispatchers.IO) {
SnapshotExt.captureSnapshot(skipScreenshot = true)
}
}
}
}) {
companion object {

View File

@ -260,6 +260,20 @@ fun DebugPage() {
)
)
}
Divider()
TextSwitch(
name = "截屏快照",
desc = "当用户截屏时保存快照(需手动替换快照图片),仅支持MIUI14",
checked = store.captureScreenshot
) {
updateStorage(
storeFlow, store.copy(
captureScreenshot = it
)
)
}
Divider()
TextSwitch(
name = "隐藏快照状态栏",