java.lang.SecurityException: Permission Denial: opening provider…

Akshat Chaturvedi
Bobble Engineering
Published in
3 min readOct 3, 2022

Images are one of the most used part of any android application, but when we pick images from our gallery and display them in our android application we may get a very annoying as well as important to be known about exception called java.lang.SecurityException: Permission Denial: opening provider {Uri of the image}.

I was making an application which stores user data and let’s the user select images from gallery or capture one using a camera. Now for capturing from camera the stuff was simple, as the images get stored in app’s internal folder the I created using content provider. The real challenge was to pick from gallery, as that part of the memory is not accessible.
However adding some permissions into manifest let’s you use those images which were clearly given in majority of tech communities.
I added the following ones..

These permissions lets you load the images smoothly, but my concern was to store them into my room database and display them into my recyclerView, if I store them as a bitmap into my database(not a recommended way) my application will take too much space and will not even store heavy images, the second way was to store them as Uri string, which I adapted.

When we store them into our database and try to fetch them into my adapter class we’ll get this exception, cause we’re now in a new activity and we don’t have a permission here.
Till android 10 we can use ActivityResultContracts.OpenDocument() to open our images but in andro11+ versions we will again have a highly probable chance of getting this kind of exception.

Okay enough of story let’s come to a solution, Google has made security stuff more and more restricted so that apps doesn’t get unnecessary rights on our device and we can have a hassle free and safe user experience. Giving permissions at every access is one solution that might be overwhelming to a lot of beginners, but there’s one more way for that and is quite simpler, and that is when you get the Uri from intent for the image you’ve selected just create a bitmap of it, and then that bitmap will be stored in your app’s internal storage and you don’t need any permissions to access these Uri’s, you can fetch them with full freedom.

Code the convert fetched Uri to bitmap….
val bit: Bitmap= Images.Media.getBitmap(content Resolver, uri)

//uri is the uri that I’ve received from the intent

then convert the bit into uri…

val tempUri: Uri = getImageUriFromBitmap(applicationContext, bit!!)private fun getImageUriFromBitmap(context: Context?, bitmap: Bitmap): Uri {
val bytes = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.JPEG,100,bytes)
val path = MediaStore.Images.Media.insertImage(context!!.contentResolver,bitmap,"File",null)
return Uri.parse(path.toString())

}

and then this tempUri is free to be stored in the database and can easily be loaded to any of the imageView as required using Glide or any other library.

So here was a small experience that I wanted to share to the community:)

--

--