8

I am trying to simply take a picture and present it in an ImageView with my samsung galaxy s. it's working fine when I do it on landscape but not on portrait. I am not getting any error or exception - just not getting anything... There is a lot of questions about this topic and it seems to be problematic (something about camera orientation) but counldn't figure out the final solution for a simple "take a picture and present it" code. here is my (problematic) code that doesn't work:

private void setUpListeners() {
    takePicture.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View arg0) {
            Intent cameraIntent = new Intent(
                    android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
            startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);
        }
    });
}

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == RESULT_OK) {
        if (requestCode == CAMERA_PIC_REQUEST) {
            Log.d("onActivityResult", "CAMERA_PIC_REQUEST returned");
            dishImage = (Bitmap) data.getExtras().get("data");
            if (dishImage==null)
                Log.d("onActivityResult", "dishImage==null");
            imageView = (ImageView) findViewById(R.id.dishinfodishimageview);
            imageView.setImageBitmap(dishImage);
            imageView.setVisibility(View.VISIBLE);
            takePicture.setVisibility(View.GONE);
            (new UploadImage()).execute(null);
        }
    } else {
        Log.e("onActivityResult",
                "no able to presenting the picture of the dish");
    }

}

I just need a code that works (on any device) or a fix to my code... thx.

rekire
  • 47,260
  • 30
  • 167
  • 264
yehudahs
  • 2,488
  • 8
  • 34
  • 54
  • see this old [answer](http://stackoverflow.com/a/11084765/1250370). It might help you. :) – Deepak Sep 01 '12 at 12:19
  • for rotate your bitmap image refer to this [link](http://stackoverflow.com/a/6051340/1250370) – Deepak Sep 01 '12 at 12:33
  • I still don't get it :in portrait orientation I don't get a rotated picture...I don't get a picture at all...and not an error or exception...its seems that its skipping the line imageView.setImageBitmap(dishImage);(but in landscape it's working...) – yehudahs Sep 01 '12 at 14:09
  • found the problem - for some reason when the picture is taken in a landscape when resuming to the activity, the onCreate isn't being called. **However, when taken a picture in a portrait orientation , the onCreate function is called and reset the activity variables** and therefore I didn't saw the taken picture... do someone know the reason for this behavior ? – yehudahs Sep 01 '12 at 19:39
  • has anyone found a solution in this weird behaviour?? I am having the same troubles and... I am stack overflow!! – TurboManolo Feb 27 '13 at 14:07
  • This should help! [See this, as how I used to fix the orientation issue][1] [1]: http://stackoverflow.com/a/16742014/583344 – nithinreddy May 24 '13 at 19:08
  • Visit here . The guy has represented a complete solution to this. – Yashar PourMohammad Oct 07 '13 at 19:02

4 Answers4

2

The reason that onCreate() is called is because when you do call the camera activity during the portrait orientation, it will change the orientation and destroy your previous activity. After finishing the onActivityResult(), your activity will be re-created.

One solution to this problem is to set the manifest to ignore changes on orientation change, you can do it by using this:

<activity android:name=".MyMainActivity"
     android:configChanges="orientation"
     android:label="@string/app_name" />

If you are using API starts with level 13, you can consider screenSize for the configChanges manifest.

dtheo
  • 123
  • 5
1

I can only suggest a hack for this problem. Save your results in shared preferences in onActivityResult() and during onCreate load your content from shared preferences. I know this is a bad solution but this will keep you going until you find a better answer. And don't forget to clear your shared preferences once you are done, else your activity will always initialize with old data.

ЯegDwight
  • 24,821
  • 10
  • 45
  • 52
ashutosh
  • 11
  • 1
  • 1
1

Try the following code.. it worked for me with Samsung galaxy S2 Insert the Following Code in onActivityResult()

ExifInterface exif = new ExifInterface(cameraimagename);
                    String orientString = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
                    int orientation = orientString != null ? Integer.parseInt(orientString) : ExifInterface.ORIENTATION_NORMAL;
                    int rotationAngle = 0;
                    System.out.println("orientation is : "+orientation);
                    System.out.println("ExifInterface.ORIENTATION_ROTATE_90 : "+ExifInterface.ORIENTATION_ROTATE_90);
                    System.out.println("ExifInterface.ORIENTATION_ROTATE_180 : "+ExifInterface.ORIENTATION_ROTATE_180);
                    System.out.println("ExifInterface.ORIENTATION_ROTATE_270 : "+ExifInterface.ORIENTATION_ROTATE_270);

                    if (orientation == ExifInterface.ORIENTATION_ROTATE_90) rotationAngle = 90;
                    if (orientation == ExifInterface.ORIENTATION_ROTATE_180) rotationAngle = 180;
                    if (orientation == ExifInterface.ORIENTATION_ROTATE_270) rotationAngle = 270;
                    System.out.println("Rotation Angle is : "+rotationAngle);
                    Matrix matrix = new Matrix();
                   // matrix.setRotate(rotationAngle, (float) photo.getWidth() / 2, (float) photo.getHeight() / 2);
                    matrix.postRotate(rotationAngle);

                    Bitmap rotatedBitmap=null;
                    try {
                        rotatedBitmap = Bitmap.createBitmap(photo, 0, 0, photo.getWidth(), photo.getHeight(), matrix, true);
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
Software Sainath
  • 1,040
  • 2
  • 14
  • 39
0

It's easy to detect the image orientation and replace the bitmap using:

 /**
 * Rotate an image if required.
 * @param img
 * @param selectedImage
 * @return 
 */
private static Bitmap rotateImageIfRequired(Context context,Bitmap img, Uri selectedImage) {

    // Detect rotation
    int rotation=getRotation(context, selectedImage);
    if(rotation!=0){
        Matrix matrix = new Matrix();
        matrix.postRotate(rotation);
        Bitmap rotatedImg = Bitmap.createBitmap(img, 0, 0, img.getWidth(), img.getHeight(), matrix, true);
        img.recycle();
        return rotatedImg;        
    }else{
        return img;
    }
}

/**
 * Get the rotation of the last image added.
 * @param context
 * @param selectedImage
 * @return
 */
private static int getRotation(Context context,Uri selectedImage) {
    int rotation =0;
    ContentResolver content = context.getContentResolver();


    Cursor mediaCursor = content.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
            new String[] { "orientation", "date_added" },null, null,"date_added desc");

    if (mediaCursor != null && mediaCursor.getCount() !=0 ) {
        while(mediaCursor.moveToNext()){
            rotation = mediaCursor.getInt(0);
            break;
        }
    }
    mediaCursor.close();
    return rotation;
}

To avoid Out of memories with big images, I'd recommend you to rescale the image using:

private static final int MAX_HEIGHT = 1024;
private static final int MAX_WIDTH = 1024;
public static Bitmap decodeSampledBitmap(Context context, Uri selectedImage)
        throws IOException {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    InputStream imageStream = context.getContentResolver().openInputStream(selectedImage);
    BitmapFactory.decodeStream(imageStream, null, options);
    imageStream.close();

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, MAX_WIDTH, MAX_HEIGHT);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    imageStream = context.getContentResolver().openInputStream(selectedImage);
    Bitmap img = BitmapFactory.decodeStream(imageStream, null, options);

    img= rotateImageIfRequired(img, selectedImage);
    return img;
} 

It's not posible to use ExifInterface to get the orientation because an Android OS issue: https://code.google.com/p/android/issues/detail?id=19268

Felix
  • 2,705
  • 1
  • 23
  • 14