I am using parcelable to pass data between activities (please don't say it is the wrong method because there is a lot of discussion about that).
this is how i capture the image:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_IMAGE_CAPTURE);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 30: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
} else {
Toast.makeText(CameraCapture.this, "Permission denied to read your External storage", Toast.LENGTH_SHORT).show();
}
return;
}
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
dateTimer = getTime();
Log.d("codig",String.valueOf(requestCode));
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Log.d("resultOK","resultOK");
CropImage.activity(data.getData())
.setAspectRatio(1,1)
.setInitialCropWindowPaddingRatio(0)
.setActivityTitle("Corte a foto")
.setActivityMenuIconColor(R.color.nephritis)
.start(this);
}
if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) {
CropImage.ActivityResult result = CropImage.getActivityResult(data);
Log.d("pict12","here");
if (resultCode == RESULT_OK) {
Log.d("pict12","here2");
Uri uri = result.getUri();
Bitmap pic = null;
try {
pic = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri);
} catch (IOException e) {
e.printStackTrace();
}
image = encodeImage(pic);
showDetailsDialog(data);
} else if (resultCode == CropImage.CROP_IMAGE_ACTIVITY_RESULT_ERROR_CODE) {
Exception error = result.getError();
Log.d("pict12",error.toString());
}
}
}
When i capture the image i start a builder to use the simpleCropView lib to cut the image, after that it returns to the second onactivityResult, and shows a details dialog like this:
private void showDetailsDialog(final Intent data) {
final CharSequence[] items = {"Tem fruto?","É arbusto","É árvore?","Tem flor?","Tem espinhos?"};
// arraylist to keep the selected items
final ArrayList seletedItems=new ArrayList();
AlertDialog dialog = new AlertDialog.Builder(this)
.setTitle("Detalhes da fotografia")
.setMultiChoiceItems(items, null, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int indexSelected, boolean isChecked) {
if (isChecked) {
// If the user checked the item, add it to the selected items
seletedItems.add(indexSelected);
} else if (seletedItems.contains(indexSelected)) {
// Else, if the item is already in the array, remove it
seletedItems.remove(Integer.valueOf(indexSelected));
}
}
}).setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
hasFruit = seletedItems.contains(0);
isBush = seletedItems.contains(1);
isTree = seletedItems.contains(2);
hasFlower = seletedItems.contains(3);
hasThorns = seletedItems.contains(4);
if(seletedItems.contains(3)){
dialog.dismiss();
colorDialog(data);
}
else{
startSimiliarActivity();
}
}
}).setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
Log.d("RECREATE","recria");
dialog.dismiss();
CameraCapture.this.recreate();
}
}).create();
dialog.show();
}
if inside this details dialog i check the flower it sends me to another dialog to change the flower color, if i don't check it send me to the similiarActivityMethod where i send the user to the acitvity where i have the blank layout.
Basically i am passing a object with a byte[] filled and other data, not so big i think, when i call the activity that displays blank i pass the parcelable like this:
public void startSimiliarActivity(){
Log.d("HELLWOR","HELLOWOR");
Intent intent = new Intent(CameraCapture.this,SimiliarPhotos.class);
if(location.getAltitude() != 0.0){
altitude = location.getAltitude() - 50;
}
Photo photo = new Photo(image,altitude,location.getLongitude(),location.getAltitude(),dateTimer);
intent.putExtra("photo",photo);
startActivity(intent);
}
and i set it up like this:
package com.example.afcosta.inesctec.pt.android.models;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import java.io.Serializable;
import java.net.URI;
/**
* Created by FilipeCosta on 25/05/2017.
*/
public class Photo implements Parcelable {
private int id;
private Uri image;
private byte[] cropedImage;
private String path;
private Double lat;
private Double lon;
private Double alt;
private String time;
public Photo() {
}
@Override
public int describeContents() {
return 0;
}
public Photo(byte[] cropedImage,Double lat, Double lon, Double alt, String time) {
this.cropedImage = cropedImage;
this.lat = lat;
this.lon = lon;
this.alt = alt;
this.time = time;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.id);
dest.writeParcelable(this.image, flags);
dest.writeByteArray(this.cropedImage);
dest.writeString(this.path);
dest.writeValue(this.lat);
dest.writeValue(this.lon);
dest.writeValue(this.alt);
dest.writeString(this.time);
}
protected Photo(Parcel in) {
this.id = in.readInt();
this.image = in.readParcelable(Uri.class.getClassLoader());
this.cropedImage = in.createByteArray();
this.path = in.readString();
this.lat = (Double) in.readValue(Double.class.getClassLoader());
this.lon = (Double) in.readValue(Double.class.getClassLoader());
this.alt = (Double) in.readValue(Double.class.getClassLoader());
this.time = in.readString();
}
public static final Creator<Photo> CREATOR = new Creator<Photo>() {
@Override
public Photo createFromParcel(Parcel source) {
return new Photo(source);
}
@Override
public Photo[] newArray(int size) {
return new Photo[size];
}
};
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Uri getImage() {
return image;
}
public void setImage(Uri image) {
this.image = image;
}
public byte[] getCropedImage() {
return cropedImage;
}
public void setCropedImage(byte[] cropedImage) {
this.cropedImage = cropedImage;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public Double getLat() {
return lat;
}
public void setLat(Double lat) {
this.lat = lat;
}
public Double getLon() {
return lon;
}
public void setLon(Double lon) {
this.lon = lon;
}
public Double getAlt() {
return alt;
}
public void setAlt(Double alt) {
this.alt = alt;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
i think the issue is related to parcelable since when i commented the Line where i instanciate the photo it works well, but i need the instance :/
any help with this?
The size of the data you can send in an Intent
is limited (to around 500Kb). The photo is most probably exceeds this limit.
There are several possible solutions, the simpliest might be to write your data in a (temporary) File
instead of sending it in an Intent
(and read that File
in the receiving Activity
).
Or just make sure the photo does not exceed the limit (by resizing for example).