How to Capture Screenshot of a View and Save it to Gallery in Android? - GeeksforGeeks

14 Feb, 2021
In this article, we will capture a screenshot of a view and store the image in the gallery. A sample video is given below to get an idea about what we are going to do in this article. Note that we are going to implement this project using the Kotlin language. 
Step 1: Create a new project
To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio. Note that select Kotlin as the programming language
Step 2: Working with the activity_main.xml file
Go to the activity_main.xml file and refer to the following code. Below is the code for the activity_main.xml file. Notice that it has a Material Card View with id card_View, we will take a screenshot of this view in this article.
XML
<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout     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:id="@+id/parentLayout"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:gravity="center"    tools:context=".MainActivity">      <com.google.android.material.card.MaterialCardView        android:id="@+id/card_View"        android:layout_width="match_parent"        android:layout_height="300dp"        android:layout_margin="20dp"        android:elevation="10dp"        app:cardBackgroundColor="@color/black"        app:layout_constraintLeft_toLeftOf="parent"        app:layout_constraintRight_toRightOf="parent"        app:layout_constraintTop_toTopOf="parent">          <LinearLayout            android:layout_width="match_parent"            android:layout_height="match_parent"            android:orientation="vertical">              <ImageView                android:layout_width="match_parent"                android:layout_height="200dp"                android:scaleType="center"                android:src="@drawable/gfg" />              <TextView                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_gravity="center"                android:layout_marginTop="20dp"                android:text="Geeks For Geeks"                android:textColor="@color/white"                android:textSize="20sp"                android:textStyle="bold" />          </LinearLayout>    </com.google.android.material.card.MaterialCardView>      <Button        android:id="@+id/btn_capture"        android:layout_width="wrap_content"        android:layout_height="50dp"        android:layout_marginTop="20dp"        android:backgroundTint="#0F9D58"        android:text="Capture View"        app:layout_constraintLeft_toLeftOf="parent"        app:layout_constraintRight_toRightOf="parent"        app:layout_constraintTop_toBottomOf="@id/card_View" />  </androidx.constraintlayout.widget.ConstraintLayout>
Step 3. Add permission in the manifest.
Go to the AndroidManifest.xml file and the following code. It has two permissions Read and Write to external storage. and inside application tag it has android:usesCleartextTraffic=”true”.
XML
<?xml version="1.0" encoding="utf-8"?><manifest     xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    package="com.geeksforgeeks.captureview">      <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />    <uses-permission        android:name="android.permission.WRITE_EXTERNAL_STORAGE"        tools:ignore="ScopedStorage" />      <application        android:allowBackup="true"        android:icon="@mipmap/ic_launcher"        android:label="@string/app_name"        android:roundIcon="@mipmap/ic_launcher_round"        android:supportsRtl="true"        android:theme="@style/Theme.CaptureView"        android:usesCleartextTraffic="true">        <activity android:name=".MainActivity">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                  <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application>  </manifest>
Step 4: Working with the MainActivity.kt file
Go to the MainActivity.kt file and refer to the following code. Below is the code for the MainActivity.kt file. Comments are added inside the code to understand the code in more detail.
Kotlin
import android.Manifestimport android.content.ContentValuesimport android.graphics.Bitmapimport android.graphics.Canvasimport android.net.Uriimport android.os.Buildimport android.os.Bundleimport android.os.Environmentimport android.provider.MediaStoreimport android.util.Logimport android.view.Viewimport android.widget.Buttonimport android.widget.Toastimport androidx.appcompat.app.AppCompatActivityimport androidx.cardview.widget.CardViewimport androidx.core.app.ActivityCompatimport java.io.Fileimport java.io.FileOutputStreamimport java.io.OutputStream  class MainActivity : AppCompatActivity() {      override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setContentView(R.layout.activity_main)          // write permission to access the storage        ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 1)        ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), 1)          // this is the card view whose screenshot          // we will take in this article        // get the view using fin view bt id        val cardView = findViewById<CardView>(R.id.card_View)          // on click of this button it will capture           // screenshot and save into gallery        val captureButton = findViewById<Button>(R.id.btn_capture)        captureButton.setOnClickListener {            // get the bitmap of the view using               // getScreenShotFromView method it is            // implemented below            val bitmap = getScreenShotFromView(cardView)              // if bitmap is not null then               // save it to gallery            if (bitmap != null) {                saveMediaToStorage(bitmap)            }        }      }      private fun getScreenShotFromView(v: View): Bitmap? {        // create a bitmap object        var screenshot: Bitmap? = null        try {            // inflate screenshot object              // with Bitmap.createBitmap it               // requires three parameters            // width and height of the view and              // the background color            screenshot = Bitmap.createBitmap(v.measuredWidth, v.measuredHeight, Bitmap.Config.ARGB_8888)            // Now draw this bitmap on a canvas            val canvas = Canvas(screenshot)            v.draw(canvas)        } catch (e: Exception) {            Log.e("GFG", "Failed to capture screenshot because:" + e.message)        }        // return the bitmap        return screenshot    }        // this method saves the image to gallery    private fun saveMediaToStorage(bitmap: Bitmap) {        // Generating a file name        val filename = "${System.currentTimeMillis()}.jpg"          // Output stream        var fos: OutputStream? = null          // For devices running android >= Q        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {            // getting the contentResolver            this.contentResolver?.also { resolver ->                  // Content resolver will process the contentvalues                val contentValues = ContentValues().apply {                      // putting file information in content values                    put(MediaStore.MediaColumns.DISPLAY_NAME, filename)                    put(MediaStore.MediaColumns.MIME_TYPE, "image/jpg")                    put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES)                }                  // Inserting the contentValues to                  // contentResolver and getting the Uri                val imageUri: Uri? = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)                  // Opening an outputstream with the Uri that we got                fos = imageUri?.let { resolver.openOutputStream(it) }            }        } else {            // These for devices running on android < Q            val imagesDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)            val image = File(imagesDir, filename)            fos = FileOutputStream(image)        }          fos?.use {            // Finally writing the bitmap to the output stream that we opened            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, it)            Toast.makeText(this , "Captured View and saved to Gallery" , Toast.LENGTH_SHORT).show()        }    }}
Github repo here
android
Android
Kotlin
Android
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Resource Raw Folder in Android Studio
Flutter - Custom Bottom Navigation Bar
How to Read Data from SQLite Database in Android?
How to Post Data to API using Retrofit in Android?
Retrofit with Kotlin Coroutine in Android
Android UI Layouts
Kotlin Array
Retrofit with Kotlin Coroutine in Android
How to Get Current Location in Android?
Kotlin Setters and Getters