android kotlin - Play default ringtone example

MainActivity.kt

package com.cfsuman.kotlintutorials

import android.app.Activity
import android.content.Context
import android.media.MediaPlayer
import android.media.Ringtone
import android.media.RingtoneManager
import android.os.Bundle
import android.provider.Settings
import android.widget.*


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

        // get the widgets reference from XML layout
        val textView = findViewById<TextView>(R.id.textView)
        val buttonPlay = findViewById<Button>(R.id.buttonPlay)
        val buttonStop = findViewById<Button>(R.id.buttonStop)
        val buttonMediaPlay = findViewById<Button>(R.id.buttonMediaPlay)
        val buttonMediaStop = findViewById<Button>(R.id.buttonMediaStop)


        // Get the device default ringtone
        val ringtone: Ringtone = defaultRingtone

        // Display the default ringtone title
        textView.text = "Ringtone : ${ringtone.getTitle(applicationContext)}"

        // Play the default ringtone
        buttonPlay.setOnClickListener{
            if (!ringtone.isPlaying){
                ringtone.play()
            }
        }

        // Stop playing ringtone
        buttonStop.setOnClickListener{
            if (ringtone.isPlaying){
                ringtone.stop()
            }
        }


        // Get the media player for default ringtone
        val mediaPlayer: MediaPlayer = defaultRingtonePlayer()

        // Play default ringtone using media player
        buttonMediaPlay.setOnClickListener{
            if (!mediaPlayer.isPlaying)mediaPlayer.start()
        }

        // Stop media player
        buttonMediaStop.setOnClickListener{
            if (mediaPlayer.isPlaying){
                mediaPlayer.stop()
            }
        }
    }
}



// Extension property to get default ringtone
val Context.defaultRingtone:Ringtone
    get() {
        val uri = RingtoneManager.getDefaultUri(
            RingtoneManager.TYPE_RINGTONE)
        return RingtoneManager.getRingtone(this, uri)
    }


// Get a media player to play default ringtone
fun Context.defaultRingtonePlayer():MediaPlayer{
    return MediaPlayer.create(this,
        Settings.System.DEFAULT_RINGTONE_URI)
}
activity_main.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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#DCDCDC"
    android:padding="24dp">

    <Button
        android:id="@+id/buttonPlay"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="Play Default Ringtone"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/buttonStop"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="Stop"
        app:layout_constraintStart_toStartOf="@+id/buttonPlay"
        app:layout_constraintTop_toBottomOf="@+id/buttonPlay" />

    <Button
        android:id="@+id/buttonMediaPlay"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="32dp"
        android:text="Play Using Media Player"
        app:layout_constraintStart_toStartOf="@+id/buttonStop"
        app:layout_constraintTop_toBottomOf="@+id/buttonStop" />

    <Button
        android:id="@+id/buttonMediaStop"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="Stop Media Player"
        app:layout_constraintStart_toStartOf="@+id/buttonMediaPlay"
        app:layout_constraintTop_toBottomOf="@+id/buttonMediaPlay" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        android:fontFamily="sans-serif"
        android:textSize="24sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/buttonMediaStop" />

</androidx.constraintlayout.widget.ConstraintLayout>

android kotlin - Turn on off do not disturb programmatically

MainActivity.kt

package com.cfsuman.kotlinexamples

import android.app.NotificationManager
import android.content.Context
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
import android.widget.Toast
import android.content.Intent
import android.os.Build
import android.provider.Settings


class MainActivity : AppCompatActivity() {

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

        // get the notification manager system service
        val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager

        // Click listener for button widget
        button_on.setOnClickListener {
            if (checkNotificationPolicyAccess(notificationManager)){
                notificationManager.onDOD()
                toast("Do Not Disturb turned on.")
            }
        }

        // Click listener for button widget
        button_off.setOnClickListener{
            if (checkNotificationPolicyAccess(notificationManager)){
                notificationManager.offDOD()
                toast("Do Not Disturb turned off")
            }
        }

        // Click listener for button widget
        button_on_alarm.setOnClickListener{
            if (checkNotificationPolicyAccess(notificationManager)){
                notificationManager.onAlarmDOD()
                toast("Do Not Disturb Alarm Only.")
            }
        }
    }


    // Method to check notification policy access status
    private fun checkNotificationPolicyAccess(notificationManager:NotificationManager):Boolean{
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (notificationManager.isNotificationPolicyAccessGranted){
                //toast("Notification policy access granted.")
                return true
            }else{
                toast("You need to grant notification policy access.")
                // If notification policy access not granted for this package
                val intent = Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS)
                startActivity(intent)
            }
        }else{
            toast("Device does not support this feature.")
        }
        return false
    }
}


/*
    *** reference source developer.android.com ***

    INTERRUPTION_FILTER_NONE
        Interruption filter constant - No interruptions filter - all notifications are suppressed
        and all audio streams (except those used for phone calls) and vibrations are muted.

    INTERRUPTION_FILTER_ALL
        Interruption filter constant - Normal interruption filter - no notifications are suppressed.

    INTERRUPTION_FILTER_ALARMS
        Interruption filter constant - Alarms only interruption filter - all notifications except
        those of category CATEGORY_ALARM are suppressed.

 INTERRUPTION_FILTER_PRIORITY
        Interruption filter constant - Priority interruption filter - all notifications are
        suppressed except those that match the priority criteria.
*/


// Extension function to turn on do not disturb
fun NotificationManager.onDOD(){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        this.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_NONE)
    }
}


// Extension function to turn off do not disturb
fun NotificationManager.offDOD(){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        this.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL)
    }
}


// Extension function to set alarms only interruption filter
fun NotificationManager.onAlarmDOD(){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        this.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALARMS)
    }
}



// Extension function to show toast message
fun Context.toast(message: String) {
    Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}
activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/root_layout"
    android:background="#8cb19c"
    android:padding="16dp"
    android:orientation="vertical"
    >
    <Button
        android:id="@+id/button_on"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Turn On Do Not Disturb"
        android:layout_gravity="center_horizontal"
        android:layout_margin="10dp"
        />
    <Button
        android:id="@+id/button_off"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Turn Off Do Not Disturb"
        android:layout_gravity="center_horizontal"
        android:layout_margin="10dp"
        />
    <Button
        android:id="@+id/button_on_alarm"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Turn On Alarm Do Not Disturb"
        android:layout_gravity="center_horizontal"
        android:layout_margin="10dp"
        />
</LinearLayout>
AndroidManifest.xml [Permission]

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

android kotlin - Set ringer volume programmatically

MainActivity.kt

package com.cfsuman.kotlintutorials

import android.app.Activity
import android.app.NotificationManager
import android.content.Context
import android.content.Intent
import android.media.AudioManager
import android.os.Bundle
import android.provider.Settings
import android.widget.*
import kotlin.random.Random


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

        // get the widgets reference from XML layout
        val button = findViewById<Button>(R.id.button)


        // Get the audio manager system service
        val audioManager: AudioManager =
            getSystemService(AUDIO_SERVICE) as AudioManager


        // get the notification manager system service
        val notificationManager =
            getSystemService(NOTIFICATION_SERVICE) as NotificationManager


        // Click listener for button widget
        button.setOnClickListener {
            if (notificationManager.isDoNotDisturbAccessGranted()){
                //toast("Notification policy access granted.")

                // Get the maximum ringer volume
                val maxVolume = audioManager.ringerMaxVolume

                // Get a random volume index in a range
                //val randomIndex = Random.nextInt(((maxVolume - 0) + 1) + 0)
                val randomIndex = Random.nextInt(0,maxVolume+1)

                // Set the ringer volume programmatically
                //audioManager.setRingerVolume(maxVolume)
                audioManager.setRingerVolume(randomIndex)

                // Show volume index in a toast message
                toast("Max: $maxVolume / Current: " +
                        "${audioManager.ringerCurrentVolume}")
            }else{
                toast("You need to grant notification policy access.")
                // If notification policy access not granted for this package
                val intent = Intent(
                    Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS)
                startActivity(intent)
            }
        }
    }
}



// Extension function to check notification
// policy access permission status
private fun NotificationManager
        .isDoNotDisturbAccessGranted():Boolean =
    this.isNotificationPolicyAccessGranted



// Extension function to change ringer volume programmatically
fun AudioManager.setRingerVolume(volumeIndex:Int) {
    // Set ringer volume level
    this.setStreamVolume(
        AudioManager.STREAM_RING, // Stream type
        volumeIndex, // Volume index
        AudioManager.FLAG_SHOW_UI// Flags
    )
}



// Extension property to get ringer maximum volume index
val AudioManager.ringerMaxVolume:Int
    get() = this.getStreamMaxVolume(AudioManager.STREAM_RING)



// Extension property to get ringer current volume index
val AudioManager.ringerCurrentVolume:Int
    get() = this.getStreamVolume(AudioManager.STREAM_RING)



// Extension function to show toast message
fun Context.toast(message: String) {
    Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}
activity_main.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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#DCDCDC"
    android:padding="24dp">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Set Ringer Volume"
        android:textAllCaps="false"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
AndroidManifest.xml [Permission]

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

android kotlin - Set media volume programmatically

MainActivity.kt

package com.cfsuman.kotlintutorials

import android.app.Activity
import android.content.Context
import android.media.AudioManager
import android.os.Bundle
import android.widget.*
import kotlin.random.Random


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

        // get the widgets reference from XML layout
        val button = findViewById<Button>(R.id.button)


        // Get the audio manager system service
        val audioManager: AudioManager =
            getSystemService(AUDIO_SERVICE) as AudioManager


        // Click listener for button widget
        button.setOnClickListener {
            // Get the maximum media/music volume
            val maxVolume = audioManager.mediaMaxVolume

            // Get a random volume index in a range
            //val randomIndex = Random.nextInt(((maxVolume - 0) + 1) + 0)
            val randomIndex = Random.nextInt(0,maxVolume+1)

            // Set the media/music volume programmatically
            //audioManager.setMediaVolume(maxVolume)
            audioManager.setMediaVolume(randomIndex)

            // Show volume index in a toast message
            toast("Max: $maxVolume / Current: " +
                    "${audioManager.mediaCurrentVolume}")
        }
    }
}



// Extension function to change media volume programmatically
fun AudioManager.setMediaVolume(volumeIndex:Int) {
    // Set media volume level
    this.setStreamVolume(
        AudioManager.STREAM_MUSIC, // Stream type
        volumeIndex, // Volume index
        AudioManager.FLAG_SHOW_UI// Flags
    )
}



// Extension property to get media maximum volume index
val AudioManager.mediaMaxVolume:Int
    get() = this.getStreamMaxVolume(AudioManager.STREAM_MUSIC)



// Extension property to get media/music current volume index
val AudioManager.mediaCurrentVolume:Int
    get() = this.getStreamVolume(AudioManager.STREAM_MUSIC)



// Extension function to show toast message
fun Context.toast(message: String) {
    Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}
activity_main.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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#DCDCDC"
    android:padding="24dp">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Set Media Volume"
        android:textAllCaps="false"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

android kotlin - Convert JPG to PNG to WebP programmatically

MainActivity.kt

package com.cfsuman.kotlintutorials

import android.app.Activity
import android.graphics.*
import android.os.Build
import android.os.Bundle
import android.widget.*
import java.io.ByteArrayOutputStream
import java.io.IOException


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

        // get the widgets reference from XML layout
        val imageView = findViewById<ImageView>(R.id.imageView)
        val imageView2 = findViewById<ImageView>(R.id.imageView2)
        val textView = findViewById<TextView>(R.id.textView)
        val textView2 = findViewById<TextView>(R.id.textView2)
        val button = findViewById<Button>(R.id.button)


        // get the bitmap from assets folder
        val bitmap = assetsToBitmap("flower2.jpg")


        // If bitmap is not null
        bitmap?.let {
            imageView.setImageBitmap(bitmap)
        }


        // Click listener for button widget
        button.setOnClickListener{
            // disable the button itself
            it.isEnabled = false

            if(bitmap!=null){
                // Compress bitmap and convert image
                // format from one to another
                val compressedBitmap = bitmap.compress(
                    Bitmap.CompressFormat.PNG)

                /*if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                    val compressedBitmap = bitmap.compress(
                        Bitmap.CompressFormat.WEBP_LOSSY
                    )
                    val compressedBitmap = bitmap.compress(
                        Bitmap.CompressFormat.WEBP_LOSSLESS
                    )
                    imageView2.setImageBitmap(compressedBitmap)
                }*/


                /*val compressedBitmap = bitmap.compress(
                    Bitmap.CompressFormat.JPEG)
                val compressedBitmap = bitmap.compress(
                    Bitmap.CompressFormat.JPEG, 10)
                val compressedBitmap = bitmap.compress(
                    quality = 10) // Compress only*/


                // Display the compressed bitmap into image view
                imageView2.setImageBitmap(compressedBitmap)

                // Notify user
                textView2.text = "Bitmap format changed to PNG."
            }else{
                // Log error
            }
        }
    }



    // Method to get a bitmap from assets
    private fun assetsToBitmap(fileName:String):Bitmap?{
        return try{
            val stream = assets.open(fileName)
            BitmapFactory.decodeStream(stream)
        }catch (e:IOException){
            e.printStackTrace()
            null
        }
    }
}



// Extension function to compress and change
// bitmap image format programmatically
fun Bitmap.compress(
    format:Bitmap.CompressFormat = Bitmap.CompressFormat.JPEG,
    quality:Int = 100
):Bitmap{
    // Initialize a new ByteArrayStream
    val stream = ByteArrayOutputStream()


    // Compress the bitmap with specified format and quality
    this.compress(
        format,
        quality,
        stream
    )

    val byteArray = stream.toByteArray()

    // Finally, return the compressed bitmap
    return BitmapFactory.decodeByteArray(
        byteArray, 0, byteArray.size
    )
}
activity_main.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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/rootLayout"
    android:background="#DCDCDC"
    android:padding="24dp">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="0dp"
        android:layout_height="225dp"
        android:layout_marginTop="8dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:text="Original Bitmap"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="@+id/imageView"
        app:layout_constraintTop_toBottomOf="@+id/imageView" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="Convert JPEG To PNG"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/textView" />

    <ImageView
        android:id="@+id/imageView2"
        android:layout_width="0dp"
        android:layout_height="225dp"
        android:layout_marginTop="24dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:text="Converted Bitmap"
        app:layout_constraintEnd_toEndOf="@+id/imageView2"
        app:layout_constraintStart_toStartOf="@+id/imageView2"
        app:layout_constraintTop_toBottomOf="@+id/imageView2" />

</androidx.constraintlayout.widget.ConstraintLayout>

android kotlin - Bitmap scale down with aspect ratio

MainActivity.kt

package com.cfsuman.kotlintutorials

import android.app.Activity
import android.content.Context
import android.graphics.*
import android.os.Bundle
import android.widget.*
import java.io.IOException

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

        // get the widgets reference from XML layout
        val imageView = findViewById<ImageView>(R.id.imageView)
        val imageView2 = findViewById<ImageView>(R.id.imageView2)
        val textView = findViewById<TextView>(R.id.textView)
        val textView2 = findViewById<TextView>(R.id.textView2)
        val button = findViewById<Button>(R.id.button)


        // get the bitmap from assets folder
        val bitmap = assetsToBitmap("flower2.jpg")


        // If bitmap is not null
        bitmap?.let {
            imageView.setImageBitmap(bitmap)

            // Display the original bitmap's width and height
            textView.text = "${bitmap.width} * ${bitmap.height}"
        }


        // Click listener for button widget
        button.setOnClickListener{
            // disable the button itself
            it.isEnabled = false

            if(bitmap!=null){
                // Resize the bitmap by keeping aspect ratio
                // Bitmap scaled to given maximum height and width value
                val resizedBitmap = bitmap.scale(500)

                // Display the resized bitmap into image view
                imageView2.setImageBitmap(resizedBitmap)

                // Display the resized bitmap width and height
                textView2.text = "${resizedBitmap.width}" +
                        " * ${resizedBitmap.height}"

                // Show a toast message
                toast("Bitmap resized.")
            }else{
                toast("bitmap not found.")
            }
        }
    }



    // Method to get a bitmap from assets
    private fun assetsToBitmap(fileName:String):Bitmap?{
        return try{
            val stream = assets.open(fileName)
            BitmapFactory.decodeStream(stream)
        }catch (e:IOException){
            e.printStackTrace()
            null
        }
    }
}



// Extension method to resize bitmap to maximum width and height
fun Bitmap.scale(maxWidthAndHeight:Int):Bitmap{
    var newWidth = 0
    var newHeight = 0

    if (this.width >= this.height){
        val ratio:Float = this.width.toFloat() / this.height.toFloat()

        newWidth = maxWidthAndHeight
        // Calculate the new height for the scaled bitmap
        newHeight = Math.round(maxWidthAndHeight / ratio)
    }else{
        val ratio:Float = this.height.toFloat() / this.width.toFloat()

        // Calculate the new width for the scaled bitmap
        newWidth = Math.round(maxWidthAndHeight / ratio)
        newHeight = maxWidthAndHeight
    }

    return Bitmap.createScaledBitmap(
        this,
        newWidth,
        newHeight,
        false
    )
}



// Extension function to show toast message
fun Context.toast(message: String) {
    Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}
activity_main.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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/rootLayout"
    android:background="#DCDCDC"
    android:padding="24dp">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="0dp"
        android:layout_height="225dp"
        android:layout_marginTop="8dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:text="Original Bitmap"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="@+id/imageView"
        app:layout_constraintTop_toBottomOf="@+id/imageView" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="Scale Down Bitmap"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/textView" />

    <ImageView
        android:id="@+id/imageView2"
        android:layout_width="0dp"
        android:layout_height="225dp"
        android:layout_marginTop="24dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:text="Scaled Bitmap"
        app:layout_constraintEnd_toEndOf="@+id/imageView2"
        app:layout_constraintStart_toStartOf="@+id/imageView2"
        app:layout_constraintTop_toBottomOf="@+id/imageView2" />

</androidx.constraintlayout.widget.ConstraintLayout>

android kotlin - Rotate a bitmap

MainActivity.kt

package com.cfsuman.kotlintutorials

import android.app.Activity
import android.content.Context
import android.graphics.*
import android.os.Bundle
import android.widget.*
import java.io.IOException

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

        // get the widgets reference from XML layout
        val imageView = findViewById<ImageView>(R.id.imageView)
        val imageView2 = findViewById<ImageView>(R.id.imageView2)
        val textView2 = findViewById<TextView>(R.id.textView2)
        val seekBar = findViewById<SeekBar>(R.id.seekBar)


        // get the bitmap from assets folder
        val bitmap = assetsToBitmap("flower2.jpg")


        // If bitmap is not null
        bitmap?.apply {
            // show original bitmap in first image view
            imageView.setImageBitmap(this)

            // initial bitmap on second image view
            imageView2.setImageBitmap(rotate(seekBar.progress.toFloat()))
            textView2.text = "Rotated Bitmap (Degrees ${seekBar.progress})"

            // rotate bitmap on seek bar change
            seekBar.setOnSeekBarChangeListener(
                object: SeekBar.OnSeekBarChangeListener{
                    override fun onProgressChanged(
                        seekBar: SeekBar?,
                        progress: Int,
                        fromUser: Boolean
                    ) {
                        // show rotated bitmap in second image view
                        imageView2.setImageBitmap(rotate(progress.toFloat()))
                        textView2.text = "Rotated Bitmap (Degrees $progress)"
                    }

                    override fun onStartTrackingTouch(seekBar: SeekBar?) {
                    }

                    override fun onStopTrackingTouch(seekBar: SeekBar?) {
                    }
                })
        }
    }
}



// extension function to get bitmap from assets
fun Context.assetsToBitmap(fileName:String):Bitmap?{
    return try {
        val stream = assets.open(fileName)
        BitmapFactory.decodeStream(stream)
    } catch (e: IOException) {
        e.printStackTrace()
        null
    }
}



// extension function to rotate bitmap
fun Bitmap.rotate(degrees:Float = 180F):Bitmap?{
    val matrix = Matrix()
    matrix.postRotate(degrees)

    return Bitmap.createBitmap(
        this, // source bitmap
        0, // x coordinate of the first pixel in source
        0, // y coordinate of the first pixel in source
        width, // The number of pixels in each row
        height, // The number of rows
        matrix, // Optional matrix to be applied to the pixels
        false // true if the source should be filtered
    )
}
activity_main.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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/rootLayout"
    android:background="#DCDCDC"
    android:padding="24dp">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="0dp"
        android:layout_height="250dp"
        android:layout_marginTop="8dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:text="Original Bitmap"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="@+id/imageView"
        app:layout_constraintTop_toBottomOf="@+id/imageView" />

    <ImageView
        android:id="@+id/imageView2"
        android:layout_width="0dp"
        android:layout_height="250dp"
        android:layout_marginTop="24dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:text="Rotated Bitmap"
        app:layout_constraintEnd_toEndOf="@+id/imageView2"
        app:layout_constraintStart_toStartOf="@+id/imageView2"
        app:layout_constraintTop_toBottomOf="@+id/imageView2" />

    <SeekBar
        android:id="@+id/seekBar"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:max="360"
        android:progress="0"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView2" />

</androidx.constraintlayout.widget.ConstraintLayout>

android kotlin - Resize bitmap keep aspect ratio

MainActivity.kt

package com.cfsuman.kotlintutorials

import android.app.Activity
import android.content.Context
import android.graphics.*
import android.os.Bundle
import android.widget.*
import java.io.IOException
import kotlin.math.roundToInt

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

        // get the widgets reference from XML layout
        val imageView = findViewById<ImageView>(R.id.imageView)
        val imageView2 = findViewById<ImageView>(R.id.imageView2)
        val button = findViewById<Button>(R.id.button)
        val textView = findViewById<TextView>(R.id.textView)
        val textView2 = findViewById<TextView>(R.id.textView2)


        // get the bitmap from assets folder
        val bitmap = assetsToBitmap("flower103.jpg")


        // If bitmap is not null
        bitmap?.let {
            imageView.setImageBitmap(bitmap)

            // Display the original bitmap width and height
            textView.text = "Original Bitmap ${bitmap.width}" +
                    " * ${bitmap.height}"
        }


        // Click listener for button widget
        button.setOnClickListener{
            // disable the button itself
            it.isEnabled = false

            if(bitmap!=null){
                // Resize the bitmap by keeping aspect ration
                val resizedBitmap = bitmap.resizeByWidth(900)
                //val resizedBitmap = bitmap.resizeByHeight(400)

                // Display the resized bitmap into image view
                imageView2.setImageBitmap(resizedBitmap)

                // Display the resized bitmap width and height
                textView2.text = "Resized Bitmap ${resizedBitmap.width}" +
                        " * ${resizedBitmap.height}"

                // Show a toast message
                toast("Bitmap resized.")
            }else{
                toast("bitmap not found.")
            }
        }
    }


    // Method to get a bitmap from assets
    private fun assetsToBitmap(fileName:String):Bitmap?{
        return try{
            val stream = assets.open(fileName)
            BitmapFactory.decodeStream(stream)
        }catch (e:IOException){
            e.printStackTrace()
            null
        }
    }
}



// Extension function to resize bitmap using
// new width value by keeping aspect ratio
fun Bitmap.resizeByWidth(width:Int):Bitmap{
    val ratio:Float = this.width.toFloat() / this.height.toFloat()
    val height:Int = (width / ratio).roundToInt()

    return Bitmap.createScaledBitmap(
        this,
        width,
        height,
        false
    )
}



// Extension function to resize bitmap using
// new height value by keeping aspect ratio
fun Bitmap.resizeByHeight(height:Int):Bitmap{
    val ratio:Float = this.height.toFloat() / this.width.toFloat()
    val width:Int = (height / ratio).roundToInt()

    return Bitmap.createScaledBitmap(
        this,
        width,
        height,
        false
    )
}



// Extension function to show toast message
fun Context.toast(message: String) {
    Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}
activity_main.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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/rootLayout"
    android:background="#DCDCDC"
    android:padding="24dp">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="0dp"
        android:layout_height="225dp"
        android:layout_marginTop="8dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:text="Original Bitmap"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="@+id/imageView"
        app:layout_constraintTop_toBottomOf="@+id/imageView" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="Resize Bitmap Keep Aspect Ratio"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/textView" />

    <ImageView
        android:id="@+id/imageView2"
        android:layout_width="0dp"
        android:layout_height="225dp"
        android:layout_marginTop="24dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:text="Resized Bitmap"
        app:layout_constraintEnd_toEndOf="@+id/imageView2"
        app:layout_constraintStart_toStartOf="@+id/imageView2"
        app:layout_constraintTop_toBottomOf="@+id/imageView2" />

</androidx.constraintlayout.widget.ConstraintLayout>

android kotlin - Resize a bitmap

MainActivity.kt

package com.cfsuman.kotlintutorials

import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.os.Bundle
import android.util.Log
import android.widget.*
import androidx.appcompat.app.AppCompatActivity
import java.io.IOException
import kotlin.random.Random


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

        // Get the widgets reference from XML layout
        val button = findViewById<Button>(R.id.button)
        val ivOriginal = findViewById<ImageView>(R.id.ivOriginal)
        val ivResized = findViewById<ImageView>(R.id.ivResized)
        val tvOriginal = findViewById<TextView>(R.id.tvOriginal)
        val tvResized = findViewById<TextView>(R.id.tvResized)


        // Get the bitmap from assets and display into image view
        val bitmap = assetsToBitmap("flower.jpg")

        // If bitmap is not null
        bitmap?.let {
            ivOriginal.setImageBitmap(bitmap)

            // Display the original bitmap width and height
            tvOriginal.text = "${bitmap.width} * ${bitmap.height}"
        }


        // Click listener for button widget
        button.setOnClickListener{
            if(bitmap!=null){
                // Resize the bitmap and display it into image view
                val resizedBitmap = resizeBitmap(
                    bitmap = bitmap,
                    width = Random.nextInt(300,600),
                    height = Random.nextInt(200,400)
                )
                ivResized.setImageBitmap(resizedBitmap)

                // Display the resized bitmap width and height
                tvResized.text =
                    "${resizedBitmap.width} * ${resizedBitmap.height}"
            }else{
                Log.d("Error","bitmap not found.")
            }
        }
    }


    // Method to get a bitmap from assets
    private fun assetsToBitmap(fileName:String):Bitmap?{
        return try{
            val stream = assets.open(fileName)
            BitmapFactory.decodeStream(stream)
        }catch (e:IOException){
            e.printStackTrace()
            null
        }
    }


    // Method to resize a bitmap programmatically
    private fun resizeBitmap(bitmap:Bitmap,width:Int,height:Int)
    :Bitmap{
        return Bitmap.createScaledBitmap(
            bitmap, width, height,false
        )
    }
}
activity_main.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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/rootLayout"
    android:background="#F8F8F8"
    android:padding="12dp">

    <ImageView
        android:id="@+id/ivOriginal"
        android:layout_width="0dp"
        android:layout_height="215dp"
        android:scaleType="centerInside"
        android:background="#E6E6E6"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/tvOriginal"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:layout_marginTop="8dp"
        android:gravity="center_horizontal"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/ivOriginal" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_margin="10dp"
        android:layout_marginTop="16dp"
        android:text="Resize Bitmap"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tvOriginal" />

    <ImageView
        android:id="@+id/ivResized"
        android:layout_width="0dp"
        android:layout_height="215dp"
        android:layout_marginTop="16dp"
        android:background="#E6E6E6"
        android:scaleType="centerInside"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button" />

    <TextView
        android:id="@+id/tvResized"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:layout_marginTop="8dp"
        android:gravity="center_horizontal"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/ivResized" />

</androidx.constraintlayout.widget.ConstraintLayout>

android kotlin - Convert bitmap to drawable

MainActivity.kt

package com.cfsuman.kotlintutorials

import android.app.Activity
import android.content.Context
import android.graphics.*
import android.graphics.drawable.BitmapDrawable
import android.os.Bundle
import android.widget.*
import java.io.IOException

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

        // get the widgets reference from XML layout
        val imageView = findViewById<ImageView>(R.id.imageView)
        val imageView2 = findViewById<ImageView>(R.id.imageView2)
        val button = findViewById<Button>(R.id.button)


        // get the bitmap from assets folder
        val bitmap = assetsToBitmap("flower103.jpg")


        // If bitmap is not null
        bitmap?.let {
            imageView.setImageBitmap(bitmap)
        }


        // Click listener for button widget
        button.setOnClickListener{
            // disable the button itself
            it.isEnabled = false

            if(bitmap!=null){
                // Get the drawable from bitmap
                // and display it into image view
                imageView2.setImageDrawable(bitmapToDrawable(bitmap))

                // Show a toast message
                toast("Bitmap converted to drawable.")
            }else{
                toast("bitmap not found.")
            }
        }
    }


    // Method to get a bitmap from assets
    private fun assetsToBitmap(fileName:String):Bitmap?{
        return try{
            val stream = assets.open(fileName)
            BitmapFactory.decodeStream(stream)
        }catch (e:IOException){
            e.printStackTrace()
            null
        }
    }


    // Method to convert a bitmap to bitmap drawable
    private fun bitmapToDrawable(bitmap:Bitmap):BitmapDrawable{
        return BitmapDrawable(resources,bitmap)
    }
}



// Extension function to show toast message
fun Context.toast(message: String) {
    Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}
activity_main.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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/rootLayout"
    android:background="#DCDCDC"
    android:padding="24dp">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="0dp"
        android:layout_height="225dp"
        android:layout_marginTop="8dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:text="Bitmap"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="@+id/imageView"
        app:layout_constraintTop_toBottomOf="@+id/imageView" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="Convert Bitmap To Drawable"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/textView" />

    <ImageView
        android:id="@+id/imageView2"
        android:layout_width="0dp"
        android:layout_height="225dp"
        android:layout_marginTop="24dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:text="Drawable"
        app:layout_constraintEnd_toEndOf="@+id/imageView2"
        app:layout_constraintStart_toStartOf="@+id/imageView2"
        app:layout_constraintTop_toBottomOf="@+id/imageView2" />

</androidx.constraintlayout.widget.ConstraintLayout>

android kotlin - Compress bitmap example

Compress Bitmap
The bitmap is used to display an image on ImageView. Sometimes android developers have to compress a Bitmap object before displaying it on the ImageView widget. The following android application development tutorial will demonstrate to us how we can compress a bitmap in an application. We used the Kotlin programming language to write the code for this tutorial.

In this tutorial XML layout file, we put two ImageView widgets, a Button widget, and a TextView widget. The first ImageView widget displays the original uncompressed bitmap on its surface. In the Button’s click event, we programmatically compress the bitmap instance. On the second ImageView widget, we displayed the compressed bitmap after applying compression with a specified quality value/percentage. The TextView widget displays the applied compression quality value/percentage on it.

So, how we can compress a bitmap object programmatically using the native android SDK API? To do that first we create a ByteArrayOutputStream instance. The ByteArrayOutputStream implements an output stream in which the data is written into a byte array. The data can be retrieved using the toByteArray() and toString() methods.

Next, we call the Bitmap compress() method. The bitmap compress() method writes a compressed version of the bitmap to the specified outputstream. This method takes three arguments, that are format, quality, and stream. The ‘format’ argument represents the format of the compressed bitmap. We can set this argument value using CompressFormat enum values. The available formats are JPEG, PNG, WEBP, WEBP_LOSSLESS, and WEBP_LOSSY.

The ‘quality’ argument is an int value that range is 0 to 100. This defines the compression quality. We can call it the percentage of compression quality. And the ‘stream’ is the outputstream to write the compressed data. The compress() method returns true if it is successfully compressed to the specified stream. Finally, we get the compressed bitmap using the BitmapFactory API.

This android kotlin tutorial code is written in an android studio IDE. Copy the code and paste it into your android studio IDE and run it on an emulator to see how we can compress a bitmap programmatically in an android application. We displayed screenshots of the emulator screen, which also help you to understand the code without running it on an android device or emulator.
MainActivity.kt

package com.cfsuman.kotlintutorials

import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.drawable.BitmapDrawable
import android.os.Bundle
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import java.io.ByteArrayOutputStream
import kotlin.random.Random


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

        // Get the widgets reference from XML layout
        val button = findViewById<Button>(R.id.button)
        val ivCompressed = findViewById<ImageView>(R.id.ivCompressed)
        val textView = findViewById<TextView>(R.id.textView)

        // Get the bitmap from given drawable object
        val drawable = ContextCompat.getDrawable(
            applicationContext,R.drawable.rose)
        val bitmap = (drawable as BitmapDrawable).bitmap

        // Click listener for button widget
        button.setOnClickListener{
            val quality = Random.nextInt(2,10)

            // Compress bitmap and display into image view
            ivCompressed.setImageBitmap(
                compressBitmap(bitmap,quality)
            )
            textView.text = "Compressed bitmap (quality $quality)"
        }
    }


    // Method to compress a bitmap
    private fun compressBitmap(bitmap: Bitmap, quality:Int):Bitmap{
        // Initialize a new ByteArrayStream
        val stream = ByteArrayOutputStream()

        // Compress the bitmap with JPEG format and specified quality
        bitmap.compress(
            Bitmap.CompressFormat.JPEG, quality, stream
        )

        val byteArray = stream.toByteArray()

        // Finally, return the compressed bitmap
        return BitmapFactory.decodeByteArray(
            byteArray, 0, byteArray.size
        )
    }
}
activity_main.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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/rootLayout"
    android:background="#DCDCDC"
    android:padding="8dp">

    <ImageView
        android:id="@+id/ivSource"
        android:layout_width="match_parent"
        android:layout_height="225dp"
        android:src="@drawable/rose"
        android:scaleType="centerCrop"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_margin="10dp"
        android:layout_marginTop="12dp"
        android:text="Compress The Bitmap"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/ivSource" />

    <ImageView
        android:id="@+id/ivCompressed"
        android:layout_width="match_parent"
        android:layout_height="225dp"
        android:layout_marginTop="12dp"
        android:scaleType="centerCrop"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:fontFamily="sans-serif"
        android:textSize="16sp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/ivCompressed" />

</androidx.constraintlayout.widget.ConstraintLayout>

android kotlin - Save image to external storage example

MainActivity.kt

package com.cfsuman.kotlinexamples

import android.content.Context
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
import android.graphics.Bitmap
import android.graphics.drawable.BitmapDrawable
import android.net.Uri
import android.os.Build
import android.support.v4.content.ContextCompat
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.OutputStream
import java.util.*
import android.os.Environment
import android.widget.Toast


class MainActivity : AppCompatActivity() {

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

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
            // Check run time permission for write external storage
            // android.permission.WRITE_EXTERNAL_STORAGE
        }

        // Get the bitmap from given drawable object
        val drawable = ContextCompat.getDrawable(applicationContext,R.drawable.flower16)
        val bitmap = (drawable as BitmapDrawable).bitmap

        // Click listener for button widget
        button.setOnClickListener{
            // Save the image in external storage and get the uri
            val uri:Uri = saveImageToExternalStorage(bitmap)

            // Display the external storage saved image in image view
            image_view_saved.setImageURI(uri)

            // Show the saved image uri
            text_view.text = "Saved: $uri"
        }
    }


    // Method to save an image to external storage
    private fun saveImageToExternalStorage(bitmap:Bitmap):Uri{
        // Get the external storage directory path
        val path = Environment.getExternalStorageDirectory().toString()

        // Create a file to save the image
        val file = File(path, "${UUID.randomUUID()}.jpg")

        try {
            // Get the file output stream
            val stream: OutputStream = FileOutputStream(file)

            // Compress the bitmap
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream)

            // Flush the output stream
            stream.flush()

            // Close the output stream
            stream.close()
            toast("Image saved successful.")
        } catch (e: IOException){ // Catch the exception
            e.printStackTrace()
            toast("Error to save image.")
        }

        // Return the saved image path to uri
        return Uri.parse(file.absolutePath)
    }
}


// Extension function to show toast message
fun Context.toast(message: String) {
    Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}
activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/root_layout"
    android:background="#ded5d2"
    android:padding="16dp"
    android:orientation="vertical"
    >
    <ImageView
        android:id="@+id/image_view_source"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:src="@drawable/flower16"
        />
    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Save Image To External Storage"
        android:layout_gravity="center_horizontal"
        android:layout_margin="10dp"
        />
    <TextView
        android:id="@+id/text_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColor="#ff2079"
        android:layout_margin="10dp"
        style="@style/Base.TextAppearance.AppCompat.Medium"
        />
    <ImageView
        android:id="@+id/image_view_saved"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        />
</LinearLayout>
AndroidManiest.xml [Permission]

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

android kotlin - Launch app programmatically

MainActivity.kt

package com.cfsuman.kotlinexamples

import android.content.Context
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_main.*
import android.content.Intent


class MainActivity : AppCompatActivity() {

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

        // Package name of GMail app
        val packageName = "com.google.android.gm"

        // Click listener for button widget
        button.setOnClickListener{
            // Launch the app programmatically
            launchApp(packageName)
        }
    }


    // Custom method to launch an app
    private fun launchApp(packageName: String) {
        // Get an instance of PackageManager
        val pm = applicationContext.packageManager

        // Initialize a new Intent
        val intent:Intent? = pm.getLaunchIntentForPackage(packageName)

        // Add category to intent
        intent?.addCategory(Intent.CATEGORY_LAUNCHER)

        // If intent is not null then launch the app
        if(intent!=null){
            applicationContext.startActivity(intent)
        }else{
            toast("Intent null.")
        }
    }
}



// Extension function to show toast message
fun Context.toast(message: String) {
    Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}
activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/root_layout"
    android:background="#bdd1b7"
    android:padding="16dp"
    android:orientation="vertical"
    >
    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Open Another App"
        android:layout_gravity="center_horizontal"
        />
</LinearLayout>

android kotlin - Save image to Gallery example

MainActivity.kt

package com.cfsuman.kotlinexamples

import android.content.Context
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import android.provider.MediaStore
import android.graphics.drawable.BitmapDrawable
import android.net.Uri
import android.os.Build
import android.support.v4.content.ContextCompat
import kotlinx.android.synthetic.main.activity_main.*


class MainActivity : AppCompatActivity() {

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

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
            // Check run time permission for write external storage
            // android.permission.WRITE_EXTERNAL_STORAGE
        }

        // Click listener for button widget
        button.setOnClickListener{
            // Disable the save button
            it.isEnabled = false

            // Save the image to gallery and get saved image Uri
            val uri = saveImage(R.drawable.flower,"Flower")
            toast("saved : $uri")

            // Show the saved image in an image view
            image_view_saved.setImageURI(uri)
        }
    }


    // Method to save an image to gallery and return uri
    private fun saveImage(drawable:Int, title:String):Uri{
        // Get the image from drawable resource as drawable object
        val drawable = ContextCompat.getDrawable(applicationContext,drawable)

        // Get the bitmap from drawable object
        val bitmap = (drawable as BitmapDrawable).bitmap

        // Save image to gallery
        val savedImageURL = MediaStore.Images.Media.insertImage(
                contentResolver,
                bitmap,
                title,
                "Image of $title"
        )

        // Parse the gallery image url to uri
        return Uri.parse(savedImageURL)
    }
}



// Extension function to show toast message
fun Context.toast(message: String) {
    Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}
activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/root_layout"
    android:background="#d1b7c6"
    android:padding="16dp"
    android:orientation="vertical"
    >
    <ImageView
        android:id="@+id/image_view_source"
        android:layout_width="match_parent"
        android:layout_height="250dp"
        android:src="@drawable/flower"
        />
    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Save"
        android:layout_gravity="center_horizontal"
        />
    <ImageView
        android:id="@+id/image_view_saved"
        android:layout_width="match_parent"
        android:layout_height="250dp"
        />
</LinearLayout>
AndroidManifest.xml [Permission]

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

android kotlin - CountDownTimer days hours minutes seconds example

MainActivity.kt

package com.cfsuman.kotlinexamples

import android.content.Context
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_main.*
import android.os.CountDownTimer
import java.util.*
import java.util.concurrent.TimeUnit


class MainActivity : AppCompatActivity() {

    private var isCancelled = false

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

        // 60 seconds (1 minute)
        val minute:Long = 1000 * 60 // 1000 milliseconds = 1 second

        // 1 day 2 hours 35 minutes 50 seconds
        val millisInFuture:Long = (minute * 1440) + (minute * 155) + (1000 * 50)

        // Count down interval 1 second
        val countDownInterval:Long = 1000


        // Count down timer start button
        button_start.setOnClickListener{
            // Start the timer
            timer(millisInFuture,countDownInterval).start()
            it.isEnabled = false
            button_stop.isEnabled = true

            isCancelled = false
        }


        // Count down timer stop/cancel button
        button_stop.setOnClickListener{
            // Start the timer
            isCancelled = true

            it.isEnabled = false
            button_start.isEnabled = true
        }
    }



    // Method to configure and return an instance of CountDownTimer object
    private fun timer(millisInFuture:Long,countDownInterval:Long):CountDownTimer{
        return object: CountDownTimer(millisInFuture,countDownInterval){
            override fun onTick(millisUntilFinished: Long){
                val timeRemaining = timeString(millisUntilFinished)
                if (isCancelled){
                    text_view.text = "${text_view.text}\nStopped.(Cancelled)"
                    cancel()
                }else{
                    text_view.text = timeRemaining
                }
            }

            override fun onFinish() {
                text_view.text = "Done"

                button_start.isEnabled = true
                button_stop.isEnabled = false
            }
        }
    }



    // Method to get days hours minutes seconds from milliseconds
    private fun timeString(millisUntilFinished:Long):String{
        var millisUntilFinished:Long = millisUntilFinished
        val days = TimeUnit.MILLISECONDS.toDays(millisUntilFinished)
        millisUntilFinished -= TimeUnit.DAYS.toMillis(days)

        val hours = TimeUnit.MILLISECONDS.toHours(millisUntilFinished)
        millisUntilFinished -= TimeUnit.HOURS.toMillis(hours)

        val minutes = TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished)
        millisUntilFinished -= TimeUnit.MINUTES.toMillis(minutes)

        val seconds = TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished)

        // Format the string
        return String.format(
                Locale.getDefault(),
                "%02d day: %02d hour: %02d min: %02d sec",
                days,hours, minutes,seconds
        )
    }
}



// Extension function to show toast message
fun Context.toast(message: String) {
    Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}
activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/root_layout"
    android:background="#dbf2f9"
    android:padding="16dp"
    android:orientation="vertical"
    >
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_gravity="center_horizontal"
        >
        <Button
            android:id="@+id/button_start"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Start"
            />
        <Button
            android:id="@+id/button_stop"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Stop(Cancel)"
            android:enabled="false"
            />
    </LinearLayout>
    <TextView
        android:id="@+id/text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#224889"
        android:layout_gravity="center_horizontal"
        android:textSize="25sp"
        android:layout_marginTop="30dp"
        android:gravity="center"
        android:textStyle="bold"
        />
</LinearLayout>

android kotlin - CountDownTimer start stop pause resume example

MainActivity.kt

package com.cfsuman.kotlinexamples

import android.content.Context
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_main.*
import android.os.CountDownTimer


class MainActivity : AppCompatActivity() {

    private var isPaused = false
    private var isCancelled = false
    private var resumeFromMillis:Long = 0

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

        val millisInFuture:Long = 50000
        val countDownInterval:Long = 1000


        // Count down timer start button
        button_start.setOnClickListener{
            // Start the timer
            timer(millisInFuture,countDownInterval).start()
            it.isEnabled = false
            button_stop.isEnabled = true
            button_pause.isEnabled = true

            isCancelled = false
            isPaused = false
        }


        // Count down timer stop/cancel button
        button_stop.setOnClickListener{
            // Start the timer
            isCancelled = true
            isPaused = false

            it.isEnabled = false
            button_start.isEnabled = true
            button_pause.isEnabled = false
        }


        // Count down timer pause button
        button_pause.setOnClickListener{
            isPaused = true
            isCancelled = false

            it.isEnabled = false
            button_start.isEnabled = false
            button_stop.isEnabled = false
            button_resume.isEnabled = true
        }


        // Count down timer resume button
        button_resume.setOnClickListener{
            // Resume the timer
            timer(resumeFromMillis,countDownInterval).start()

            isPaused = false
            isCancelled = false

            it.isEnabled = false
            button_pause.isEnabled = true
            button_start.isEnabled = false
            button_stop.isEnabled = true
        }
    }



    // Method to configure and return an instance of CountDownTimer object
    private fun timer(millisInFuture:Long,countDownInterval:Long):CountDownTimer{
        return object: CountDownTimer(millisInFuture,countDownInterval){
            override fun onTick(millisUntilFinished: Long){
                val timeRemaining = "Seconds remaining\n${millisUntilFinished/1000}"

                if (isPaused){
                    text_view.text = "${text_view.text}\nPaused"
                    // To ensure start timer from paused time
                    resumeFromMillis = millisUntilFinished
                    cancel()
                }else if (isCancelled){
                    text_view.text = "${text_view.text}\nStopped.(Cancelled)"
                    cancel()
                }else{
                    text_view.text = timeRemaining
                }
            }

            override fun onFinish() {
                text_view.text = "Done"
            }
        }

   }
}



// Extension function to show toast message
fun Context.toast(message: String) {
    Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}
activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/root_layout"
    android:background="#b8d7bf"
    android:padding="16dp"
    android:orientation="vertical"
    >
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_gravity="center_horizontal"
        >
        <Button
            android:id="@+id/button_start"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Start"
            />
        <Button
            android:id="@+id/button_stop"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Stop(Cancel)"
            android:enabled="false"
            />
        <Button
            android:id="@+id/button_pause"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Pause"
            android:enabled="false"
            />
        <Button
            android:id="@+id/button_resume"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Resume"
            android:enabled="false"
            />
    </LinearLayout>
    <TextView
        android:id="@+id/text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#ff0011"
        android:layout_gravity="center_horizontal"
        android:textSize="25sp"
        android:layout_margin="25dp"
        android:gravity="center"
        />
</LinearLayout>

android kotlin - AlertDialog yes no cancel button example

AlertDialog Yes No Cancel Button
The AlertDialog is a subclass of Dialog that can display one, two, or three Buttons. It can display a text message. Developers can display a more complex View on the alert dialog window using a custom View.

The following android application development tutorial will demonstrate to us how we can display an alert dialog with yes, no, and a cancel button inside it. The code is written in Kotlin programming language. We created the AlertDialog using the native android SDK API.

To create an alert dialog we have to initialize an instance of AlertDialog.Builder object. This AlertDialog Builder object can define the alert dialog’s various properties such as button, message, icon and etc. Finally, we can create an AlertDialog using this builder instance.

So how can we display the yes, no, and cancel buttons inside the alert dialog? Using the AlertDialog Builder instance developers can set its Positive, Negative, and Neutral buttons. Simply we can call the Positive button to the ‘yes’ button, the Negative button to the ‘no’ button, and the Neutral button to the ‘cancel’ button. We also can set the click listeners for those buttons using AlertDialog Builder API. The android SDK display the following buttons inside a dialog window in a good format and position.

This android kotlin tutorial code is written in an android studio IDE. Copy the code and paste it into your android studio IDE and run it on an emulator to see how we create an AlertDialog with yes, no and cancel buttons in an android application.

And how we handle the click events for the alert dialog’s specified button objects in an application. We displayed screenshots of the emulator screen, which also help you to understand the code without running it on an android device or emulator.
MainActivity.kt

package com.cfsuman.kotlintutorials

import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity


class MainActivity : AppCompatActivity() {
    private lateinit var context:MainActivity
    private lateinit var textView:TextView

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

        // Get the context
        context = this;

        // Get the widgets reference from XML layout
        textView = findViewById(R.id.textView)
        val button = findViewById<Button>(R.id.button)

        // Button click listener
        button.setOnClickListener{
            // Show the yes, no and cancel buttons on an alert dialog
            showDialog()
        }
    }


    // Method to show an alert dialog with yes, no and cancel button
    private fun showDialog(){
        // Late initialize an alert dialog object
        lateinit var dialog:AlertDialog

        // Initialize a new instance of alert dialog builder object
        val builder = AlertDialog.Builder(context)

        // Set a title for alert dialog
        builder.setTitle("Title of AlertDialog.")

        // Set a message for alert dialog
        builder.setMessage("I am alert dialog message.")

        // Set the alert dialog positive/yes button
        builder.setPositiveButton("YES"){_, _ ->
            textView.text = "Positive (Yes) button clicked."
        }

        // Set the alert dialog negative/no button
        builder.setNegativeButton("NO"){_, _ ->
            textView.text = "Negative (No) button clicked."
        }

        // Set the alert dialog neutral/cancel button
        builder.setNeutralButton("CANCEL"){_, _ ->
            textView.text = "Neutral (Cancel) button clicked."
        }

        // Initialize the AlertDialog using builder object
        dialog = builder.create()

        // Finally, display the alert dialog
        dialog.show()
    }
}
activity_main.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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/rootLayout"
    android:background="#FEFEFA"
    android:padding="24dp">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Show Dialog"
        android:textAllCaps="false"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        android:fontFamily="sans-serif"
        android:textSize="24sp"
        app:layout_constraintStart_toStartOf="@+id/button"
        app:layout_constraintTop_toBottomOf="@+id/button" />

</androidx.constraintlayout.widget.ConstraintLayout>