Orientation issues

On some devices (such as the Samsung ones), captured images in portrait mode are rotated 90 degrees; and on other devices (such as the Nexus devices), things seem to be just fine. You won't notice this if you have a look at the file using the Astro app, for example, but you will if you see the preview in the Facebook share dialog.

This is a well-known challenge for many Android developers. Images may contain metadata about the rotation degree, but apparently not every app respects that metadata. What is the best solution? Should you rotate the image every time you want to display it? Should you rotate the bitmap itself, which could be very time and processor consuming?

Getting ready

For this recipe, you need to have the previous recipe completed successfully. It would be ideal if you had multiple Android devices to test your app on. Otherwise, it would be great if you had at least a Samsung device available, as the orientation issue can be reproduced for most (if not all) models from this brand.

How to do it...

Let's take a look at how you can fix this orientation issue if it appears:

  1. In the Facebook share dialog, the preview image is rotated 90 degrees (on some devices), as shown here:
    How to do it...
  2. This does not look like the world I live in. It appears this way on my Samsung Galaxy Note 3 device, but not on my Nexus 5 device. Apparently, Samsung stores the picture as it is from a landscape point of view, and then adds metadata to it to indicate that the image has been rotated (compared to the default orientation). Things, however, will go wrong if you want to share it on Facebook, for example, as the orientation information in the metadata is not being respected.
  3. So, we need to examine the meta data and find out if there is any rotation information in there. Add the getRotationFromMetaData method:
    private int getRotationFromMetaData(){
       try {
          ExifInterface exif = new 
          ExifInterface(mFile.getAbsolutePath());
          int orientation = exif.getAttributeInt(
           ExifInterface.TAG_ORIENTATION,
            ExifInterface.ORIENTATION_NORMAL);
          switch (orientation) {
    		  case ExifInterface.ORIENTATION_ROTATE_270:
                    return 270;
              case ExifInterface.ORIENTATION_ROTATE_180:
                    return 180;case ExifInterface.ORIENTATION_ROTATE_90:
                    return 90;
              default:
                    return 0;
          }
       }
       catch (IOException ex){
           return 0;
       }
    }
  4. If needed, you have to rotate the bitmap before showing the sharing preview. That is where the rotateCaptureImageIfNeeded method comes in.

    Here, we can safely rotate the bitmap in memory, because of the inSampleSet value of 4. If you rotate the original full-size bitmap, chances are that you will run out of memory. Either way, it is going to be time consuming and will result in a delay between capturing an image and displaying the sharing preview dialog:

    private Bitmap rotateCapturedImageIfNeeded(Bitmap bitmap){
        int rotate = getRotationFromMetaData();
        Matrix matrix = new Matrix();
        matrix.postRotate(rotate);
        bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
         bitmap.getHeight(), matrix, true);
        Bitmap mutableBitmap = bitmap.copy(Bitmap.Config.ARGB_8888,  
         true);
       return mutableBitmap;
    }
  5. Then, in the sharePictureOnFacebook method, right after you have retrieved the bitmap using the BitmapFactory class , call the onRotateCaptureImageIfNeeded method and pass the bitmap as a parameter:
    bitmap = rotateCapturedImageIfNeeded(bitmap);
    
  6. If you run the app again, you will see that everything is fine in portrait mode too:
    How to do it...

These things are easy to implement and will improve the quality of your app, although they can also drive you nuts sometimes and make you wonder why one solution cannot just work on any device. Everything looks fine now, but what will it look like on a tablet or on a Huawei, LG, or HTC device? There's nothing that cannot be fixed, but since you do not have a drawerful of Android devices (or maybe you do), testing is hard.

It always is a good thing to test your app on as many devices as possible. Consider using a service for remote testing, for example, TestDroid. You can find their website at www.testdroid.com. In Chapter 8, Improving quality, this and other topics will be discussed, but first will we have a look at observables and content providers in the upcoming chapter.

There's more...

Capturing video is even more fun to do. There is also a Camera2 API sample for video capturing available. You can examine the sample project through the Import sample option as well.

See also

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset