0

My goal is to take a picture via a camera app and save it to a directory. Much like this tutorial explains: https://developer.android.com/training/camera/photobasics

However, onActivityResult returns -1 as return code on some devices. The problem is most likely that the camera app cannot write the photo file to the URI I provide but I don't understand why.

Here are my tests results:

  • Moto G with Android 7: works fine
  • Xiaomi Mi A1 with Android 7.1: fails
  • Samsung Galaxy A40 with Android 9: fails

Here's what I do:

Declare provider in the manifest (along with the proper permisions)

        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="com.mypackage.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/filepaths" />
        </provider>

Declare a proper file path

    <paths>
        <external-path name="my_images"  path="Android/data/com.mypackage/files/Pictures" />
    </paths>

In the activity, launch the camera app with an intent

        Intent(MediaStore.ACTION_IMAGE_CAPTURE).also { takePictureIntent ->

            takePictureIntent.resolveActivity(requireContext().packageManager)?.also {

                val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.FRANCE).format(Date())

                requireContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES)?.let { storageDir ->

                    File.createTempFile("JPEG_${timeStamp}_", ".jpg", storageDir).also {

                        fileUri = FileProvider.getUriForFile(requireContext(), "com.mypackage.fileprovider", it)
                        takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri)
                        startActivityForResult(takePictureIntent, TAKE_PIC_CODE)
                    }
                }
            }
        }
Ika
  • 1,608
  • 14
  • 15
  • Instead of **external-path**, try **** – Alex Cohn Oct 11 '19 at 14:59
  • @AlexCohn I still have the same issue with – Ika Oct 12 '19 at 08:44
  • 1
    Wait a sec… [`RESULT_OK == -1`](https://stackoverflow.com/a/26199510/192373) ‼ – Alex Cohn Oct 13 '19 at 07:25
  • You're right, well done :). My problem is not because resultCode is equal to -1. It is because resultData is null. https://stackoverflow.com/questions/9890757/android-camera-data-intent-returns-null helped me with this null resultData. You put me on the right track. I would accept your answer. – Ika Oct 14 '19 at 08:26

1 Answers1

0
override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) 

When onActivityResult returns -1 as return code, you are actually very lucky: -1 is nothing but Activity.RESULT_OK. Actually, with ACTION_IMAGE_CAPTURE intent, you don't care what the return code is; it's enough to check whether the temp file you opened in storageDir is not empty (an empty file is created in your app, and the image is stored there by a Camera app).

This said, I advice to use <external-files-path name="my_images" path="Pictures" />, to be less dependent on the implementation details of getExternalFilesDir().

If your activity has only one call to startActivityForResult(), you don't need to even check the requestCode.

Finally, in your scenario, requestData will probably be null. This parameter is only relevant when your ACTION_IMAGE_CAPTURE intent does not specify MediaStore.EXTRA_OUTPUT. Luckily, you need no information that requestData Intent could pass to you.

Alex Cohn
  • 56,089
  • 9
  • 113
  • 307