androidandroid-intentandroid-camera-intentactivitynotfoundexceptionregisterforactivityresult

ActivityNotFoundException when accessing the camera using registerForActivityResult


My API 28 application throws this ActivityNotFoundException when trying to capture photos with the camera (both in the Emulator as well as with a real device) using registerForActivityResult: "No Activity found to handle Intent { act=android.media.action.IMAGE_CAPTURE typ=image/jpg flg=0x3 clip={text/uri-list U:content://... "

`public class IntentHelper {

private static final String AUTHORITY = BuildConfig.APPLICATION_ID + ".fileprovider";
File output = null;
private final ActivityResultRegistry mRegistry;
private ActivityResultLauncher<Intent> takePhotoActivityResultLauncher;
private final Context context;
private final Activity activity;
private final FragmentOperationBinding binding;

public IntentHelper(Context context, Activity activity, FragmentOperationBinding binding, ActivityResultRegistry registry) {
    this.mRegistry = registry;
    this.context = context;
    this.activity = activity;
    this.binding = binding;
}

public void handleIntent() {
    setUpLauncher();
    createIntent();
}

private void setUpLauncher() {
    takePhotoActivityResultLauncher = mRegistry.register("key",
            new ActivityResultContracts.StartActivityForResult(),
            new ActivityResultCallback<ActivityResult>() {
                @Override
                public void onActivityResult(ActivityResult result) {
                    if (result.getResultCode() == Activity.RESULT_OK) {
                        final int THUMBSIZE = 64;
                        Bitmap ThumbImage = ThumbnailUtils.extractThumbnail(BitmapFactory.decodeFile(output.getAbsolutePath()),
                                THUMBSIZE, THUMBSIZE);
                        binding.photoThumbnail.setImageBitmap(ThumbImage);
                        Intent returnToCallingActivityIntent = new Intent(context, OperationFragment.class);
                        Uri outputUri = FileProvider.getUriForFile(context, AUTHORITY, output);
                        returnToCallingActivityIntent.setDataAndType(outputUri, "image/jpeg");
                        returnToCallingActivityIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                    }
                }
            });
}

private void createIntent() {//Create Intent
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    if (takePictureIntent.resolveActivity(activity.getPackageManager()) != null) {
        // Create the File where the photo should go
        try {
            output = createImageFile();
        } catch (IOException ex) {
            // Error occurred while creating the File
            Toast.makeText(context, ex.getMessage(), Toast.LENGTH_LONG).show();
        }
        takePictureIntent.setType("image/jpg");
        Uri photoURI = FileProvider.getUriForFile(context, AUTHORITY, output);
        takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
        takePictureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    }
    binding.photoThumbnail.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
                //Launch activity to get result
                takePhotoActivityResultLauncher.launch(takePictureIntent);
        }
    });
}

private File createImageFile() throws IOException {
    // Create an image file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = binding.getOperation().getIdentifier() + "_" + timeStamp;
    File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS + "/operationtimerecord");
    File image = File.createTempFile(
            imageFileName,  /* prefix */
            ".jpg",         /* suffix */
            storageDir      /* directory */
    );
    // Save a file: path for use with ACTION_VIEW intents
    String currentPhotoPath = image.getAbsolutePath();
    return image;
}

}`

I call the handleIntent method in an object of this custom IntentHelper class from a fragment, triggered by a click event. The ActivityResultRegistry parameter passed in the constructor is retrieved in that fragment from the main activity.

The application does create empty files in the corresponding folder while he device camera does not open. The job worked fine before when I was using the deprecated startActivityForResult, so I assume that permissions, paths and dependencies are fine...


Solution

  • Remove the setType() call. And, consider replacing all of this with ActivityResultContracts.TakePicture().