Kotlin Take Screenshot Programmatically And Share | Particular Layout

kotlin take scrollview screenshot, kotlin generate pdf from view, kotlin take screenshot, kotlin custom camera, kotlin indeterminate horizontal progressbar, kotlin horizontal recyclerview, Kotlin Volley ListView JSON, Kotlin RecyclerView Volley

Make example on Kotlin Take Screenshot Programmatically And Share.

This tutorial will guide you to take screenshot of any Particular Layout Programmatically using Kotlin.

We will be able to share the screen shot using various social platforms like facebook, whatsapp, gmail etc.

See the below youtube video for output of this example.

 

Step 1. New Project With Permissions

Make a new project in the android studio. Set Kotlin as the source language and Empty activity as the default activity.

Now go to your AndroidManifest.xml file. You should add the below lines in this file.

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

These lines are adding the READ and WRITE permissions in our project.

Now let us implement runtime permissions. For this, open build.gradle (Module: app) file and write the below line in it.

 implementation 'com.karumi:dexter:5.0.0'

Above line will integrate the dexter laboratory in our example. It will help us in the implementation of the runtime permissions structure.

We will use the classes of this library in our kotlin file.

Step 2. Taking Screen shot

Now let us take the screen shot programmatically using the Kotlin code.

Go to activity_main.xml file and add the following lines

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:app="http://schemas.android.com/apk/res-auto"
              xmlns:tools="http://schemas.android.com/tools"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical"
              tools:context=".MainActivity">

    <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:textSize="25sp"
            android:layout_marginTop="10dp"
            android:text="Take Screenshot Programmatically"/>

    <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:gravity="center">

        <ImageView
                android:layout_width="270dp"
                android:layout_height="0dp"
                android:id="@+id/iv"
                android:background="@color/colorAccent"
                android:scaleType="fitXY"
                android:layout_weight="1"
                android:layout_marginTop="10dp"/>

        <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/btnSS"
                android:layout_marginTop="10dp"
                android:text="Take Screenshot"/>
        <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/btnShare"
                android:layout_marginTop="10dp"
                android:text="Share"/>
        <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/btnPL"
                android:layout_marginTop="10dp"
                android:text="SS of Particular Layout"/>

    </LinearLayout>
</LinearLayout>

Above XML layout file have one text view, one image view and three buttons.

Text view is static and it’s value will remain unchanged. In the image view, we will preview the screen shot.

There are three buttons : TAKE SCREENSHOT , SHARE and SS OF PARTICULAR LAYOUT

Now you should write down the below lines in MainActivity.kt file.

import android.Manifest
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Environment
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.os.StrictMode
import android.util.Log
import android.view.View
import android.widget.Button
import android.widget.ImageView
import android.widget.Toast
import com.karumi.dexter.Dexter
import com.karumi.dexter.MultiplePermissionsReport
import com.karumi.dexter.PermissionToken
import com.karumi.dexter.listener.DexterError
import com.karumi.dexter.listener.PermissionRequest
import com.karumi.dexter.listener.PermissionRequestErrorListener
import com.karumi.dexter.listener.multi.MultiplePermissionsListener
import java.io.File
import java.io.FileOutputStream
import java.util.Date

class MainActivity : AppCompatActivity() {

    private var btnSS: Button? = null
    private var btnshare: Button? = null
    private var btnPL: Button? = null
    private var iv: ImageView? = null
    private var sharePath = "no"

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

        val builder = StrictMode.VmPolicy.Builder()
        StrictMode.setVmPolicy(builder.build())

        requestReadPermissions()

        btnSS = findViewById(R.id.btnSS)
        btnshare = findViewById(R.id.btnShare)
        btnPL = findViewById(R.id.btnPL)

        iv = findViewById(R.id.iv)

        btnSS!!.setOnClickListener { takeScreenshot() }

        btnshare!!.setOnClickListener {
            if (sharePath != "no") {
                share(sharePath)
            }
        }

        btnPL!!.setOnClickListener {
            val intent = Intent(this@MainActivity, ParticularLayoutActivity::class.java)
            startActivity(intent)
        }
    }

    private fun takeScreenshot() {
        val now = Date()
        android.text.format.DateFormat.format("yyyy-MM-dd_hh:mm:ss", now)

        try {
            // image naming and path  to include sd card  appending name you choose for file
            val mPath = Environment.getExternalStorageDirectory().toString() + "/" + now + ".jpeg"

            // create bitmap screen capture
            val v1 = window.decorView.rootView
            v1.isDrawingCacheEnabled = true
            val bitmap = Bitmap.createBitmap(v1.drawingCache)
            v1.isDrawingCacheEnabled = false

            val imageFile = File(mPath)

            val outputStream = FileOutputStream(imageFile)
            val quality = 100
            bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream)
            outputStream.flush()
            outputStream.close()

            //setting screenshot in imageview
            val filePath = imageFile.path

            val ssbitmap = BitmapFactory.decodeFile(imageFile.absolutePath)
            iv!!.setImageBitmap(ssbitmap)
            sharePath = filePath

        } catch (e: Throwable) {
            // Several error may come out with file handling or DOM
            e.printStackTrace()
        }

    }

    private fun share(sharePath: String) {

        Log.d("ffff", sharePath)
        val file = File(sharePath)
        val uri = Uri.fromFile(file)
        val intent = Intent(Intent.ACTION_SEND)
        intent.type = "image/*"
        intent.putExtra(Intent.EXTRA_STREAM, uri)
        startActivity(intent)

    }

    private fun requestReadPermissions() {

        Dexter.withActivity(this)
            .withPermissions( Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE )
            .withListener(object : MultiplePermissionsListener {
                override fun onPermissionsChecked(report: MultiplePermissionsReport) {
                    // check if all permissions are granted
                    if (report.areAllPermissionsGranted()) {
                        Toast.makeText(applicationContext, "All permissions are granted by user!", Toast.LENGTH_SHORT)
                            .show()
                    }

                    // check for permanent denial of any permission
                    if (report.isAnyPermissionPermanentlyDenied) {
                        // show alert dialog navigating to Settings
                        //openSettingsDialog();
                    }
                }

                override fun onPermissionRationaleShouldBeShown(permissions: List<PermissionRequest>, token: PermissionToken) {
                    token.continuePermissionRequest()
                }
            }).withErrorListener(object : PermissionRequestErrorListener {
                override fun onError(error: DexterError) {
                    Toast.makeText(applicationContext, "Some Error! ", Toast.LENGTH_SHORT).show()
                }
            })
            .onSameThread()
            .check()
    }

}

More Words

First of all, see the following

 private var btnSS: Button? = null
    private var btnshare: Button? = null
    private var btnPL: Button? = null
    private var iv: ImageView? = null
    private var sharePath = "no"

Compiler will first create the three objects of the Button class. There is one object of Image view.

Then there is a variable named sharePath which will hold the string value.

Now read the following

private fun requestReadPermissions() {

        Dexter.withActivity(this)
            .withPermissions( Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE )
            .withListener(object : MultiplePermissionsListener {
                override fun onPermissionsChecked(report: MultiplePermissionsReport) {
                    // check if all permissions are granted
                    if (report.areAllPermissionsGranted()) {
                        Toast.makeText(applicationContext, "All permissions are granted by user!", Toast.LENGTH_SHORT)
                            .show()
                    }

                    // check for permanent denial of any permission
                    if (report.isAnyPermissionPermanentlyDenied) {
                        // show alert dialog navigating to Settings
                        //openSettingsDialog();
                    }
                }

                override fun onPermissionRationaleShouldBeShown(permissions: List<PermissionRequest>, token: PermissionToken) {
                    token.continuePermissionRequest()
                }
            }).withErrorListener(object : PermissionRequestErrorListener {
                override fun onError(error: DexterError) {
                    Toast.makeText(applicationContext, "Some Error! ", Toast.LENGTH_SHORT).show()
                }
            })
            .onSameThread()
            .check()
    }

Above is the code block for the requestReadPermissions() method.

This method is asking for the runtime permissions (read and write) to the user.

We are using the Dexter library in this method.

Now focus on the below lines

  btnPL!!.setOnClickListener {
            val intent = Intent(this@MainActivity, ParticularLayoutActivity::class.java)
            startActivity(intent)
        }

Compiler will run the above code when the user clicks the SS OF PARTICULAR LAYOUT button.

It will simply open the ParticularLayoutActivity. We will create this activity in the next step.

Now read the below code

  btnSS!!.setOnClickListener { takeScreenshot() }

This line is the click event of the TAKE SCREENSHOT button. Compiler will execute the takeScreenshot() function.

Below are the code lines for the takeScreenshot() function.

 private fun takeScreenshot() {
        val now = Date()
        android.text.format.DateFormat.format("yyyy-MM-dd_hh:mm:ss", now)

        try {
            // image naming and path  to include sd card  appending name you choose for file
            val mPath = Environment.getExternalStorageDirectory().toString() + "/" + now + ".jpeg"

            // create bitmap screen capture
            val v1 = window.decorView.rootView
            v1.isDrawingCacheEnabled = true
            val bitmap = Bitmap.createBitmap(v1.drawingCache)
            v1.isDrawingCacheEnabled = false

            val imageFile = File(mPath)

            val outputStream = FileOutputStream(imageFile)
            val quality = 100
            bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream)
            outputStream.flush()
            outputStream.close()

            //setting screenshot in imageview
            val filePath = imageFile.path

            val ssbitmap = BitmapFactory.decodeFile(imageFile.absolutePath)
            iv!!.setImageBitmap(ssbitmap)
            sharePath = filePath

        } catch (e: Throwable) {
            // Several error may come out with file handling or DOM
            e.printStackTrace()
        }

This method is taking the screen shot of the whole screen.

For this it will use various classes like Date, Bitmap, Environment etc.

At last, this method will create the bitmap of the screen which is our final screen shot (screen shot will be an image in the jpeg format). Compiler will preview this bitmap into the Image View.

Now see the below writings

  btnshare!!.setOnClickListener {
            if (sharePath != "no") {
                share(sharePath)
            }
        }

On the click event of SHARE button, compiler will run the above code. It will call the share() method whose coding lines are as the below.

 private fun share(sharePath: String) {

        Log.d("ffff", sharePath)
        val file = File(sharePath)
        val uri = Uri.fromFile(file)
        val intent = Intent(Intent.ACTION_SEND)
        intent.type = "image/*"
        intent.putExtra(Intent.EXTRA_STREAM, uri)
        startActivity(intent)

    }

In the parameter, this method is getting the path to the screen shot (a path where screen shot image is saved).

Compiler will create one share intent. In this intent, it will bind the screen shot image using the URI of this screen shot image.

You can share the screen shot via this intent. It will allow user to share via whatsapp, instagram, facebbok etc.

Step 3. Screen shot of Any Specific Layout

We have take the screen shot of whole screen in the last step. But what if you want to take screen shot of any particular layout of small piece of screen ?

This step will give you the answer to this question.

So let us make a new activity and give it a name as ParticularLayoutActivity.

In your activity_particular_layout.xml file, add the following source snippet

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:app="http://schemas.android.com/apk/res-auto"
              xmlns:tools="http://schemas.android.com/tools"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical"
              tools:context=".ParticularLayoutActivity">

    <ImageView
            android:layout_width="170dp"
            android:layout_height="150dp"
            android:id="@+id/ivpl"
            android:layout_marginLeft="30dp"
            android:background="@color/colorAccent"
            android:layout_marginTop="10dp"/>

    <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/btnim"
            android:layout_marginTop="10dp"
            android:text="Take SS of below Image"/>

    <ImageView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:id="@+id/image"
            android:scaleType="fitXY"
            android:layout_marginTop="10dp"
            android:layout_marginLeft="10dp"
            android:src="@mipmap/ic_launcher"/>

    <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/btntx"
            android:text="Take SS of below TextView"/>

    <TextView
            android:layout_width="180dp"
            android:layout_height="50dp"
            android:id="@+id/tx"
            android:gravity="center"
            android:background="#1be94e"
            android:textColor="#000"
            android:text="I'm textview, Take My SS "/>

</LinearLayout>

There are two image views in the above file. Two buttons are also there : TAKE SS OF BELOW IMAGE and TAKE SS OF BELOW TEXTVIEW

Now in your ParticularLayoutActivity.kt file, you should write the below lines

import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.os.Environment
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import java.io.File
import java.io.FileOutputStream
import java.util.Date

class ParticularLayoutActivity : AppCompatActivity() {

    private var btnIm: Button? = null
    private var btntx: Button? = null
    private var imageView: ImageView? = null
    private var ivpl: ImageView? = null
    private var tv: TextView? = null

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

        btnIm = findViewById(R.id.btnim)
        btntx = findViewById(R.id.btntx)
        tv = findViewById(R.id.tx)
        imageView = findViewById(R.id.image)
        ivpl = findViewById(R.id.ivpl)

        btnIm!!.setOnClickListener { takeSS(imageView) }

        btntx!!.setOnClickListener { takeSS(tv) }
    }

    private fun takeSS(v: View?) {
        val now = Date()
        android.text.format.DateFormat.format("yyyy-MM-dd_hh:mm:ss", now)

        try {
            // image naming and path  to include sd card  appending name you choose for file
            val mPath = Environment.getExternalStorageDirectory().toString() + "/" + now + ".jpeg"

            // create bitmap screen capture
            v!!.isDrawingCacheEnabled = true
            val bitmap = Bitmap.createBitmap(v.drawingCache)
            v.isDrawingCacheEnabled = false

            val imageFile = File(mPath)

            val outputStream = FileOutputStream(imageFile)
            val quality = 100
            bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream)
            outputStream.flush()
            outputStream.close()

            //setting screenshot in imageview
            val filePath = imageFile.path

            val ssbitmap = BitmapFactory.decodeFile(imageFile.absolutePath)
            ivpl!!.setImageBitmap(ssbitmap)
            //sharePath = filePath;

        } catch (e: Throwable) {
            // Several error may come out with file handling or DOM
            e.printStackTrace()
        }

    }
}

See the following first

 btnIm!!.setOnClickListener { takeSS(imageView) }

When the user clicks TAKE SS OF BELOW IMAGE button, compiler will run the above code.

It will execute the takeSS() method. Following is the lines for takeSS() method.

 private fun takeSS(v: View?) {
        val now = Date()
        android.text.format.DateFormat.format("yyyy-MM-dd_hh:mm:ss", now)

        try {
            // image naming and path  to include sd card  appending name you choose for file
            val mPath = Environment.getExternalStorageDirectory().toString() + "/" + now + ".jpeg"

            // create bitmap screen capture
            v!!.isDrawingCacheEnabled = true
            val bitmap = Bitmap.createBitmap(v.drawingCache)
            v.isDrawingCacheEnabled = false

            val imageFile = File(mPath)

            val outputStream = FileOutputStream(imageFile)
            val quality = 100
            bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream)
            outputStream.flush()
            outputStream.close()

            //setting screenshot in imageview
            val filePath = imageFile.path

            val ssbitmap = BitmapFactory.decodeFile(imageFile.absolutePath)
            ivpl!!.setImageBitmap(ssbitmap)
            //sharePath = filePath;

        } catch (e: Throwable) {
            // Several error may come out with file handling or DOM
            e.printStackTrace()
        }

    }

This method getting the view in it’s parameter. It will take the screen shot of this view.

This view can be of any type like Image View, Text View , Linear Layout etc.

Compiler will save the screen shot of any particular layout or piece of the screen into the .jpeg format.

Now below is the code block for the click event of the TAKE SS OF BELOW TEXTVIEW button.

 btntx!!.setOnClickListener { takeSS(tv) }

It will also call the takeSS() method. Only difference is that, we will give text view in the parameter instead of image view.

Download Code Of Kotlin Take Screenshot

https://github.com/demonuts/Kotlin-Take-Screenshot-Programmatically-And-Share-Particular-Layout