1

I am developing an android application in which I need to import photos from the gallery to save them in the phone's internal memory. I have no idea how to do it, do you have any idea?

I looked on the internet but only came across cases where we wanted to store in the gallery...

Actually, in my application I have objects with a name and an image. For the image, I saved his name (in the drawables) as a String and I will retrieve it by sorting it with the names. I would also like to be able to retrieve images from the phone gallery, but I don't know how to mix the two...

Thank you guy !

Obergam
  • 13
  • 4
  • sounds like you could use the storage access framework. Have a look here: https://developer.android.com/guide/topics/providers/document-provider – Nikos Hidalgo Jul 04 '19 at 15:25
  • When you say "internal memory" do you mean "in memory", or "on disk, in your app's internal storage"? – M.Pomeroy Jul 04 '19 at 15:26
  • @M.Pomeroy I mean in the app's internal storage. it must remain saved even if we delete all the images in the gallery. It would be really cool to be able to save them in the Drawables. – Obergam Jul 05 '19 at 07:44

1 Answers1

0

You can use Android's ACTION_PICK intent to load an image from a users gallery, see here, with EXTERNAL_CONTENT_URI as the target directory. This will allow the user to select an image using some external app, and provide the URI back to your app once a selection has been made. Please note the code below is in Kotlin.

Somewhere in your Activity, start ACTION_PICK for result:

val intent = Intent(Intent.ACTION_PICK,
            android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
startActivityForResult(intent, 0)

You'll get the URI for the image as data in OnActivityResult, from there you'll need to read the file and write it to your apps storage. Since you're going to load this file into an ImageView as well, I'd suggest re-using the stream. I've included a possible way of doing that in the block below, which is to read the stream into a ByteArray, then write that ByteArray to your FileOutputStream and your ImageView(by using the BitmapFactory class).

See below:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)

    if (resultCode == RESULT_OK) {
        val resultUri: Uri? = data?.data

        val extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(contentResolver.getType(resultUri))
        val newFile = File(context.filesDir.absolutePath, "aGeneratedFileName.${extension}")

        var inputStream: InputStream? = null
        var byteStream: ByteArrayOutputStream? = null
        var fileOutputStream: FileOutputStream? = null
        var bitmap: Bitmap? = null
        try {
            inputStream = contentResolver.openInputStream(resultUri)
            fileOutputStream = FileOutputStream(newFile)

            IOUtils.copy(inputStream, byteStream)
            var bytes = byteStream.toByteArray()

            fileOutputStream.write(bytes)
            bitmap = BitmapFactory.decodeByteArray(bytes, 0, byteStream.size())
            myImageView.setImageBitmap(bitmap)
        } catch (e: Exception) {
            Log.e(TAG, "Failed to copy image", e)

            inputStream?.close()
            fileOutputStream?.close()
            byteStream?.close()

            return
        } finally {
            inputStream?.close()
            fileOutputStream?.close()
            byteStream?.close()
        }
    } else {
        // Probably handle this error case
    }
}

I'm assuming you'll want to reload the images you've imported when your app next launches, for that you can fetch a list of files in your filesDir and read them using BitmapFactory.decodeFile.

It seems like your goal is to show an array of images, if you haven't already I suggest you look into the RecyclerView class to implement that. If you run into trouble with it, I suggest you open another question, however.

M.Pomeroy
  • 997
  • 11
  • 22
  • 1
    Thanks for your answer, my aim is to import one file at time. I don't know how to retrieve the image after this to insert it to an ImageView, so I cannot test your solution (even if it make sense). I'm sorry i am a beginner, I don't know much about the Android world. There are so much things (maybe I'm just lost) – Obergam Jul 08 '19 at 11:12
  • No worries, it gets easier, trust me. I'll refine my answer for you a bit, once you have the file, loading it into an ImageView is pretty straight forward. – M.Pomeroy Jul 08 '19 at 14:24
  • I found another way thanks to this link : https://stackoverflow.com/questions/31154777/how-to-read-image-from-internal-memory-in-android I saved the paths in the database and then : `imageViewConceptPicto.setImageDrawable(Drawable.createFromPath(pathFormDatabase))` I don't know if it's as optimized as that, but is works. – Obergam Jul 09 '19 at 07:37