Userlambda
Userlambda

Reputation: 85

Capture layout screen in Android

I am facing an issue. I want to capture screen of a XML layout. I know there is a lot of topic on this question. I read them all. But No one of them helped me. Note: I want to get screen capture of a layout which is not part of the current activity.

This my function which is suppose to make capture of the Y layout (called on X activity):

fun getTestCapture() : Bitmap{
    val view = layoutInflater.inflate(R.layout.activity_test, null)
    val layout = view.findViewById<LinearLayout>(R.id.linearLayout)

    layout.layout(0,0, layout.measuredWidth, layout.measuredHeight)
    val bitmap = Bitmap.createBitmap(100, 200, Bitmap.Config.ARGB_8888)
    val canvas = Canvas(bitmap)
    val background = layout.background

    if (background != null) {
        background.draw(canvas)
    }

    layout.draw(canvas)

    storeScreenShot(bitmap, "test.jpg", this)

    return bitmap

}

And when I save the bitmap it shows me nothing. My save bitmap function work fine, I don't want to bother you with that. So my question is simply: what causes my function to not work?

Upvotes: 1

Views: 2153

Answers (3)

Hardik Talaviya
Hardik Talaviya

Reputation: 1496

Try below solution

Java

yourView.post(new Runnable() {
    @Override
    public void run() {
        //take screenshot
        Bitmap myBitmap = captureScreen(binding.llMain);
        Log.e(TAG, "run :: Screenshot captured..!");
        try {
            if (myBitmap != null) {
                //your save image code
                Log.e(TAG, "run :: Screenshot saved..!");
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
});

private Bitmap captureScreen(View v) {
    Bitmap screenshot = null;
    try {
        if (v != null) {
            screenshot = Bitmap.createBitmap(v.getMeasuredWidth(), v.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(screenshot);
            v.draw(canvas);
        }
    } catch (Exception e) {
        Log.e(TAG, "Failed to capture screenshot because:" + e.getMessage());
    }
    return screenshot;
}

Kotlin

binding.idLayout.post(Runnable {
    val myBitmap = getScreenShotFromView(binding.idLayout)
    try {
        if (myBitmap != null) {
            storeScreenShot(myBitmap, "test2.jpg", this@TelecollecteActivity)
        }
    } catch (e: java.lang.Exception) {
        Log.e("BLABLA", "Error ::" + e.message)
    }
})

fun getScreenShotFromView(v: View): Bitmap? {
    var screenshot: Bitmap? = null
    try {
        if (v != null) {
            screenshot = Bitmap.createBitmap(v.measuredWidth, v.measuredHeight, Bitmap.Config.ARGB_8888)
            val canvas = Canvas(screenshot)
            v.draw(canvas)
        }
    } catch (e: Exception) {
        Log.e("BLABLA", "Failed to capture screenshot because:" + e.message)
    }
    return screenshot
}

For your reference

I have also added full code which I was tested and it's working fine for me.

activity_main_two.xml

If you are use black color So, you need to add background color as white other vice full image show as black.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/llMain"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/White"
    android:gravity="center"
    android:orientation="vertical"
    tools:context=".Main2Activity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hardik Talaviya" />

</LinearLayout>

Main2Activity

class Main2Activity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main_two)

        llMain.post(Runnable {
            val myBitmap = getScreenShotFromView(llMain)
            try {
                if (myBitmap != null) {
                    //storeScreenShot(myBitmap, "test2.jpg", this@TelecollecteActivity)
                    val extr = Environment.getExternalStorageDirectory().toString()
                    val myPath = File(extr, "test.jpg")
                    var fos: FileOutputStream? = null

                    try {
                        fos = FileOutputStream(myPath)
                        myBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos)
                        fos!!.flush()
                        fos!!.close()
                        MediaStore.Images.Media.insertImage(contentResolver, myBitmap,
                                "Screen", "screen")

                    } catch (e: FileNotFoundException) {
                        // TODO Auto-generated catch block
                        e.printStackTrace()
                    } catch (e: Exception) {
                        // TODO Auto-generated catch block
                        e.printStackTrace()
                    }

                }
            } catch (e: java.lang.Exception) {
                Log.e("BLABLA", "Error ::" + e.message)
            }
        })
    }

    fun getScreenShotFromView(v: View): Bitmap? {
        var screenshot: Bitmap? = null
        try {
            if (v != null) {
                screenshot = Bitmap.createBitmap(v.measuredWidth, v.measuredHeight, Bitmap.Config.ARGB_8888)
                val canvas = Canvas(screenshot)
                v.draw(canvas)
            }
        } catch (e: Exception) {
            Log.e("BLABLA", "Failed to capture screenshot because:" + e.message)
        }
        return screenshot
    }
}

Saved screen shot image

Image link

I hope this can help you!

Upvotes: 1

Userlambda
Userlambda

Reputation: 85

So this is what I did, But I have still an empty image.

binding.idLayout

is my LinearLayout with content in it, that I retrieve with databinding

run { Log.v("BLABLA", "jifjifoer")
            val myBitmap = getScreenShotFromView(binding.idLayout)
            try {
                if (myBitmap != null){
                    storeScreenShot(myBitmap, "test2.jpg", this@TelecollecteActivity)
                }
            }catch (e : java.lang.Exception){} }

Get screen function

fun getScreenShotFromView(v: View) : Bitmap? {
    var screenshot : Bitmap? = null;
    try {
        if (v != null) {
            screenshot = Bitmap.createBitmap(100, 200, Bitmap.Config.ARGB_8888);
            val canvas = Canvas(screenshot);
            v.draw(canvas);
        }
    } catch (e : Exception) {
        Log.e("BLABLA", "Failed to capture screenshot because:" + e.message);
    }
    return screenshot
}

EDIT

view.post(object : Runnable{
            override fun run() {
                Log.v("BLABLA", "jifjifoer")
                val myBitmap = getScreenShotFromView(binding.parent)
                try {
                    if (myBitmap != null){
                        storeScreenShot(myBitmap, "test2.jpg", this@TelecollecteActivity)
                    }
                }catch (e : java.lang.Exception){}
            }
        })

Upvotes: 0

Furqan Khan
Furqan Khan

Reputation: 528

You need the following code

layout.buildDrawingCache(true);
bitmap = layout.getDrawingCache(true).copy(Config.ARGB_8888, false);
layout.destroyDrawingCache();

this will capture the view into a bitmap and that bitmap can be stored in a file.

Upvotes: 0

Related Questions