Search code examples
androidkotlinandroid-camera

Get image from camera


I am trying to get an image from the camera on an Android device. I want to display the image in an ImageView. I have a button in a fragment that opens the camera. I use the Activity Results API to get the response. Here's the fragment code:

class MainFragment : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_main, container, false)

        val activity = requireActivity()
        val file = File(activity.filesDir,"images/go_capture.png")
        val imageUri = FileProvider.getUriForFile(
            activity,
            BuildConfig.APPLICATION_ID + ".images.provider",
            file
        )
        val takePicture = registerForActivityResult(ActivityResultContracts.TakePicture()) { saved: Boolean ->
            Log.d(MainFragment::class.toString(), "take picture result")
            Log.d(MainFragment::class.toString(), saved.toString())
            val action = MainFragmentDirections.actionImage(imageUri.toString())
            view.findNavController().navigate(action)
        }

        val cameraButton: ImageButton = view.findViewById(R.id.camera_button)
        cameraButton.setOnClickListener {
            takePicture.launch(imageUri)
        }

        return view
    }
}

When I click on the button and take a picture, I get the following exception

Unable to open content: content://codeguru.cameraexample.images.provider/images/go_capture.png
    java.io.FileNotFoundException: open failed: ENOENT (No such file or directory)
    at android.os.ParcelFileDescriptor.openInternal(ParcelFileDescriptor.java:342)
    at android.os.ParcelFileDescriptor.open(ParcelFileDescriptor.java:229)
    at androidx.core.content.FileProvider.openFile(FileProvider.java:632)
    at android.content.ContentProvider.openAssetFile(ContentProvider.java:2026)
    at android.content.ContentProvider.openTypedAssetFile(ContentProvider.java:2202)
    at android.content.ContentProvider.openTypedAssetFile(ContentProvider.java:2269)
    at android.content.ContentProvider$Transport.openTypedAssetFile(ContentProvider.java:548)
    at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:2027)
    at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1842)
    at android.content.ContentResolver.openInputStream(ContentResolver.java:1518)
    at android.graphics.ImageDecoder$ContentResolverSource.createImageDecoder(ImageDecoder.java:278)
    at android.graphics.ImageDecoder.decodeDrawableImpl(ImageDecoder.java:1766)
    at android.graphics.ImageDecoder.decodeDrawable(ImageDecoder.java:1759)
    at android.widget.ImageView.getDrawableFromUri(ImageView.java:1017)
    at android.widget.ImageView.resolveUri(ImageView.java:986)
    at android.widget.ImageView.setImageURI(ImageView.java:561)
    at androidx.appcompat.widget.AppCompatImageView.setImageURI(AppCompatImageView.java:132)
    at codeguru.cameraexample.ImageFragment.onCreateView(ImageFragment.kt:22)
    at androidx.fragment.app.Fragment.performCreateView(Fragment.java:3104)
    at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:524)
    at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261)
    at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1899)
    at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1823)
    at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1760)
    at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2985)
    at androidx.fragment.app.FragmentManager.dispatchStart(FragmentManager.java:2902)
    at androidx.fragment.app.Fragment.performStart(Fragment.java:3171)
    at androidx.fragment.app.FragmentStateManager.start(FragmentStateManager.java:588)
    at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:279)
    at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:113)
    at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1433)
    at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2977)
    at androidx.fragment.app.FragmentManager.dispatchStart(FragmentManager.java:2902)
    at androidx.fragment.app.FragmentController.dispatchStart(FragmentController.java:274)
    at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:359)
    at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:248)
    at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1455)
    at android.app.Activity.performStart(Activity.java:8076)
    at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3660)
    at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
    at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
    at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2210)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loopOnce(Looper.java:201)
    at android.os.Looper.loop(Looper.java:288)
    2022-11-05 11:01:30.720  3702-3702  ImageView               codeguru.cameraexample               W      at android.app.ActivityThread.main(ActivityThread.java:7839)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
2022-11-05 11:01:30.721  3702-3702  ImageView               codeguru.cameraexample               W  resolveUri failed on bad bitmap uri: content://codeguru.cameraexample.images.provider/images/go_capture.png

How do I fix this error? What am I missing?


Solution

  • FileProvider will not create directories for you, even though it will create files for you in a designated directory. So, you should make sure that the directory for your file exists before anything tries using a Uri from FileProvider for that file.