Reputation: 557
I have complete working code to take a picture, crop it, send email with image attachment.
Here is the flow of the code: Take a picture > Find and select the picture we just took from Gallery > Crop it > Email attachment.
I would like to find out how I can skip the whole "Find and select the picture we just took from Gallery" part out and just go straight into cropping immediately after taking the picture.
Is there an Intent that can do what I am requesting?
I've tried this tutorial but it still makes the user go into gallery and look for the picture they just took http://www.londatiga.net/featured-articles/how-to-select-and-crop-image-on-android/
EDIT I should also mention that I have a custom view when I am taking pictures so Im not sure if I can use Intent MediaStore.ACTION_IMAGE_CAPTURE
Here is the code that executes the cropping AND also makes you choose the image you just took by looking in the gallery.
Intent crop_pic = new Intent(Intent.ACTION_PICK, uriTarget); // used to be ACTION_GET_CONTENT /ACTION_PICK
crop_pic.putExtra("crop", "true"); // this enables crop feature
//crop_pic.putExtra("aspectX", 200); // this defines the aspect ration
//crop_pic.putExtra("aspectY", 150);
//crop_pic.putExtra("outputX", 500); // this defines the output bitmap size
//crop_pic.putExtra("outputY", 500);
//crop_pic.putExtra("scale", true);
try { crop_pic.putExtra("return-data", false); // true to return a Bitmap, false to directly save the cropped iamge
crop_pic.putExtra(MediaStore.EXTRA_OUTPUT, uriTarget); // save output image in uri
//crop_pic.setDataAndType(uriTarget, "image/*"); // this will open all images in the Galery
startActivityForResult(crop_pic, EMAIL_PIC);
overridePendingTransition(R.anim.fadein, R.anim.fadeout);
}
catch (ActivityNotFoundException e) {
toast.showToastDialog(getApplicationContext(), e.toString());
}
LOGCAT.DEBUG(TAG, "Cropping Picture");
}
Is there an Intent im not aware of that can just start cropping if I supply it with a uri Target?
Here is the full code:
public class DigitalSignature extends Activity implements SurfaceHolder.Callback{
Camera camera;
SurfaceHolder surfaceHolder;
boolean previewing = false;
Uri uriTarget;
String[] recipients = new String[]{"[email protected]", "",};
final int CROP_PIC = 1, EMAIL_PIC = 2, RETURN_ACTIVITY = 3, FINISH = 4, INDEX_GALLERY = 5;
final String TAG = "Digital Signature";
ToastBuilder toast = new ToastBuilder(this);
ProjectDebug LOGCAT = new ProjectDebug();
ProgressDialogManager pDialog = new ProgressDialogManager();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DigitalSignature.this.requestWindowFeature(Window.FEATURE_NO_TITLE);
DigitalSignature.this.setContentView(R.layout.digitalsignature);
DigitalSignature.this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
DigitalSignature.this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
DigitalSignature.this.getWindow().setFormat(PixelFormat.TRANSLUCENT); // Used to be TRANSPARENT
SurfaceView surfaceView = (SurfaceView)findViewById(R.id.camerapreview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(DigitalSignature.this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
LayoutInflater controlInflater = LayoutInflater.from(getApplicationContext());
View viewControl = controlInflater.inflate(R.layout.control, null);
LayoutParams layoutParamsControl = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
DigitalSignature.this.addContentView(viewControl, layoutParamsControl); // Applying Filters and Parameters
TextView alignsig = (TextView)findViewById(R.id.alignsig);
alignsig.setText("Please take picture of the signature for" + "\n" + "Job Number " + DIGIJOB);
Button buttonTakePicture = (Button)findViewById(R.id.takepicture);
buttonTakePicture.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View arg0) {
LOGCAT.DEBUG(TAG, "Taking Picture");
// Sets camera monochrome filter ( Black and Whiite )
Camera.Parameters parameters = camera.getParameters();
parameters.setColorEffect(android.hardware.Camera.Parameters.EFFECT_MONO);
camera.setParameters(parameters);
camera.startPreview();
// Initiate Camera Focus
camera.autoFocus(mAutoFocusCallback);
// Creates Directory to save image in gallery
uriTarget = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, new ContentValues());
//Notify the MediaScanner that a new file has been added and should be indexed so it shows up in the MediaStore.
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(uriTarget);
sendBroadcast(intent);
}
});
}
Camera.AutoFocusCallback mAutoFocusCallback = new Camera.AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, Camera camera) {
camera.takePicture(myShutterCallback, myPictureCallback_RAW, myPictureCallback_JPG);
}
};
ShutterCallback myShutterCallback = new ShutterCallback(){
@Override
public void onShutter() {
}};
PictureCallback myPictureCallback_RAW = new PictureCallback(){
@Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
}};
PictureCallback myPictureCallback_JPG = new PictureCallback(){
@Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
//bmp = BitmapFactory.decodeByteArray(arg0, 0, arg0.length);
cropPic();
OutputStream imageFileOS;
try {
imageFileOS = getContentResolver().openOutputStream(uriTarget);
imageFileOS.write(arg0);
imageFileOS.flush();
imageFileOS.close();
toast.showToastDialog(getApplicationContext(), "Image saved: " + uriTarget.toString());
}
catch (IOException e) {
toast.showToastDialog(getApplicationContext(), e.toString());
}
// camera.startPreview(); // No need to start preview, we are saving
}}; // picture and no longer initiating camera
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case CROP_PIC:
cropPic();
LOGCAT.DEBUG(TAG, "cropPic Case");
break;
case EMAIL_PIC:
emailPic();
LOGCAT.DEBUG(TAG, "emailPic Case");
break;
case RETURN_ACTIVITY:
returnActivity();
LOGCAT.DEBUG(TAG, "returnActivity Case");
break;
}
}
private void cropPic() {
Intent crop_pic = new Intent(Intent.ACTION_PICK, uriTarget); // used to be ACTION_GET_CONTENT /ACTION_PICK
crop_pic.putExtra("crop", "true"); // this enables crop feature
//crop_pic.putExtra("aspectX", 200); // this defines the aspect ration
//crop_pic.putExtra("aspectY", 150);
//crop_pic.putExtra("outputX", 500); // this defines the output bitmap size
//crop_pic.putExtra("outputY", 500);
//crop_pic.putExtra("scale", true);
try { crop_pic.putExtra("return-data", false); // true to return a Bitmap, false to directly save the cropped iamge
crop_pic.putExtra(MediaStore.EXTRA_OUTPUT, uriTarget); // save output image in uri
//crop_pic.setDataAndType(uriTarget, "image/*"); // this will open all images in the Galery
startActivityForResult(crop_pic, EMAIL_PIC);
overridePendingTransition(R.anim.fadein, R.anim.fadeout);
}
catch (ActivityNotFoundException e) {
toast.showToastDialog(getApplicationContext(), e.toString());
}
LOGCAT.DEBUG(TAG, "Cropping Picture");
}
private void emailPic(){
// new email_pic().execute();
GMailSender m = new GMailSender("[email protected]", "testtest");
String[] toArr = { "[email protected]" };
m.setTo(toArr);
m.setFrom("[email protected]");
m.setSubject("This is an email sent using my Mail JavaMail wrapper from an Android device.");
m.setBody("Email body.");
try {
m.addAttachment(getRealPathFromURI(uriTarget));
if(m.send()) {
Toast.makeText(DigitalSignature.this, "Email was sent successfully.", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(DigitalSignature.this, "Email was not sent.", Toast.LENGTH_LONG).show();
}
} catch(Exception e) {
//Toast.makeText(MailApp.this, "There was a problem sending the email.", Toast.LENGTH_LONG).show();
Log.e("MailApp", "Could not send email", e);
}
// OLD METHOD OF SENDING EMAIL
/* Intent email_pic = new Intent(Intent.ACTION_SEND); // Commence choose photo action
email_pic.putExtra(Intent.EXTRA_EMAIL, recipients); // Inserts Digital Signature address automatically in recipient
email_pic.putExtra(Intent.EXTRA_SUBJECT, DIGIJOB); // Inserts Track Number automatically in subject
email_pic.putExtra(Intent.EXTRA_STREAM, uriTarget); // Attaches image to Gmail
email_pic.setType("image/jpeg"); // Converts image to jpeg
startActivityForResult(email_pic, RETURN_ACTIVITY);
overridePendingTransition(R.anim.fadein, R.anim.fadeout); */
JOB = "job"; // Reset job variable from track no (1736) to "job" so
LOGCAT.DEBUG(TAG, "Emailing Picture"); // when you go back into Jobs Activity, it can parse data.
returnActivity();
}
private void returnActivity() {
Intent email_pic = new Intent(DigitalSignature.this, AgentPortalActivity.class);
startActivityForResult(email_pic, FINISH);
overridePendingTransition(R.anim.fadein, R.anim.fadeout);
LOGCAT.DEBUG(TAG, "Returning Activity");
}
private String getRealPathFromURI(Uri uriTarget) {
String[] projection = { MediaStore.Images.Media.DATA };
@SuppressWarnings("deprecation")
Cursor cursor = managedQuery(uriTarget, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
LOGCAT.DEBUG("getRealPathFromURI", cursor.getString(column_index));
return cursor.getString(column_index);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
if (previewing){
camera.stopPreview();
previewing = false;
}
if (camera != null){
try { camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
previewing = true;
}
catch (IOException e) {
toast.showToastDialog(getApplicationContext(), e.toString());
}
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
camera = Camera.open();
//camera = Camera.open(0);
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopPreview();
camera.release();
camera = null;
previewing = false;
}
}
Upvotes: 1
Views: 6959
Reputation: 2063
You just need to use the MediaStore.ACTION_IMAGE_CAPTURE intent action. That will launch the camera. And in your onActivityResult you can get a the image that was just taken. Now you can crop it and send it and whatever else you'd like. Below is an example.
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File pics = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File cameraPhotoFile = new File(pics, System.currentTimeMillis()+".jpg");
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(cameraPhotoFile));
startActivityForResult(cameraIntent, REQUEST_CODE_CAMERA);
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != Activity.RESULT_OK) return;
if (requestCode == REQUEST_CODE_CAMERA) {
MediaScannerConnection.scanFile(this,
new String[]{cameraPhotoFile.getAbsolutePath()}, null, null);
// do something with the image located at cameraPhotoFile
I've included the MediaScannerConnection because the image will not show up in the gallery until it gets scanned. You can remove that if you want, but I like images that were taken to show up. The bitmap is now located in the "cameraPhotoFile." Use that file however you like.
Also, here are the docs from Google about this called Taking Photos Simply. It's pretty straight forward
Upvotes: 1
Reputation: 2690
The easiest solution i can think of is:
no need for the pick intent.
Upvotes: 0