25

I am trying to check the orientation of bitmap and flip it if there is a need, but I have error while applying the code. Here is my code while i am trying to flipp the image using ExifInterface:

@RequiresApi(api = Build.VERSION_CODES.N)
    public void flipping(Bitmap b)
    {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        b.compress(Bitmap.CompressFormat.JPEG,100, bos);
        byte[] bitmapdata = bos.toByteArray();
        ByteArrayInputStream bs = new ByteArrayInputStream(bitmapdata);
        try {

            ExifInterface exif = new ExifInterface(bs);
            int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_UNDEFINED);
            switch(orientation) {

                case ExifInterface.ORIENTATION_ROTATE_90:
                    rotateImage(b, 90);
                    break;

                case ExifInterface.ORIENTATION_ROTATE_180:
                    rotateImage(b, 180);
                    break;

                case ExifInterface.ORIENTATION_ROTATE_270:
                    rotateImage(b, 270);
                    break;

                case ExifInterface.ORIENTATION_NORMAL:

                default:
                    break;
            }

            encoding();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static Bitmap rotateImage(Bitmap source, float angle) {
        Matrix matrix = new Matrix();
        matrix.postRotate(angle);
        return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(),
                matrix, true);
    }

And here is the error:

java.lang.NoSuchMethodError: No direct method <init>(Ljava/io/InputStream;)V in class Landroid/media/ExifInterface; or its super classes (declaration of 'android.media.ExifInterface' appears in /system/framework/framework.jar)
                                                                       at com.sara.image_test.MainActivity.flipping(MainActivity.java:181)
                                                                       at com.sara.image_test.MainActivity.onActivityResult(MainActivity.java:66)
                                                                       at android.app.Activity.dispatchActivityResult(Activity.java:7165)
                                                                       at android.app.ActivityThread.deliverResults(ActivityThread.java:4994)
                                                                       at android.app.ActivityThread.handleSendResult(ActivityThread.java:5041)
                                                                       at android.app.ActivityThread.access$1600(ActivityThread.java:229)
                                                                       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1875)
                                                                       at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                       at android.os.Looper.loop(Looper.java:148)
                                                                       at android.app.ActivityThread.main(ActivityThread.java:7325)
                                                                       at java.lang.reflect.Method.invoke(Native Method)
                                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
                                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Saleh Refaai
  • 689
  • 3
  • 14
  • 25

4 Answers4

54

for AndroidX use

androidx.exifinterface.media.ExifInterface

Import this dependency in build.gradle:

implementation 'androidx.exifinterface:exifinterface:1.3.2'
Zeus Almighty
  • 155
  • 1
  • 10
Francis
  • 6,788
  • 5
  • 47
  • 64
26

You are attempting to use android.media.ExifInterface. On Android 7.0+ (API Level 24), that class is safe to use and has a constructor that takes an InputStream. Apparently, you are running your app on an older device. That results in two problems:

  1. The older device will not have that constructor

  2. ExifInterface has security flaws on older devices, opening your app up to malware attacks

Use android.support.media.ExifInterface instead. It is from the support libraries (com.android.support:exifinterface, specifically). It offers a constructor taking an InputStream that works on all supported versions of Android. And, it bypasses the security bug on older devices.

Ben Butterworth
  • 22,056
  • 10
  • 114
  • 167
CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • thanks, it is not giving errors anymore. But it returns 0 always on all images. – Saleh Refaai May 29 '17 at 16:32
  • @SalehRefaai: That is not surprising, since a `Bitmap` does not have any EXIF headers. You already threw away any EXIF data when you loaded the `Bitmap` from wherever it came from. Use `ExifInterface` on the original source of the data, not the `Bitmap`. – CommonsWare May 29 '17 at 16:38
14

Add this to your build.gradle file

compile "com.android.support:exifinterface:25.1.0"

for me it worked.

Fincha
  • 151
  • 5
1

The ExifInterface constructor being used in your code sample:

ByteArrayInputStream bs = new ByteArrayInputStream(bitmapdata);

was added in SDK level 24.

But it looks like the code is being run on a device with an earlier version of Android than 24.

See https://developer.android.com/reference/android/media/ExifInterface.html#ExifInterface(java.io.InputStream)

albert c braun
  • 2,650
  • 1
  • 22
  • 32