使用 Jetpack Compose 自动截取 Android 应用程序的屏幕截图

Android Studio 4.2 新变化 按变体配置应用签名 现在可以按变体在 Android Gradle 插件中启用或停用应用签名。 下面的示例展示了如何在 Kotlin 或 Groovy 中使用 onVariants() 方法按变体设置应用签名: 针对 JDK 11 优化 Gradle 构建 在 Android Studio 中运行时,Gradle 构建工具使用 Android Studio 中设置的默认 JDK 版本。在以前的版本中,默认情况下使用 JDK 8;但在 4.2 中,默认的 JDK 版本为 JDK 11。JDK 11 的这项更新 阅读详情

在本文中,我将展示如何自动截取用 Jetpack Compose 编写的 Android 应用程序的屏幕截图。

1.创建测试

从设置仪器测试开始。此测试不会检查任何内容,它只会执行单击按钮和截取应用程序等操作。

首先,设置测试app/build.gradle:

android {
    // other properties
    defaultConfig {
           // other properties
           testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" // Add this line
    }
}
// ...

dependencies {
    // other dependencies
    androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version" // Add this line
}

现在,假设这是我们要截屏的 Activity:

package com.example

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Button
import androidx.compose.material.Scaffold
import androidx.compose.material.Text
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp

class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Scaffold {
                Column(
                    verticalArrangement = Arrangement.spacedBy(16.dp),
                    modifier = Modifier.padding(16.dp),
                ) {
                    var greetingVisible by remember { mutableStateOf(false) }
                    if (greetingVisible) {
                        Text("Hello!")
                    }
                    Button(onClick = { greetingVisible = true }) {
                        Text("Show greeting")
                    }
                }
            }
        }
    }
}

androidTest在目录中创建测试:

package com.example

import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class ScreenshotTest {

    @get:Rule
    val rule = createAndroidComposeRule<MainActivity>()

    @Test
    fun makeScreenshot() {
        // TODO: Take screenshot before clicking button
        rule
            .onNodeWithText("Show greeting")
            .performClick()
        // TODO: Take screenshot after clicking button
    }
}

2. 截图

为了截取屏幕截图并将其保存为图像,请使用以下功能:

private fun ComposeContentTestRule.takeScreenshot(file: String) {
    onRoot()
        .captureToImage()
        .asAndroidBitmap()
        .save(file)
}

private fun Bitmap.save(file: String) {
    val path = InstrumentationRegistry.getInstrumentation().targetContext.filesDir.canonicalPath
    FileOutputStream("$path/$file").use { out ->
        compress(Bitmap.CompressFormat.PNG, 100, out)
    }
}

这是对应用程序进行截图的完整测试:

package com.example

import android.graphics.Bitmap
import androidx.compose.ui.graphics.asAndroidBitmap
import androidx.compose.ui.test.captureToImage
import androidx.compose.ui.test.junit4.ComposeContentTestRule
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.onRoot
import androidx.compose.ui.test.performClick
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import java.io.FileOutputStream

@RunWith(AndroidJUnit4::class)
class ScreenshotTest {

    @get:Rule
    val rule = createAndroidComposeRule<MainActivity>()

    @Test
    fun makeScreenshot() {
        rule.takeScreenshot("before-click.png")
        rule
            .onNodeWithText("Show greeting")
            .performClick()
        rule.takeScreenshot("after-click.png")
    }
}


private fun ComposeContentTestRule.takeScreenshot(file: String) {
    onRoot()
        .captureToImage()
        .asAndroidBitmap()
        .save(file)
}

private fun Bitmap.save(file: String) {
    val path = InstrumentationRegistry.getInstrumentation().targetContext.filesDir.canonicalPath
    FileOutputStream("$path/$file").use { out ->
        compress(Bitma## 标题p.CompressFormat.PNG, 100, out)
    }
}

3.在主机PC上保存截图

代码截取的所有屏幕截图都存储在模拟器或手机中。

要手动获取它们,您可以使用 Android Studio 中构建的设备文件资源管理器。截图可以在以下目录中找到:

/data/data/$applicationId/files/

此过程可以通过 ADB 命令自动执行:

adb root
adb pull /data/data/com.example/files/ screenshots

额外的信息

关闭动画

在某些情况下,需要关闭动画才能运行测试。为此,请使用以下命令:

adb shell settings put global window_animation_scale 0
adb shell settings put global animator_duration_scale 0
adb shell settings put global transition_animation_scale 0

一些用户报告说他们的设备需要重新启动才能应用这些设置。如果这是您的情况,您可以使用以下命令:

adb shell "su 0 am start -a android.intent.action.REBOOT"

关闭键盘

软键盘可以通过裁剪来影响屏幕截图。要禁用它,请使用以下命令:

# Show all keyboards (-a for all, -s for short summary).
adb shell ime list -s -a

# Disable keyboards:
adb shell ime disable <<keyboard id>>
# Example: adb shell ime disable com.android.inputmethod.latin

最后我还整理了很多Android中高级的PDF技术文档。以及一些大厂面试真题解析文档。需要的朋友都可以点击文末微信卡片即可直接免费获取

image

KataScreenshotKotlin:使用Kotlin的Android开发人员的Kata截图。 主要目标是练习UI屏幕截图测试 立即下载

相关推荐

STM32--基于STM32F103C8T6的OV7670摄像头显示

使用 STM32F103C8T6 微控制器驱动 OV7670 摄像头模组,并将图像数据显示在屏幕上,是嵌入式系统中常见的图像采集与显示应用。OV7670 是一款 CMOS VGA 图像传感器,具有高灵敏度、低电压等特点,适用于嵌入式应用。而 STM32F103C8T6 是一款常用的 MCU 控制器,具有丰富的管脚资源和较高的工作频率。

duierrorshuobu的博客 2146

Compose ScreenshotBox:轻松实现截图功能的强大工具

Compose ScreenshotBox:轻松实现截图功能的强大工具 在现代移动应用开发中,截图功能已成为许多应用不可或缺的一部分。无论是用于用户反馈、调试还是内容分享,截图功能都能大大提升用户体验。今天,我们要介绍的是一个强大的开源项目——Compose ScreenshotBox,它能够帮助开发者轻松地在Jetpack Compose中实现截图功能。 项目介绍 Compose Screens...

gitblog_01152的博客 1112

国产麒麟系统下Kettle安装避坑指南:解决aarch64架构不兼容问题

本文针对在国产麒麟系统上安装Kettle时遇到的aarch64架构不兼容问题,提供了详细的解决方案。通过剖析错误根源,指导用户获取并放置正确的SWT库文件,并修改启动脚本,成功解决“平台不支持”的报错,确保ETL工具在ARM架构的国产化环境中顺利运行。

weixin_29214691的博客 278

推荐开源项目:Compose ScreenshotBox

推荐开源项目:Compose ScreenshotBox 项目简介 Compose ScreenshotBox 是一个专为 Jetpack Compose 设计的开源库,它提供了便捷的方法来捕获 Composable 界面的截图,并可选择性地在用户操作或定期执行这一功能。通过这个库,你可以轻松获取屏幕快照并以 Bitmap 或者 ImageBitmap 的形式展示。 项目技术分析 Compose ...

gitblog_00003的博客 576

驯服电源尖峰:从BUCK/BOOST环路剖析到高di/dt噪声的实战抑制

本文深入探讨了电源系统中高di/dt噪声的产生机制及抑制方法,通过BUCK/BOOST电路的环路分析,揭示了电流路径不连续导致的电压尖峰问题。文章提供了实用的PCB布局技巧和噪声抑制策略,包括最短回路原则、铺铜优化和过孔阵列战术,帮助工程师有效降低EMI噪声,提升电源系统的稳定性。

weixin_29587015的博客 275

关于Arduino中的常用函数

一、I/O函数 二、时间函数 三、数学函数 abs 返回其参数的无符号值 【abs(12)返回12,abs(-12)也返回12】 constrain 限制一个数字以阻止它超出范围。第一个参数是被限制的数字,第二个参数是范围区间的开始,第三个参数是允许的数字范围区间的结尾。 【constrain(8,1,10)返回8,constrain(11,1,10)返回10,constrain(0,1,10)返回1】 map 将一个范围内的数字映射到另一个范围。第一个参数是要映射到数字,第二个和第三个参数是from范围(

TREE的博客 7323

Android 多种截屏方式介绍

做项目的时候遇到截图的功能要求(部分截图、截长图),感觉挺有意思的,所有下来查阅了下资料,学习了下原理。在此记录下,供大家参考 效果图: 原理:计算好图片的宽度与高度,通过Bitmap 于Canvas 绘制好即可,不同之处是获取宽高方式不同。 关键代码如下: 整个屏幕截屏(不包含状态栏) public Bitmap screenShot() { View v...

Mr_Leixiansheng的博客 3466

数字IC后端时序违例修复:setup/hold冲突与时钟树优化实战

时序收敛是数字IC后端设计中最关键的环节之一,直接影响芯片能否在目标频率下稳定工作。建立时间与保持时间的本质是寄存器对数据稳定性的物理约束,而实际工程中,setup违例和hold违例往往此消彼长,冲突的根源在于数据路径与时钟路径的延迟匹配。时钟树综合(CTS)作为连接逻辑与物理的关键步骤,其skew、insertion delay和transition的优化直接决定了时序修复的成败。通过useful skew技术、合理的单元替换和路径结构调整,可以系统性地解决setup/hold冲突,实现时序收敛。本文结合

weixin_28292761的博客 224

Compose-Screenshot 项目教程

Compose-Screenshot 项目教程 1. 项目介绍 Compose-Screenshot 是一个用于在 Jetpack Compose 中捕获和处理截图的开源项目。该项目允许开发者轻松地对 Composable 函数进行截图,并将其转换为 Bitmap 或 ImageBitmap。无论是单次截图还是周期性截图,Compose-Screenshot 都提供了灵活的解决方案。 2. 项目快...

gitblog_00860的博客 1620

高通跃龙QCS6490部署yolov11_obb实战:QNN SDK工具链全解析与避坑指南

本文详细解析了在高通跃龙QCS6490平台上部署yolov11_obb模型的实战过程,重点介绍了QNN SDK工具链的使用与优化技巧。从环境配置、模型转换到性能调优,提供了全面的避坑指南和DSP加速配置建议,帮助开发者高效实现旋转框检测任务在边缘设备上的部署。

weixin_29232121的博客 305

海洋CMS admin_notify.php 远程代码执行漏洞复现(CVE-2024-30565)

海洋CMS admin_notify.php 接口处存在远程代码执行漏洞,经过身份验证的远程攻击者可利用该漏洞执行任意代码,写入后门文件,进而控制整个web服务器。

0xSec 2719

android--布局组件截图

android应用中,我们可能需要对一些布局截图显示,比如:在editText中加入图片,或者加入一个录音布局,布局中有图标,有录音文件大小和录音名字。一般步骤: 1 获取自定义布局 2 初始化控件值 3 打开图像缓存 4 测量大小 5 视图布局再获取视图view对象如:自定义布局文件:task_recoder_item.xml<?xml version="1.0" encodi

翻滚吧!程序猿! 2757

【AI理论学习】手把手推导扩散模型:Diffusion Models(DDPM)

生成扩散模型DDPM如下图所示分为前向、逆向两个过程,它首先通过不断往原始清晰数据中添加噪声使其变成标准高斯噪声(前向过程),而后期望从标准高斯噪声中还原原始数据(逆向过程)。若能实现,那便可从已知的标准高斯分布中采样一个噪声数据,而后利用DDPM模型生成符合原始数据分布的新数据。 Diffusion模型包含两个过程:数学符号:y∝xy\propto xy∝x:y正比于x,即y随着x增大而线性增大。 条件概率:贝叶斯公式:p(A∣B)=p(B∣A)×p(A)p(B)p(A|B)=\frac{p(B|A)\

小哲的博客 1512

Android Studio 中的 Gemini 现已支持多模态图像附件功能

您可以将生成的代码理解为高效的起点,从而加快您的界面开发工作流程。借助这项技术,Android Studio 中的 Gemini 能够理解简单的线框图,并将其转换为可运行的 Jetpack Compose 代码。您还可以添加相关的代码片段,以获得更精确的帮助。对于更复杂的界面,请优化您的提示以明确所需的特定功能。上传 Now in Android 架构图,并输入 "解释此图中的组件和数据流" 或 "撰写有关此图的文档"。借助 Gemini 的多模态能力,您还可以尝试上传图表图像,并要求提供解释或生成文档。

谷歌开发者 428

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

jetpack compose 组件截图 出现Software rendering doesn‘t support hardware bitmaps

/ 例如:Image(bitmap = it.asImageBitmap(), contentDescription = "Screenshot")Software rendering doesn't support hardware bitmaps 崩溃问题。// 获取当前的视图并捕获截图。重要问题 view.drawToBitmap() 时可能会出现。// 使用图片展示或保存截图。// 显示被截图的内容。原因是 显示图片时 应该设置。

zhouchenjia的博客 840

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

UIAutomator截屏

UIAutomator截屏 第一次博客 在学习使用UIAutomator写Android的自动化case的过程中,遇到了需要截取手机屏幕的操作。 UIAutomator为我们提供了截取屏幕的接口基本代码如下: Instrumentation instrumentation = InstrumentationRegistry,getInstrumentation(); UiDevice ...

lee2315的博客 2040

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Android 截长图一种实现方式

如果截取长图?    个别android厂商 手机自带有截取长图的功能,比如我的 vivo x9 plus手机就有截取长图的功能    &lt;GIF图片&gt;    通过分析系统截图行为方式,大概逻辑如下:            1: 获取View在屏幕渲染的内容            2:滚动View,不断获取View渲染的内容,存储到一个集合中            3:将集合中内容,一个...

lixiaodong_的博客 4694

Android Jetpack Compose 用计数器demo理解Compose UI 更新的关键-------状态管理(State)

假如我们把Composable的执行看成是一个函数的运算的话,那么状态就是函数的参数,输出就是生成的布局。由于唯一的参数决定唯一的输出,所以只有当函数的参数发生了变化,生成的布局才会相应的跟着变化。

知识应该共享,创造才应收费 1782

从理论到实践:使用gh_mirrors/tra/training构建你的第一个深度学习模型

gh_mirrors/tra/training是MLPerf™训练基准的参考实现仓库,为新手和普通用户提供了构建深度学习模型的完整框架和工具。无论你是深度学习领域的初学者,还是想要快速上手实际项目的开发者,这个项目都能帮助你从理论走向实践,轻松搭建属于自己的深度学习模型。 ## 项目概述:开启深度学习之旅的得力助手 🚀 gh_mirrors/tra/training包含了MLPerf套件中基

gitblog_00556的博客 1052

Android中使用代码截图的各种方法总结

public class ScreenShot { private BufferedImage image = null; /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub AndroidDebugBridge.init(false)

千里之外 13万+

好奇心驱使,看看Android Jetpack Compose 1.5.1性能到底有没有提升?

使用Perfetto工具和大家一起测一测,这次新鲜出炉的 1.5.1 版本是否真的如官方所说的一样性能有所提升?

农贤钢的专栏 1579

Jetpack Compose截图测试:使用Shot实现声明式UI的视觉验证

Shot是一款专为Android平台设计的截图测试库,能够帮助开发者轻松实现Jetpack Compose声明式UI的视觉验证。通过自动化截图对比和详细的测试报告,Shot让UI测试变得简单高效,确保应用界面在迭代过程中保持一致性。 ## 📱 为什么选择Shot进行Compose截图测试? Jetpack Compose作为现代Android UI开发框架,以其声明式语法和组件化特性深受开发

gitblog_00869的博客 837

【Android】Kotlin实现选取相片&拍照&截图&图片上传(兼容android 9-14)(超详细完整版)

① 打开摄像头/访问相册权限 (兼容android 9-14) ② 选取相片/拍摄, 存放临时路径 ③ 引入CropImage依赖, 配置, 打开cropImageActivity, 进行截图操作 ④ 封装图片上传网络请求, 上传图片

每天进步一点点, 靠近小目标一点点~ 2304

Android代码截图并分享

对屏幕进行截图(直接软件可视部分) public Bitmap captureScreen() { getWindow().getDecorView().setDrawingCacheEnabled(true); Bitmap bitmap = getWindow().getDecorView().getDrawingCache();

小杨的博客 826

Android 使用命令截图

1.使用 screencap 截图: 截图无 UI 效果。 截图保存的路径可自定义,但需要是可读可写的路径才行,如 data/ 目录或 外接U盘里, screencap -p data/test.png 2.模拟发送截图按键 模拟发送系统截图按键 KEYCODE_SYSRQ ,截图有 UI 效果。 input keyevent KEYCODE_SYSRQ 截图保存的路径是 mnt/sdcard/Pictures/Screenshots/ 文件夹,也就是 storage/emulated/0/Pictu

weixin_44021334的博客 7449
上一篇: 如何通过调用实现 Android 应用的前台服务和深度链接?带有代码示例
下一篇: 最常用的 Android Studio 快捷键
不秃头de程序猿
博客等级 码龄5年 4089粉丝 1478原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值