Skip to content
Home » startActivityForResult deprecated camera

startActivityForResult deprecated camera

  • by
startActivityForResult deprecated camera

1. Overview

In this article, we will learn about the alternative for the startActivityForResult deprecated camera.

Android introduced the Activity Result APIs as a major change in the androidx.activity:activity:1.2.0 and androidx.activity:activity-ktx:1.2.0 releases.

This API improves code readability, avoids writing code for requesting camera permissions, improves type safety.

2. Old way using startActivityForResult camera

In the old way, we perform the following to get the required result from the Camera application:

  1. Get permission CAMERA and WRITE_EXTERNAL_STORAGE
  2. Create an Intent
  3. Pass intent and also request code to startActivityForResult method. The request code returned in the onActivityResult to identify the request (Intent) for which the result came back.
  4. Register onActivityResult to retrieve the result

For example, the following code requests the CAMERA and WRITE_EXTERNAL_STORAGE permissions to capture video or picture.

private void activeTakePhoto() {

    if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED || 
        ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 110);
    } else {
        takePicture();
    }

}

public void takePicture() {
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
}
@Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        if (requestCode == 110) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED
                    && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
                takePicture();
            }
        }}

The following code retrieves the result Bitmap.

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if(requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK){
        Bundle extra = data.getExtras();
        Bitmap bitmap = (Bitmap) extra.get("data");
        imageView.setImageBitmap(bitmap) ;
    }
}

3. Alternative to deprecated startActivityForResult camera

The Activity Result APIs provide the registerForActivityResult in place of startActivityForResult + onActivityResult.

The registerForActivityResult method takes the following two parameters and returns ActivityResultLauncher as output:

1. ActivityResultContracts

A contract defines the type of action or interaction (Intent) requested from an activity. After getting the result from the activity, it then produces the output of a particular type that makes calling activity for result type-safe.

A collection of standard ActivityResultContracts available for use. Among the contracts available, the TakePicture contract is the replacement to the startActivityForResult camera Intent.

2. ActivityResultCallback

The callback is to be called once the activity result is available. Whatever code you plan to write in your old onActivityResult method must be placed here.

private val takePictureLauncher = registerForActivityResult(
        ActivityResultContracts.TakePicture()
    ) { isSuccess ->
        if (isSuccess) {
            // success
        } else {
            // handle failure
        }
    }

For example, the below registerForActivityResult method takes the ActivityResultContracts.TakePicture as contract and then returns the ActivityResultLauncher as output.

Once you have the ActivityResultLauncher, you can launch the activity using the launch method:

private fun takeImage() {
        val photoFile: File? = viewModel.createImageFile()
        photoFile?.also {
            // You must set up file provider to expose the url to Camera app
            val photoURI: Uri = FileProvider.getUriForFile(
                requireContext(),
                BuildConfig.APPLICATION_ID +".fileProvider",
                it
            )
            takePictureLauncher.launch(photoURI)
        }
    }

You had to pass Uri for getting a full image from the Camera app.

fun createImageFile(): File? {
    return try {
        val file = File(storageDir, "fullImage.jpg")
        if (file.createNewFile() || file.exists()) {
            file
        } else {
            null
        }
    } catch (ex: IOException) {
        ex.printStackTrace()
        null
    }
}

If you only require a preview of the image, you can use the following code:

cameraActivityLauncher.launch(null)

private val cameraActivityLauncher =
    registerForActivityResult(ActivityResultContracts.TakePicture(){ bitmap ->
    // we get bitmap as result directly   
}

Notice that we haven’t passed any request code here as registerForActivityResult automatically takes care of everything including request permissions.

4. Conclusion

To sum up, we have discussed the Activity Result API available from androidx 1.2.0 releases as an alternative to the deprecated startActivityForResult camera. You can also refer settings panel article where we are using the Activity Result API for launching the settings panel.

Leave a Reply

Your email address will not be published. Required fields are marked *