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.