|
1 | 1 | package com.fredhappyface.ewesticker |
2 | 2 |
|
| 3 | +import android.content.ContentValues |
| 4 | +import android.content.Context |
| 5 | +import android.graphics.Bitmap |
| 6 | +import android.os.Environment |
| 7 | +import android.provider.MediaStore |
| 8 | +import androidx.test.core.app.ActivityScenario |
| 9 | +import androidx.test.core.app.takeScreenshot |
| 10 | +import android.app.UiModeManager |
| 11 | +import android.content.res.Configuration |
3 | 12 | import androidx.test.ext.junit.runners.AndroidJUnit4 |
4 | 13 | import androidx.test.platform.app.InstrumentationRegistry |
5 | | -import org.junit.Assert.assertEquals |
| 14 | +import org.junit.Before |
| 15 | +import org.junit.Rule |
6 | 16 | import org.junit.Test |
| 17 | +import org.junit.rules.TestName |
7 | 18 | import org.junit.runner.RunWith |
| 19 | +import java.io.OutputStream |
| 20 | +import java.util.Locale |
8 | 21 |
|
9 | | -/** |
10 | | - * Instrumented test, which will execute on an Android device. |
| 22 | +/* |
| 23 | + * Illustrates usage of APIs to capture a bitmap from view and saving it to test storage. |
11 | 24 | * |
12 | | - * See [testing documentation](http://d.android.com/tools/testing). |
| 25 | + * When this test is executed via gradle managed devices, the saved image files will be stored at |
| 26 | + * build/outputs/managed_device_android_test_additional_output/debugAndroidTest/managedDevice/nexusOneApi30/ |
13 | 27 | */ |
14 | 28 | @RunWith(AndroidJUnit4::class) |
15 | | -class ExampleInstrumentedTest { |
| 29 | +class ScreenshotTest { |
| 30 | + |
| 31 | + // a handy JUnit rule that stores the method name, so it can be used to generate unique |
| 32 | + // screenshot files per test method |
| 33 | + @get:Rule |
| 34 | + var nameRule: TestName = TestName() |
| 35 | + |
| 36 | + private val appContext: Context = InstrumentationRegistry.getInstrumentation().targetContext |
| 37 | + private lateinit var activityScenario: ActivityScenario<MainActivity> |
| 38 | + |
| 39 | + @Before |
| 40 | + fun setUp() { |
| 41 | + // Launch the main activity of your app |
| 42 | + activityScenario = ActivityScenario.launch(MainActivity::class.java) |
| 43 | + } |
| 44 | + |
| 45 | + |
| 46 | + /** |
| 47 | + * Captures and saves an image of the entire device screen to storage. |
| 48 | + */ |
| 49 | + @Test |
| 50 | + fun mainActivityLight() { |
| 51 | + val bitmap = takeScreenshot() |
| 52 | + saveBitmapToMediaStore(appContext, bitmap, nameRule.methodName) |
| 53 | + assert(true) |
| 54 | + } |
| 55 | + |
16 | 56 | @Test |
17 | | - fun useAppContext() { |
18 | | - // Context of the app under test. |
19 | | - val appContext = InstrumentationRegistry.getInstrumentation().targetContext |
20 | | - assertEquals("com.fredhappyface.ewesticker", appContext.packageName) |
| 57 | + fun mainActivityDark() { |
| 58 | + val uiModeManager = appContext.getSystemService(Context.UI_MODE_SERVICE) as UiModeManager |
| 59 | + uiModeManager.nightMode = UiModeManager.MODE_NIGHT_YES |
| 60 | + activityScenario.recreate() |
| 61 | + |
| 62 | + val bitmap = takeScreenshot() |
| 63 | + saveBitmapToMediaStore(appContext, bitmap, nameRule.methodName) |
| 64 | + |
| 65 | + |
| 66 | + uiModeManager.nightMode = UiModeManager.MODE_NIGHT_NO |
| 67 | + |
| 68 | + assert(true) |
| 69 | + } |
| 70 | + |
| 71 | + @Test |
| 72 | + fun mainActivityFr() { |
| 73 | + setLocale("fr") |
| 74 | + val bitmap = takeScreenshot() |
| 75 | + saveBitmapToMediaStore(appContext, bitmap, nameRule.methodName) |
| 76 | + assert(true) |
| 77 | + } |
| 78 | + |
| 79 | + |
| 80 | + private fun setLocale(languageCode: String) { |
| 81 | + val locale = Locale(languageCode) |
| 82 | + val config = Configuration() |
| 83 | + config.setLocale(locale) |
| 84 | + InstrumentationRegistry.getInstrumentation().targetContext.resources.updateConfiguration( |
| 85 | + config, |
| 86 | + null |
| 87 | + ) |
| 88 | + } |
| 89 | + |
| 90 | + private fun saveBitmapToMediaStore(context: Context, bitmap: Bitmap, fileName: String) { |
| 91 | + // Define the subdirectory where the image will be saved (e.g., "Screenshots") |
| 92 | + val subdirectory = "Screenshots/" |
| 93 | + |
| 94 | + // Prepare the content values for the MediaStore |
| 95 | + val values = ContentValues() |
| 96 | + values.put(MediaStore.Images.Media.DISPLAY_NAME, "screenshot_$fileName") |
| 97 | + values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg") |
| 98 | + values.put( |
| 99 | + MediaStore.MediaColumns.RELATIVE_PATH, |
| 100 | + "${Environment.DIRECTORY_DCIM}/$subdirectory" |
| 101 | + ) |
| 102 | + values.put(MediaStore.Images.Media.IS_PENDING, 1) // Mark the image as pending |
| 103 | + |
| 104 | + // Insert the image into the MediaStore |
| 105 | + val uri = |
| 106 | + context.contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values) |
| 107 | + uri?.let { |
| 108 | + try { |
| 109 | + // Open an OutputStream to the newly created image |
| 110 | + val os: OutputStream? = context.contentResolver.openOutputStream(uri) |
| 111 | + |
| 112 | + // Compress and save the bitmap to the OutputStream |
| 113 | + bitmap.compress(Bitmap.CompressFormat.JPEG, 100, os) |
| 114 | + os?.close() |
| 115 | + |
| 116 | + // Mark the image as non-pending |
| 117 | + values.clear() |
| 118 | + values.put(MediaStore.Images.Media.IS_PENDING, 0) |
| 119 | + context.contentResolver.update(uri, values, null, null) |
| 120 | + } catch (e: Exception) { |
| 121 | + e.printStackTrace() |
| 122 | + } |
| 123 | + } |
21 | 124 | } |
22 | 125 | } |
| 126 | + |
| 127 | + |
0 commit comments