1

I am refactoring the AWS S3TransferUtilitySample from Java to Kotlin, and hit an exception when I try to upload an image. I traced the error to after the gallery intent returns to my app with an image URI. Within onActivityResult, getContentResolver.query(...) is the problem.

  • Java cursor = getContentResolver().query(uri, projection, selection, selectionArgs, null); translates in my code to
  • Kotlin cursor = contentResolver.query(uri, projection, selection, selectionArgs, null).

The query argument values at this point are:

  • uri: content://media/external/images/media
  • projection: {"_data"}
  • selection: "_id=?"
  • selectionArgs: {"3812"}
  • sortOrder: null

I looked up the documentation for contentResolver and I think I may be unpacking the query arguments wrong. I saw this answer, but nothing there helped. Any suggestions?

Thomas
  • 5,810
  • 7
  • 40
  • 48
  • I think in you image media has no image of id `3812` and if you check all media has return to remove `projecton`, `selection`, `selectionArgs` in query only fire query with `uri`; and check result – Ashish Patidar Jul 28 '19 at 06:32
  • Thanks @AshishPatidar. I think `3812` is parsed correctly from the path of the selected image. I'm not sure if I understand your second suggestion. The `query(...)` method must take each of those parameters, so I can't fire it with just `uri`. Please let me know if I'm misunderstanding. – Thomas Jul 30 '19 at 16:12
  • `Cursor c1 = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);` this is example i have run for Contact only for URI other parameter are null. – Ashish Patidar Jul 31 '19 at 06:59

1 Answers1

0

It was a permissions error. In the Logcat, I saw

2019-07-30 09:32:57.566 11640-12481/? E/DatabaseUtils: Writing exception to parcel
    java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/images/media from pid=13823, uid=10149 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()
        at android.content.ContentProvider.enforceReadPermissionInner(ContentProvider.java:633)
        at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:503)
        at android.content.ContentProvider$Transport.query(ContentProvider.java:214)
        at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:102)
        at android.os.Binder.execTransact(Binder.java:697)

Then I saw that I had commented out the permissions code beforehand to get a better understanding of what's going on. Mission accomplished smh. I actually just deleted the commented code and wrote it from scratch to drive the lesson home.

Here's what fixed it:

  • Add permission to AndroidManifest.xml

<uses-permission android:name=“android.permission.READ_EXTERNAL_STORAGE”/>

  • Check for, and grant permission to the app when the user presses the Upload Image button
    buttonUploadImage!!.setOnClickListener {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    val permissions = arrayOf(permission.READ_EXTERNAL_STORAGE)

                    val intent = Intent()
                    intent.action = Intent.ACTION_GET_CONTENT
                    intent.type = "image/*"

                    if (checkSelfPermission(permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                                permission.READ_EXTERNAL_STORAGE)) {
                            // Explain why the permission is needed
                        } else {
                            ActivityCompat.requestPermissions(this, permissions, PERMISSION_CODE)
                        }
                    } else {
                        // Permission has already been granted
                        startActivityForResult(intent, PERMISSION_CODE)
                    }
                }
            }

Resources

Thomas
  • 5,810
  • 7
  • 40
  • 48