24

Android Save Bitmap to Gallery – Download and Save Image from URL

 3 years ago
source link: https://www.simplifiedcoding.net/android-save-bitmap-to-gallery/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Android Save Bitmap to Gallery – Download and Save Image from URL

Things are changing very fast in tech world. And if you want to be an Android Developer, then be ready to keep upgrading yourself. Actually this learning curve is the best thing that I like about this industry (My personal opinion). So, here is a new about about “Android Save Bitmap to Gallery”.

Saving file to internal storage, is required many times in our projects. We have done this thing many times before, but the method for saving file to internal storage has been changed completely for devices running with OS >= android10.

Basically your old way of saving files will not work with new versions of android, starting with android10. You can still go the old way, but it is a temporary solution. In this post we are going to talk about all these things.

File Storage in Android

Now, we have two kinds of storage to store files.

  • App-specific storage: The files for your application only. Files store here cannot be accessed outside your application. And you do not need any permission to access this storage.
  • Shared Storage: The files that can be shared with other apps as well. For example Media Files (Images, Videos, Audios), Documents and other files.

To know more details about File Storage in Android, you can go through this official guide.

In this post we will be saving a Bitmap to Shared Storage as an Image File.

To demonstrate saving file to internal storage in android10, I will be creating an app that will fetch an Image from the Given URL and then it will save it to external storage.

Android Save Bitmap to Gallery

Let’s first start with the main function, that we need to save a Bitmap instance to gallery as an Image File.

    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
            context?.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
            //So I don't think an explanation is needed here
            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)
            context?.toast("Saved to Photos")

Let’s understand the above function.

  • We have the bitmap instance that we want to save to our gallery in the function parameter.
  • Then I’ve generated a file name using System.currentTimeMillis()  , you apply your own logic here if you want a different file name. I used it just to generate a unique name quickly.
  • Now we have created an OutputStream  instance.
  • The main thing here is we need to write two logics, because method of android 10 and above won’t work for lower versions; and that is why I have written a check here to identify if the device is >= VERSION_CODES.Q .
  • Inside the if block, first I’ve got the ContentResolver  from the Context .
  • Inside ContentResolver , we have created ContentValues and inside ContentValues  we have added the Image File informations.
  • Now we have got the Uri  after inserting the content values using the insert()  function.
  • After getting the Uri , we have opened output stream using openOutputStream()  function.
  • I am not explaining the else part, as it is the old way, that we already know.
  • Finally using the output stream we are writing the Bitmap to stream using compress()  function. And that’s it.

Now let’s build a complete application that will save image from an URL to the external storage. 

Creating an Image Downloader Application

Again we will start by creating a new Android Studio project. I have created a project named ImageDownloader. And now we will start by adding all the required dependencies first.

Adding Permissions

For this app we require Internet and Storage permission. So define these permision in your AndroidManifest.xml  file.

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <application
        android:usesCleartextTraffic="true"

Also make sure you add android:usesCleartextTraffic="true"  as I did.

Setting Up Dependencies

We will add the following dependencies inside app level build.gradle  file.

    //androidx activity for handling permission request
    implementation "androidx.activity:activity:1.2.0-alpha08"
    implementation 'androidx.fragment:fragment:1.3.0-alpha08'
    //Coroutines
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9"
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.9"
    //Life cycle components
    implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.3.0-alpha07"
    //new material design
    implementation "com.google.android.material:material:1.3.0-alpha02"
    //Library for downloading image
    implementation "io.coil-kt:coil:0.13.0"

Designing UI

I have designed the following UI for the application.

Android Save Bitmap to Gallery
Android Save Bitmap to Gallery

The UI is pretty simple and I hope you can make a UI like this easily. I am not posting the XML code here; but if you need it you can get the source code at the end of this post.

So basically here we have an EditText to input an Image URL. Two buttons, one to paste the copied URL and another one to Download the image from the given URL.

Creating Utils Function

Create a file named Utils.kt  and write the following code.

fun View.visible(isVisible: Boolean) {
    visibility = if (isVisible) View.VISIBLE else View.GONE
fun View.enable(isEnabled: Boolean) {
    setEnabled(isEnabled)
    alpha = if (isEnabled) 1f else 0.5f
fun Context.toast(text: String?) {
    Toast.makeText(this, text, Toast.LENGTH_LONG).show()
fun Context.showPermissionRequestDialog(
    title: String,
    body: String,
    callback: () -> Unit
    AlertDialog.Builder(this).also {
        it.setTitle(title)
        it.setMessage(body)
        it.setPositiveButton("Ok") { _, _ ->
            callback()
    }.create().show()

We will be using these functions, in our MainActivity .

Downloading and Saving Bitmap to Gallery

Now we just need to add the functionality in our MainActivity.kt  file. The code is very straight forward so I am directly showing the whole MainActivity  here.

class MainActivity : AppCompatActivity() {
    //ImageLoader instance
    private lateinit var imageLoader: ImageLoader
    //Permission Request Handler
    private lateinit var requestPermissionLauncher: ActivityResultLauncher<String>
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //Setting up Activity Permission Request Handler
        setPermissionCallback()
        progressbar.visible(false)
        //getting imageloader instance
        imageLoader = Coil.imageLoader(this)
        button_paste_link.setOnClickListener {
            pasteLink()
        button_download.setOnClickListener {
            val bitmapURL = edit_text_image_url.text.toString().trim()
            //when download is pressed check permission and save bitmap from url
            checkPermissionAndDownloadBitmap(bitmapURL)
        edit_text_image_url.addTextChangedListener {
            button_download.enable(it.toString().isNotEmpty())
    //Allowing activity to automatically handle permission request
    private fun setPermissionCallback() {
        requestPermissionLauncher =
            registerForActivityResult(
                ActivityResultContracts.RequestPermission()
            ) { isGranted: Boolean ->
                if (isGranted) {
                    getBitmapFromUrl(edit_text_image_url.text.toString().trim())
    //function to check and request storage permission
    private fun checkPermissionAndDownloadBitmap(bitmapURL: String) {
        when {
            ContextCompat.checkSelfPermission(
                this,
                Manifest.permission.WRITE_EXTERNAL_STORAGE
            ) == PackageManager.PERMISSION_GRANTED -> {
                getBitmapFromUrl(bitmapURL)
            shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE) -> {
                showPermissionRequestDialog(
                    getString(R.string.permission_title),
                    getString(R.string.write_permission_request)
                    requestPermissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
            else -> {
                requestPermissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
    //this function will fetch the Bitmap from the given URL
    private fun getBitmapFromUrl(bitmapURL: String) = lifecycleScope.launch {
        progressbar.visible(true)
        image_view.load(bitmapURL)
        val request = ImageRequest.Builder(this@MainActivity)
            .data(bitmapURL)
            .build()
            val downloadedBitmap = (imageLoader.execute(request).drawable as BitmapDrawable).bitmap
            image_view.setImageBitmap(downloadedBitmap)
            saveMediaToStorage(downloadedBitmap)
        } catch (e: Exception) {
            toast(e.message)
        progressbar.visible(false)
    //the function I already explained, it is used to save the Bitmap to external storage
    private fun saveMediaToStorage(bitmap: Bitmap) {
        val filename = "${System.currentTimeMillis()}.jpg"
        var fos: OutputStream? = null
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            contentResolver?.also { resolver ->
                val contentValues = ContentValues().apply {
                    put(MediaStore.MediaColumns.DISPLAY_NAME, filename)
                    put(MediaStore.MediaColumns.MIME_TYPE, "image/jpg")
                    put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES)
                val imageUri: Uri? =
                    resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
                fos = imageUri?.let { resolver.openOutputStream(it) }
        } else {
            val imagesDir =
                Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
            val image = File(imagesDir, filename)
            fos = FileOutputStream(image)
        fos?.use {
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, it)
            toast("Saved to Photos")
    //Pasting the value from Clipboard to EditText
    private fun pasteLink() {
        val clipboard: ClipboardManager? =
            getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager?
        if (clipboard?.hasPrimaryClip() == true) {
            edit_text_image_url.setText(clipboard.primaryClip?.getItemAt(0)?.text.toString())

The code is very straight forward, but in case you have a problem; don’t hesitate to ask.

Now you can run your application and you will see the following result.

android save bitmap to gallery app
Image Downloader
I have created a special space for
Simplified Coding in Quora.
You can join here to ask your question in detail.

Android Save Bitmap to Gallery Source Code

In case you need the source code of this tutorial, you can get it from here.

So that is all for this tutorial friends. Make sure you share it with your friends, if you found this post helpful. Thank You

Hi, my name is Belal Khan and I am a Google Developers Expert (GDE) for Android. The passion of teaching made me create this blog. If you are an Android Developer, or you are learning about Android Development, then I can help you a lot with Simplified Coding.

Checkout these tutorials as well:

  • Dagger 2 Android Example using Retrofit : Injecting Dependency
  • Android Data Binding Library Tutorial with Firebase
  • Firebase Phone Authentication Android Tutorial
  • Android Splash Screen Example - Implementing Splash Screen
  • Android Paging Library Tutorial using Retrofit
  • Android Room Database Example - Building a Todo App

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK