UCrop from a fragment no requestCode being sent

1.9k Views Asked by At

I am trying to use Ucrop from a fragment. The issue I am facing is that onActivityresult is not receiving requestCode == UCrop.REQUEST_CROP thus not performing the actions I need to do with the image. I have searched around for tutorials but I haven't managed to find any.

The following is the code of the fragment that is using UCrop:

public class FragmentSettingsTabImage extends Fragment {
private String TAG = "----->";
Tools t;
private String currentPhotoPath;
private final int REQUEST_TAKE_PHOTO = 1;
private final int CAMERA_PERMISSIONS = 2;
private ImageView imgTabImageDriver;
private Button btnSettingsSaveImage;

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if (requestCode == CAMERA_PERMISSIONS) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // All good so launch take picture from here
            dispatchTakePictureIntent();
        } else {
            // Permission denied. Warn the user and kick out of app
            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
            builder.setTitle(R.string.permsDeniedCameraTitle);
            builder.setMessage(R.string.permsDeniedCameraMessage);
            builder.setCancelable(false);
            builder.setPositiveButton(R.string.close, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    Objects.requireNonNull(getActivity()).finishAffinity();
                }
            });
            builder.create().show();
        }
    }
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_TAKE_PHOTO && resultCode == Activity.RESULT_OK) {
        Uri starturi = Uri.fromFile(new File(currentPhotoPath));
        Uri destinationuri = Uri.fromFile(new File(currentPhotoPath));
        UCrop.Options options = AppConstants.makeUcropOptions(Objects.requireNonNull(getActivity()));
        UCrop.of(starturi, destinationuri).withOptions(options).start(getActivity());
    }

    Log.d(TAG, "onActivityResult: CCCCCCC" + resultCode + " " + requestCode);

    // On result from cropper add to imageview
    getActivity();
    if (resultCode == Activity.RESULT_OK && requestCode == UCrop.REQUEST_CROP) {
        final Uri resultUri = UCrop.getOutput(data);
        assert resultUri != null;
        File imgFile = new File(resultUri.getPath());
        Picasso.Builder builder = new Picasso.Builder(Objects.requireNonNull(getActivity()));
        builder.listener(new Picasso.Listener() {
            @Override
            public void onImageLoadFailed(Picasso picasso, Uri uri, Exception exception) {
                exception.printStackTrace();
            }
        });
        builder.build().load(imgFile).into(imgTabImageDriver, new Callback() {
            @Override
            public void onSuccess() {
                btnSettingsSaveImage.setEnabled(true);
            }

            @Override
            public void onError(Exception e) {
                e.printStackTrace();
            }
        });
    }
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}

@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    SharedPreferences preferences = Objects.requireNonNull(this.getActivity()).getSharedPreferences("mykago-driver", Context.MODE_PRIVATE);
    final SharedPreferences.Editor editor = preferences.edit();
    View view = inflater.inflate(R.layout.fragment_settings_tab_image, container, false);
    imgTabImageDriver= view.findViewById(R.id.imgTabImageDriver);
    ImageView imgTakeSettingsDriverPicture = view.findViewById(R.id.imgTakeSettingsDriverPicture);
    btnSettingsSaveImage = view.findViewById(R.id.btnSettingsSaveImage);

    imgTakeSettingsDriverPicture.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            dispatchTakePictureIntent();
        }
    });

    imgTabImageDriver.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            dispatchTakePictureIntent();
        }
    });

    btnSettingsSaveImage.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            editor.putString("driver_picture", currentPhotoPath);
            editor.apply();
        }
    });

    Picasso.Builder builder = new Picasso.Builder(Objects.requireNonNull(getContext()));
    builder.listener(new Picasso.Listener() {
        @Override
        public void onImageLoadFailed(Picasso picasso, Uri uri, Exception exception) {
            exception.printStackTrace();
        }
    });

    Log.d(TAG, "onCreateView: " + preferences.getString("driver_picture", ""));

    builder.build().load(new File(preferences.getString("id_picture", ""))).into(imgTabImageDriver);

    return view;
}

private void dispatchTakePictureIntent() {
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    // Ensure that there's a camera activity to handle the intent
    if (takePictureIntent.resolveActivity(Objects.requireNonNull(getActivity()).getPackageManager()) != null) {
        // Create the File where the photo should go
        File photoFile = null;
        try {
            photoFile = createImageFile();
        } catch (IOException ex) {
            // Error occurred while creating the File
            Log.d("IMAGE CREATION", ex.toString());
        }
        // Continue only if the File was successfully created
        if (photoFile != null) {
            Uri photoURI = FileProvider.getUriForFile(getActivity(),
                    "com.mytestapp.fileprovider",
                    photoFile);
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
            startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
        }
    }
}

private File createImageFile() throws IOException {
    // Create an image file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date());
    String imageFileName = "didimage_" + timeStamp + "_";
    File storageDir = Objects.requireNonNull(getActivity()).getExternalFilesDir(Environment.DIRECTORY_PICTURES);
    File image = File.createTempFile(
            imageFileName,
            ".png",
            storageDir
    );

    // Save a file: path for use with ACTION_VIEW intents
    currentPhotoPath = image.getAbsolutePath();
    return image;
}

}

The same code from a normal activity works without any issues. Any help appreciated.

3

There are 3 best solutions below

0
On BEST ANSWER

Managed to solve the issue. To pass the result of the UCrop activity to the fragment and not to the hosting activity you need to call the UCrop....start() method as follows:

UCrop.of(starturi, destinationuri).withOptions(options).start(getActivity().getApplicationContext(), getFragmentManager().findFragmentByTag("your_fragment_tag"));

so

.start(Context, Fragment)

This will make sure that the onActivityResult of the fragment gets called and not the one of the hosting activity.

0
On

This works also:

UCrop.of(sourceUri,destinationUri) .withOptions(options) .start(getActivity(),YourFragment.this);

0
On

If you want to start uCrop activity from Fragment use this.

UCrop.of(uri, destinationFileName)
.withAspectRatio(1, 1)
.start(getContext(), this, UCrop.REQUEST_CROP);