Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add java sample and fix bug calling lib from java #125

Merged
merged 8 commits into from
May 9, 2021
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions sample/src/main/java/com/canhub/cropper/sample/SMainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.canhub.cropper.sample

import android.content.Intent
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import com.canhub.cropper.sample.camera.app.SCameraFragment
import com.canhub.cropper.sample.camera_java.app.SCameraFragmentJava
import com.canhub.cropper.sample.crop_image_view.app.SCropImageViewFragment
import com.canhub.cropper.sample.extend_activity.app.SExtendActivity
import com.example.croppersample.R
Expand Down Expand Up @@ -36,6 +38,14 @@ internal class SMainActivity : AppCompatActivity() {
.replace(R.id.container, SCameraFragment.newInstance())
.commit()
}

binding.sampleCropImageJava.setOnClickListener {
hideButtons(binding)
supportFragmentManager
.beginTransaction()
.replace(R.id.container, SCameraFragmentJava.newInstance())
.commit()
}
}

private fun hideButtons(binding: ActivityMainBinding) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,317 @@
package com.canhub.cropper.sample.camera_java.app;

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.FileProvider;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager.widget.ViewPager;

import com.canhub.cropper.CropImage;
import com.canhub.cropper.CropImageView;
import com.canhub.cropper.sample.SCropResultActivity;
import com.canhub.cropper.sample.camera_java.domain.CameraEnumDomainJava;
import com.canhub.cropper.sample.camera_java.domain.SCameraContractJava;
import com.canhub.cropper.sample.camera_java.presenter.SCameraPresenterJava;
import com.example.croppersample.R;
import com.example.croppersample.databinding.FragmentCameraBinding;

import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

import static android.graphics.Color.RED;
import static android.graphics.Color.WHITE;

public class SCameraFragmentJava extends Fragment implements SCameraContractJava.View {

public static final int CODE_PHOTO_CAMERA = 811917;
static final String DATE_FORMAT = "yyyyMMdd_HHmmss";
static final String FILE_NAMING_PREFIX = "JPEG_";
static final String FILE_NAMING_SUFFIX = "_";
Canato marked this conversation as resolved.
Show resolved Hide resolved
static final String FILE_FORMAT = ".jpg";
static final String AUTHORITY_SUFFIX = ".fileprovider";
public static final int CUSTOM_REQUEST_CODE = 8119153;

private FragmentCameraBinding binding;
private SCameraContractJava.Presenter presenter = new SCameraPresenterJava();
Canato marked this conversation as resolved.
Show resolved Hide resolved
private Uri photoUri;
private ActivityResultLauncher<String> requestPermissionLauncher =
Canato marked this conversation as resolved.
Show resolved Hide resolved
registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
presenter.onPermissionResult(isGranted);
});
Canato marked this conversation as resolved.
Show resolved Hide resolved

public static SCameraFragmentJava newInstance(){
return new SCameraFragmentJava();
}

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
binding = FragmentCameraBinding.inflate(inflater, container, false);

return binding.getRoot();
}

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
presenter.bind(this);

binding.startWithUri.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
presenter.startWithUriClicked();
}
});

binding.startWithoutUri.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
presenter.startWithoutUriClicked();
}
});

binding.startPickImageActivity.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
presenter.startPickImageActivityClicked();
}
});

binding.startActivityForResult.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
presenter.startActivityForResultClicked();
}
});
Canato marked this conversation as resolved.
Show resolved Hide resolved

presenter.onCreate(getActivity(), getContext());
}

@Override
public void startCropImage(@NotNull CameraEnumDomainJava option) {
switch (option) {
case START_WITH_URI : startCameraWithUri(); break;
case START_WITHOUT_URI : startCameraWithoutUri(); break;
case START_PICK_IMG : startPickImage(); break;
case START_FOR_RESULT : startForResult(); break;
default: break;
}
}

private void startForResult(){
assert(getContext()!=null);
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), CUSTOM_REQUEST_CODE);

}

private void startPickImage(){
assert(getContext()!=null);
CropImage.activity()
.start(getContext(), this);
}

private void startCameraWithoutUri(){
assert(getContext()!=null);
Context ctx = getContext();
CropImage.activity()
.setScaleType(CropImageView.ScaleType.CENTER)
.setCropShape(CropImageView.CropShape.OVAL)
.setGuidelines(CropImageView.Guidelines.ON)
.setAspectRatio(4, 16)
.setMaxZoom(8)
.setAutoZoomEnabled(false)
.setMultiTouchEnabled(false)
.setCenterMoveEnabled(true)
.setShowCropOverlay(false)
.setAllowFlipping(false)
.setSnapRadius(10f)
.setTouchRadius(30f)
.setInitialCropWindowPaddingRatio(0.3f)
.setBorderLineThickness(5f)
.setBorderLineColor(R.color.black)
.setBorderCornerThickness(6f)
.setBorderCornerOffset(2f)
.setBorderCornerLength(20f)
.setBorderCornerColor(RED)
.setGuidelinesThickness(5f)
.setGuidelinesColor(RED)
.setBackgroundColor(Color.argb(119, 30, 60, 90))
.setMinCropWindowSize(20, 20)
.setMinCropResultSize(16, 16)
.setMaxCropResultSize(999, 999)
.setActivityTitle("CUSTOM title")
.setActivityMenuIconColor(RED)
.setOutputUri(null)
.setOutputCompressFormat(Bitmap.CompressFormat.PNG)
.setOutputCompressQuality(50)
.setRequestedSize(100, 100)
.setRequestedSize(100, 100, CropImageView.RequestSizeOptions.RESIZE_FIT)
.setInitialCropWindowRectangle(null)
.setInitialRotation(180)
.setAllowCounterRotation(true)
.setFlipHorizontally(true)
.setFlipVertically(true)
.setCropMenuCropButtonTitle("Custom name")
.setCropMenuCropButtonIcon(R.drawable.ic_gear_24)
.setAllowRotation(false)
.setNoOutputImage(false)
.setFixAspectRatio(true)
.start(ctx, this);
}

private void startCameraWithUri(){
assert(getContext()!=null);
Context ctx = getContext();
CropImage.activity(photoUri)
.setScaleType(CropImageView.ScaleType.FIT_CENTER)
.setCropShape(CropImageView.CropShape.RECTANGLE)
.setGuidelines(CropImageView.Guidelines.ON_TOUCH)
.setAspectRatio(1, 1)
.setMaxZoom(4)
.setAutoZoomEnabled(true)
.setMultiTouchEnabled(true)
.setCenterMoveEnabled(true)
.setShowCropOverlay(true)
.setAllowFlipping(true)
.setSnapRadius(3f)
.setTouchRadius(48f)
.setInitialCropWindowPaddingRatio(0.1f)
.setBorderLineThickness(3f)
.setBorderLineColor(Color.argb(170, 255, 255, 255))
.setBorderCornerThickness(2f)
.setBorderCornerOffset(5f)
.setBorderCornerLength(14f)
.setBorderCornerColor(WHITE)
.setGuidelinesThickness(1f)
.setGuidelinesColor(R.color.white)
.setBackgroundColor(Color.argb(119, 0, 0, 0))
.setMinCropWindowSize(24, 24)
.setMinCropResultSize(20, 20)
.setMaxCropResultSize(99999, 99999)
.setActivityTitle("")
.setActivityMenuIconColor(0)
.setOutputUri(null)
.setOutputCompressFormat(Bitmap.CompressFormat.JPEG)
.setOutputCompressQuality(90)
.setRequestedSize(0, 0)
.setRequestedSize(0, 0, CropImageView.RequestSizeOptions.RESIZE_INSIDE)
.setInitialCropWindowRectangle(null)
.setInitialRotation(90)
.setAllowCounterRotation(false)
.setFlipHorizontally(false)
.setFlipVertically(false)
.setCropMenuCropButtonTitle(null)
.setCropMenuCropButtonIcon(0)
.setAllowRotation(true)
.setNoOutputImage(false)
.setFixAspectRatio(false)
.start(ctx, this);
}

@Override
public void showErrorMessage(@NotNull String message) {
Log.e("Camera Error:", message);
Toast.makeText(getActivity(), "Crop failed: "+message, Toast.LENGTH_SHORT).show();
}

@Override
public void dispatchTakePictureIntent() {
assert(getContext()!=null);
Context ctx = getContext();
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
try {
if(takePictureIntent.resolveActivity(ctx.getPackageManager()) != null){
String authorities = getContext().getPackageName() + AUTHORITY_SUFFIX;
photoUri = FileProvider.getUriForFile(ctx, authorities, createImageFile());
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
startActivityForResult(takePictureIntent, CODE_PHOTO_CAMERA);
}
} catch (ActivityNotFoundException e) {
// display error state to the user
} catch (IOException e) {
e.printStackTrace();
}
}

@Override
public void cameraPermissionLaunch() {
requestPermissionLauncher.launch(Manifest.permission.CAMERA);
}

@Override
public void showDialog() {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getContext());
alertDialogBuilder.setTitle(R.string.missing_camera_permission_title);
alertDialogBuilder.setMessage(R.string.missing_camera_permission_body);
alertDialogBuilder.setPositiveButton(R.string.ok,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
presenter.onOk();
}
});
alertDialogBuilder.setNegativeButton(R.string.cancel,new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
presenter.onCancel();
}
});
Canato marked this conversation as resolved.
Show resolved Hide resolved
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();

}

@Override
public void handleCropImageResult(@NotNull String uri) {
SCropResultActivity.Companion.start(this, null, Uri.parse(uri), null);
}

@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
presenter.onActivityResult(resultCode, requestCode, data);
}

private File createImageFile() throws IOException {
assert getActivity()!=null;
SimpleDateFormat timeStamp = new SimpleDateFormat(DATE_FORMAT, Locale.getDefault());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

look like this is never used, is this right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is used in dispatchTakePictureIntent

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm talking about the line I tag, 309. look like timeStamp is never used

File storageDir = getActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES);
return File.createTempFile(
"$FILE_NAMING_PREFIX$$FILE_NAMING_SUFFIX",
FILE_FORMAT,
storageDir
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.canhub.cropper.sample.camera_java.domain;

public enum CameraEnumDomainJava {
START_WITH_URI, START_WITHOUT_URI, START_PICK_IMG, START_FOR_RESULT;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.canhub.cropper.sample.camera_java.domain;

import android.content.Context;
import android.content.Intent;
import androidx.fragment.app.FragmentActivity;

public interface SCameraContractJava {

interface View {
public void startCropImage(CameraEnumDomainJava option);
public void showErrorMessage(String message);
public void dispatchTakePictureIntent();
public void cameraPermissionLaunch();
public void showDialog();
public void handleCropImageResult(String uri);
}

interface Presenter {
public void bind(View view);
public void unbind();
public void onPermissionResult(boolean granted);
public void onCreate(FragmentActivity activity, Context context);
public void onOk();
public void onCancel();
public void onActivityResult(int resultCode, int requestCode, Intent data);
public void startWithUriClicked();
public void startWithoutUriClicked();
public void startPickImageActivityClicked();
public void startActivityForResultClicked();
Canato marked this conversation as resolved.
Show resolved Hide resolved
}
}
Loading