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

在本文中,我将展示如何自动截取用 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值