I have a class(A) who need to take a picture, so I create an other class(B) with this responsibility. But the problem is, that A don't wait the result of B. How can I do that?
Here is my code :
Class which take the picture
static final int REQUEST_IMAGE_CAPTURE = 1;
Bitmap image = null;
public void takePicture(Context context, Activity activity) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(context.getPackageManager()) != null) {
activity.startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Bundle extras = data.getExtras();
image = (Bitmap) extras.get("data");
}
}
public Bitmap getImage(){
return image;
}
The method which call the the Camera class
public void openCamera() {
Bitmap image = null;
camera.takePicture((Context) _addView, (Activity) _addView);
image = camera.getImage();
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
byte[] picture = outStream.toByteArray();
_addView.SetCameraPicture(picture);
}
While taking pictures what you are doing is opening another app(startActivityForResult) which is capable of taking pictures. When the app finishes taking the picture you are sent the data through an intent which you listen using onActivityResult. The other class B must be an
Activity(startActivityForResult() can be called only from an Activity).
So with your scenario, you must first open Activity B, then take the picture,
put the result into an intent and start Activity A with that data, which just does not make any sense. If you want to follow DRY principles put your photo taking method into a utility class and dependency inject your class to wherever you need it. Hope this helps.
You can always try to make class B async and then let class A await the method of class B
Related
I have integrated crop image library in my application which have function for take and use picture taken via camera. My developer have done it as expected but now when I have checked via take picture from camera than after take picture and set it on crop page, its getting blur before we set it.My developer is out of coverage for some task. I have asked library developer and they have given me solution for integrate code like below
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);Uri outputFileUri = Uri.fromFile(new File(context.getExternalCacheDir().getPath(), "pickImageResult.jpeg"));intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
and My developer have integrated code like below in my application
#Override
public void onClick(DialogInterface dialog, int which) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent,REQ_PHOTO_CAMERA);
}
}
as well method like below
public final int REQ_PHOTO_CAMERA=243;
public final int REQ_PHOTO_GALLERY=346;
public final int REQ_APP_GALLERY=427;
public final int ACTION_CHANGE_BACKGROUND=1;
public final int ACTION_CHANGE_AUTHOR=2;
private int mChangeAction;
public void onActivityResult(int req,int res,Intent data){
if(res==RESULT_OK){
if(req==REQ_PHOTO_CAMERA){
Bitmap cameraImg = (Bitmap) data.getExtras().get("data");
cropAndSaveImage(cameraImg);
//updateCustomImage(cameraImg);
}else if(req==REQ_PHOTO_GALLERY){
try {
Bitmap imgGallery = MediaStore.Images.Media.getBitmap(getApplicationContext().getContentResolver(), data.getData());
// updateCustomImage(imgGallery);
cropAndSaveImage(imgGallery);
} catch (IOException e) {
// e.printStackTrace();
}
}else if (req == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) {
CropImage.ActivityResult result = CropImage.getActivityResult(data);
Uri resultUri = result.getUri();
Log.e("ImageUrl",resultUri.getPath());
updateCustomImage(BitmapFactory.decodeFile(resultUri.getPath()));
}else if(req==REQ_APP_GALLERY){
String imgPath=data.getStringExtra("ImagePath");
try {
InputStream inputStream=getAssets().open(imgPath);
Bitmap image=BitmapFactory.decodeStream(inputStream);
cropAndSaveImage(image);
} catch (IOException e) {
}
}
}
}
public void cropAndSaveImage(Bitmap imgPicked){
ImageLoader.getInstance().saveTempImage(imgPicked);
CropImage.activity(ImageLoader.getInstance().getTempImageUri())
.setInitialCropWindowPaddingRatio(0)
.setFixAspectRatio(false)
.setAspectRatio(1,2)
.setGuidelines(CropImageView.Guidelines.ON)
.start(this);
}
let me know what I am missing ?
Note : we have used this library : Link
Thanks
Your original image taken using camera will be here-
Uri outputFileUri = Uri.fromFile(new File(context.getExternalCacheDir().getPath(), "pickImageResult.jpeg"));
in this file.
the Bitmap cameraImg = (Bitmap) data.getExtras().get("data"); is just a thumbnail returned.
I have Activity A, B and C. In Activity C, it has an image and caption. The image and caption will be return to B when ok button is clicked. In activity b, it will return both to activity A.
Activity C
ok.setOnClickListener(new View.OnClickListener() // ok button to return image and caption to B
{
public void onClick(View arg0)
{
Intent returnIntent=new Intent();
text=t.getText().toString();
b.setDrawingCacheEnabled(true);
b.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
b.layout(0, 0, b.getMeasuredWidth(), b.getMeasuredHeight());
b.buildDrawingCache(true);
returnIntent.putExtra("text", text);
if (b.getDrawingCache() != null) {
Bitmap bitmap = Bitmap.createBitmap(b.getDrawingCache());
if (bitmap == null) {
Log.e("TAG", "getDrawingCache() == null");
}
Global.img = bitmap;
}
setResult(Activity.RESULT_OK, returnIntent);
finish();
}
});
Activity B
public void onActivityResult(int requestCode,int resultCode, Intent data)
{
if(requestCode==PROJECT_REQUEST_CODE) {
if(data!=null&&data.hasExtra("text")) {
c = data.getStringExtra("text");
txt1.setText(c); // caption can show in txt1
viewImage.setImageBitmap(Global.img); // image from C can show in viewImage
}
}
else if (requestCode==CAMERA_REQUEST_CODE)
{
}
}
b.setOnClickListener(new View.OnClickListener() { // button to return image and caption to A
public void onClick(View arg0) {
Intent returnIntent = new Intent();
returnIntent.putExtra("c",c); // return caption
returnIntent.putExtra("globalImg",Global.img);
setResult(Activity.RESULT_OK, returnIntent);
finish();
}
});
Activity A
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Bitmap b = Global.img
if (requestCode==1) {
caption = data.getStringExtra("c"); // caption from A
v.setImageBitmap(Global.img) // image from C
}else if {.....}
}
Global.java
public class Global {
static Bitmap img;
}
When I click button b in Activity B, I get this
11-05 17:26:47.114 6031-6031/com.example.project.project
E/JavaBinder﹕ !!! FAILED BINDER TRANSACTION !!!
Provided what you are trying to do is simply to pass along the data returned from C->B on to A, why don't you just get the string again in your onClick and put it into your intent?
You could store the text in a String member, or, as the code looks now, even get it back from the TextView:
Intent returnIntent = new Intent();
returnIntent.putExtra("text", txt1.getText().toString);
setResult(Activity.RESULT_OK, returnIntent);
The image is being stored as a static in a global object, which honestly is horrible, but you could of course access that as well from your onClickListener. You should however seriously consider returning the bitmap data in some other way, the most straightforward probably being utilizing that Bitmaps implement the Parcelable interface, and Intents can hold Parcelables as extras, so in theory you can just do putExtra("img", bitmap) and on the receiving end do intent.getParcelableExtra("img").
However, if the bitmap is large this might fail, and it might be better to store the bitmap to a resource such as a file, and pass the location of the file instead. You may also get a way with something like what you did with your static member in the Global class, but 1) you must be careful to remove the object after passing it back or the static reference will waste memory and 2) make sure you don't use this reference incorrectly, e.g. from multiple places simulatenously. A more robust solution is to make sure you create a unique ID for each bitmap and store it in a cache (for example a HashMap with the Bitmaps hashCode() as the key) and identify it by id.
public class BitmapStore {
private static final HashMap<Integer, Bitmap> BITMAPS= new HashMap<>();
public static Bitmap getBitmap(int id) {
return BITMAPS.remove(id);
}
public static int putBitmap(Bitmap b) {
int id = b.hashCode();
BITMAPS.put(id, b);
return id;
}
}
Using this, you could put the ID of your bitmap in your intent:
intent.putExtra("imageId", BitmapStore.putBitmap(bitmap));
setResult(RESULT_OK, intent);
and in onActivityResult:
Bitmap b = BitmapStore.getBitmap(intent.getIntExtra("imageId", 0));
This bitmap store is not persistant but it should be pretty safe to use as an intermediate store in the transition between two activities. It's also possible to generalize to any kind of object implementing a valid hashCode/equals contract.
try comment this line:
//returnIntent.putExtra("globalImg",Global.img);
in your Activity B
You can use Global.img for all Activity and not use intent
Added:
v.setImageBitmap(Global.img); -> nullPointerExeption becouse v is not initialize
Added:
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmapOptions.inJustDecodeBounds = false;
bitmapOptions.inPreferredConfig = Config.RGB_565;
bitmapOptions.inDither = true;
For "Out of memory" error.
I'm trying to get a program to let the user to import a custom background.
Here's where I'm at:
I have the getDrawable function taking another function as an argument:
mDrawableBg = getResources().getDrawable(getImage());
getImage() is suppose to return a integer referencing the selected image, here is the code (so far) for that function:
public int getImage(){
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, 10);
}
This is suppose to open the gallery and let the user select an image. I would then use mDrawableBg to set the background. I'm not sure how to return a reference ID to that selected image though. Any suggestions?
Try this:
String pathName = "selected Image path";
Resources res = getResources();
Bitmap bitmap = BitmapFactory.decodeFile(pathName);
BitmapDrawable bd = new BitmapDrawable(res, bitmap);
View view = findViewById(R.id.container);
view.setBackgroundDrawable(bd);
The way you're attempting to do it is not possible, I'm afraid. One of the things you'll want to learn as a new Android developer is how the cycle between activities works. In your case, you're running an Activity that calls upon an Intent to get data from it. However, in the Android API, an Intent can only be referenced on its own time. This means you can't use your getImage() method the way you had tried.
There is hope, though!
What you first need to do is call the Intent. You will do this through the code you have now in getImage():
public void getImage() { // This has to be a void!
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, 10);
}
This method will now start the Image Picker that you want users to select from. Next, you have to catch what is returned. This cannot be returned from your getImage() method, but instead must be collected from elsewhere.
You must implement the below method:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
final int SELECT_PICTURE = 1; // Hardcoded from API
if (requestCode == SELECT_PICTURE) {
String pathToImage = data.getData().getPath(); // Get path to image, returned by the image picker Intent
mDrawableBg = Drawable.createFromPath(pathToImage); // Get a Drawable from the path
}
}
}
Lastly, instead of calling mDrawableBg = getResources().getDrawable(getImage());, just call getImage();. This will initialize the Image Picker.
Some reading:
Android Activity (notably stuff about Intents and getting a result back)
Android Drawable
Getting a Drawable from a path
More on the Image Picker Intent
Good luck!
I'm not sure, but if you mean you don't know how to receive results from that intent, you can use :
#Override
protected void onActivityResult(int requestCode,int resultCode,Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_OK)
{
if (requestCode == 10)
{
// DoSomething
}
}
}
I have an application that allow users to choose picture from native gallery then I show this image in image view widget.
My question is:
1-i have to send this image to another Activity. How can i do it.
2-in the receiver Activity i should show it in image view widget as in image not link or Something
I tried this code but it gives me a RunTime Error
Bitmap image = Bitmap.createBitmap(view.getWidth(), view.getHeight(),Bitmap.Config.RGB_565);
view.draw(new Canvas(image));
String url = Images.Media.insertImage(getContentResolver(), image,"title", null);
Just follow the below steps...
Uri uri = null;
1) on any click event use the below code to open native gallery
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"),0);
This will open gallery select picture will return you to your activity. OnActivity result.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case 0:
if (resultCode == RESULT_OK) {
try {
uri = Uri.parse(data.getDataString());
imageView.setImageUri(uri);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}}
break;
}
}
2) Also instead of passing the image you can pass the URI to next activity as you pass string and inthe secont activity you get it using intent.
Intent i = new Intent(this, Second.class);
i.putExtra("URI", uri.toString() );
startActivity(i);
and in the second activity
String uri = getIntent().getStringExtra("URI");
Now you have string just set it to the image view like below
imageView.setImageUri(Uri.parse(uri));
Use intent putExtra and send uri of the image user selected in Acvtivity1 and in second activity use intent getExtra to read the uri
Refer this answer https://stackoverflow.com/a/7325248/308251
Maybe this is not what you're looking for and it's a bit poor but saved my life when I needed to pass objects between Activities.
public class MagatzemImg {
private static MagatzemImg instance = null;
private static Bitmap img;
public MagatzemImg(){
img=null;
}
public static MagatzemImg getInstance() {
if (instance == null)
instance = new MagatzemImg();
return instance;
}
public static void setImg(Bitmap im){
img = im;
}
public static Bitmap getImg(){
Bitmap imgAux = img;
img = null;
return imgAux;
}
}
And then from the new activity:
MagatzemImg.getInstance();
image = MagatzemImg.getImg();
You can 'assure' to the new Activity that the image exists inside the Static Class through putExtra("image",true) or something else you prefer, like checking if the "image" is null.
I'm trying to create a small app for Android that takes a picture using the device's camera and put's a PNG frame on top of it. This way the final saved picture will have a beach on top of it, or hats, or anything. Does anyone have any sample programs with this behavior?
Have a look at the SDK documentation on using the image capture intent here.
I start my image capture intent like this:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE is a private member in my activity:
private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
Then get the byte array back from the camera by using the following onActivityResult handler:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK) {
Bitmap bmp = (Bitmap) data.getExtras().get("data");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
AddImage(byteArray);
} else if (resultCode == Activity.RESULT_CANCELED) {
// User cancelled the image capture
} else {
// Image capture failed, advise user
}
}
}
After that you can do all the processing you want on the image.