Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin: How to save image from Internet to internal storage

Tags:

android

kotlin

I am new to Android Studio and especially to Kotlin. I need to load image from internet and then save it to phone. I tried to load image with Glide as Bitmap and then save it. But it doesn't work. This code is best thing i found but it doesn't work.

try {
var bitmap = Glide.with(this)
        .asBitmap()
        .load("https://s3.amazonaws.com/appsdeveloperblog/Micky.jpg")
        .apply(RequestOptions().override(100).downsample(DownsampleStrategy.CENTER_INSIDE).skipMemoryCache(true).diskCacheStrategy(DiskCacheStrategy.NONE))
        .submit().get()
    val wrapper = ContextWrapper(applicationContext)
    var file = wrapper.getDir("Images", Context.MODE_PRIVATE)
    file = File(file, "img.jpg")
    val out = FileOutputStream(file)
    bitmap.compress(Bitmap.CompressFormat.JPEG, 85, out)
    out.flush()
    out.close()
}
catch (e: Exception) {
    println(e)
}

How I understood problem is in this ".submit().get()" part of Glide. But if I take it away then compress doesn't work.

like image 949
Seiggailion Avatar asked Nov 02 '18 16:11

Seiggailion


2 Answers

submit(): Returns a future that can be used to do a blocking get on a background thread.

get(): Waits if necessary for the computation to complete, and then retrieves its result.

In your case to download an image from a url and save it to internal storage, you should use a background thread to do that. If you calling on main thread, your app might be throws ANR dialog.

Here I will demo how to download and save the image by using AsyncTask API

First write a class to download and save the image.

class DownloadAndSaveImageTask(context: Context) : AsyncTask<String, Unit, Unit>() {
    private var mContext: WeakReference<Context> = WeakReference(context)

    override fun doInBackground(vararg params: String?) {
        val url = params[0]
        val requestOptions = RequestOptions().override(100)
            .downsample(DownsampleStrategy.CENTER_INSIDE)
            .skipMemoryCache(true)
            .diskCacheStrategy(DiskCacheStrategy.NONE)

        mContext.get()?.let {
            val bitmap = Glide.with(it)
                .asBitmap()
                .load(url)
                .apply(requestOptions)
                .submit()
                .get()

            try {
                var file = it.getDir("Images", Context.MODE_PRIVATE)
                file = File(file, "img.jpg")
                val out = FileOutputStream(file)
                bitmap.compress(Bitmap.CompressFormat.JPEG, 85, out)
                out.flush()
                out.close()
                Log.i("Seiggailion", "Image saved.")
            } catch (e: Exception) {
                Log.i("Seiggailion", "Failed to save image.")
            }
        }
    }
}

Then in activity just call

class MainActivity : AppCompatActivity() {

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

        DownloadAndSaveImageTask(this).execute("https://s3.amazonaws.com/appsdeveloperblog/Micky.jpg")
    }
}

If you want to save to internal storage

var file = File(it.filesDir, "Images")
if (!file.exists()) {
    file.mkdir()
}
file = File(file, "img.jpg")

It will save the image in path data/data/yourapppackagename/files/Images/img.jpg

like image 73
Son Truong Avatar answered Nov 04 '22 19:11

Son Truong


Just use this method

    fun DownloadImageFromPath(path: String?) {
    var `in`: InputStream? = null
    var bmp: Bitmap? = null
    val iv = findViewById<View>(R.id.imagFullImage) as ImageView
    var responseCode = -1
    try {
        val url = URL(path) //"http://192.xx.xx.xx/mypath/img1.jpg
        val con: HttpURLConnection = url.openConnection() as HttpURLConnection
        con.setDoInput(true)
        con.connect()
        responseCode = con.getResponseCode()
        if (responseCode == HttpURLConnection.HTTP_OK) {
            //download
            `in` = con.getInputStream()
            bmp = BitmapFactory.decodeStream(`in`)
            `in`.close()
            iv.setImageBitmap(bmp)
        }
    } catch (ex: Exception) {
        Log.e("Exception", ex.toString())
    }
}
like image 38
Jewel Rana Avatar answered Nov 04 '22 18:11

Jewel Rana