How to take screenshot of Composable functions in Jetpack Compose

Assuming a drawing app that allows users to export a canvas, or a simple image editing app that users can share the edited photo, there might be limited ways to convert a composable to a bitmap.


In this post, I will share my experience of using standard methods to convert a composable into a bitmap and store it as a PNG in internal storage.

According to official docs you can access the view version of your composable function using LocalView.current, and export that view to a bitmap file like this (the following code goes inside the composable function):

    val view = LocalView.current
    val context = LocalContext.current

    val handler = Handler(Looper.getMainLooper())
    handler.postDelayed(Runnable {
        val bmp = Bitmap.createBitmap(view.width, view.height,
            Bitmap.Config.ARGB_8888).applyCanvas {
            view.draw(this)
        }
        bmp.let {
            File(context.filesDir, "screenshot.png")
                .writeBitmap(bmp, Bitmap.CompressFormat.PNG, 85)
        }
    }, 1000)

The writeBitmap method is a simple extension function for File class. Example:

private fun File.writeBitmap(bitmap: Bitmap, format: Bitmap.CompressFormat, quality: Int) {
    outputStream().use { out ->
        bitmap.compress(format, quality, out)
        out.flush()
    }
}

If you liked this approach, vote for the stackoverflow post. Looking forward to read your feedback soon! 🙂

Arduino USB Terminal

During the isolation period caused by Corona, I was playing around with Arduino as a quite small hobby in my free time to create a simple robot that is being controlled by Android. 🙂

The robot uses an Arduino and a Motor Shield to control the motors, but since I am an Android developer, I wanted to somehow make use of Android to control it. 📱🤖

The concept is simple: There is an Android phone on the robot which is connected to the Arduino via a Bluetooth cable and sends commands to Arduino to control the motors.

Because of that, I had to test the USB connection between the Android phone and the Arduino, so I created a simple terminal to achieve this. But the terminal can be used for many more purposes than testing this robot, so I decided to publish it as an open-source project on GitHub and also a free app on Google Play Store:

Get it on Google Play

The robot itself, is still under construction 🚧 🔨 and I will probably send a photo of it when it is done, but until then, please feel free to use the new Terminal and I am looking forward to receiving your feedback. 😉

Unit testing Android LiveData using Espresso with Kotlin? Not a mess anymore!

After searching a lot about how to test the live data returned by Room DAOs for unit testing, I found it would be a good idea to share it with other people. The language is Kotlin and I am using Robolectric to mock the context; But here, I just focus on the problem itself and I’m not gonna explain how to write the tests. You can of course check the links provided in the text.

MEME2018-08-30-03-20-59

I also have to mention that there are also other workarounds to achieve this, like using Mockito, but honestly in my opinion, this was the most clean approach. But if you prefer those ones, good luck with that. 😊

tl;dr

What did I want to do? Check if the LiveData objects returned by a DAO method are correct; And to have 100% test coverage on those files. 😉

What I did? Created a Kotlin extension function for LiveData object in my test class to block the main thread and wait for the observer to call onChange method and return the value. How? Using CountdownLatch. Read the answer to this Stack Overflow post.

private fun <T> LiveData<T>.blockingObserve(): T? {

    var value: T? = null
    val latch = CountDownLatch(1)
    val observer = Observer<T> {

        t ->
        value = t
        latch.countDown()
    }

    observeForever(observer)

    latch.await(2, TimeUnit.SECONDS)
    return value
}

The Problem: Although CountDownLatch is used to block the thread and wait for the value, but it would not block the thread and the value was always null. This is probably because of LiveData’s main feature which is usually being used in the main thread and obviously, it is not supposed to block the main thread, never!

Solution: Well, that’s pretty easy! You just need to add this rule to your test class:

@get:Rule
val rule = InstantTaskExecutorRule()

It will allow the liveData observer to block the main thread and Viola!

Just don’t forget to add the core-testing dependency which is part of the Architecture library to your project and also match its version to the version of your current Architecture library that you’re using and everything will work like a charm:

testImplementation "android.arch.core:core-testing:1.1.1"

The answer to this post on StackOverflow also explains it.

Now the tests should work fine and as a reminder, I am running the tests as Local Unit Tests using Robolectric and not as Android Instrumented tests.

Good Luck Unit Testing 😊

Kotlin, the second official programming language for Android

Kotlin was being used in Android by Android Developers unofficially using libraries like ANKO. Yesterday, Kotlin was introduced as a second officially supported Android programming language in Google I/O.

Here are some links and resources to presentations and tools which I found useful for getting started with Kotlin for Android.

Here is an introduction presented by Wojtek Kaliciński which gives you a better perspective about how to use Kotlin in Android Studio 3.0:
Android Tool Time: Getting Started with Kotlin

I also found this presentation from Hadi Hariri in CERN a good resource to get up and running with Kotlin in about 45 minutes, I really encourage you to watch it.
Kotlin – Ready for production by Hadi Hariri

And finally download the new version of Android Studio 3.0 Canary from the official preview website.
Android Studio Preview Download

I hope these resources help jumpstart your next Android project using Kotlin and improve your productivity in Android Development.