0

I have an application where I am trying to save an image with gps coordinates in it (EXIF). When I share the image via gallery to my application the image is sent as expected but the gps coordinates are returning null, as if they don't exist.

Save image in my app

Here is the code for saving:

...
// put gps location into image
ExifInterface exif = new ExifInterface(pictureFile.getCanonicalPath());
List<Double> latLon = getCurrentLatLon(); // this returns lat and lon doubles values
Log.d(null, "getPictureCallback lat " + latLon.get(0) + "  lon " + latLon.get(1));

GPS gps = new GPS(); // class used to convert gps coordinates
exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE, gps.convert(latLon.get(0)));
exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE_REF, gps.convert(latLon.get(0)));
exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE, gps.convert(latLon.get(1)));
exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF, gps.convert(latLon.get(1)));
exif.saveAttributes();

Log.i("getPictureCallback LATITUDE EXTRACTED", exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE));
Log.i("getPictureCallback LONGITUDE EXTRACTED", exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE));

// write to the file
FileOutputStream fos = new FileOutputStream(pictureFile);
// save the bitmap to a file compressed as a JPEG with 100% compression rate
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();

The logcat for the above code:

05-10 14:55:12.161   8560-12142/com.example.fela E/JHEAD﹕ can't open '/storage/sdcard/Pictures/fela/IMG_20150510_145512.jpg'
05-10 14:55:12.161   8560-12142/com.example.fela D/﹕ getPictureCallback lat 13.003821666666665  lon 55.60497999999999
05-10 14:55:12.161   8560-12142/com.example.fela E/JHEAD﹕ can't open '/storage/sdcard/Pictures/fela/IMG_20150510_145512.jpg'
05-10 14:55:12.161   8560-12142/com.example.fela E/JHEAD﹕ Can't write back - didn't read all
05-10 14:55:12.161   8560-12142/com.example.fela I/getPictureCallback LATITUDE EXTRACTED﹕ 13/1,0/1,13757/1000,
05-10 14:55:12.161   8560-12142/com.example.fela I/getPictureCallback LONGITUDE EXTRACTED﹕ 55/1,36/1,17927/1000,

As you can see, the coordinates are written:

getPictureCallback LATITUDE EXTRACTED﹕ 13/1,0/1,13757/1000
getPictureCallback LONGITUDE EXTRACTED﹕ 55/1,36/1,17927/1000

I presumed that they are now saved in the image file itself.

Share to my app via gallery

Down below is when I share the image saved to my application.

Intent intent = getActivity().getIntent();
String action = intent.getAction();
String type = intent.getType();

Uri imageUri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
Log.v(null, imageUri.getPath());
try {
    ExifInterface exif = new ExifInterface(imageUri.getPath());
    String lat = exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE);
    String lon = exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE);
    Log.v(null, "lat " + lat + " lon " + lon);
} catch (IOException e) {
    e.printStackTrace();
}

LogCat:

05-10 14:47:25.274    8560-8560/com.example.fela V/﹕ /external/images/media/44
05-10 14:47:25.274    8560-8560/com.example.fela E/JHEAD﹕ can't open '/external/images/media/44'
05-10 14:47:25.274    8560-8560/com.example.fela V/﹕ lat null lon null

The intent does give way to an image which is displayed in my application, so the image file is there.

However as you can the image cannot extract the gps coordinates, they are null. I don't know why they are null as I checked them when saving.

basickarl
  • 37,187
  • 64
  • 214
  • 335

2 Answers2

2

https://stackoverflow.com/a/21501807/1137669

It was an issue all along with how I read the uri path of the intent image. The correct is answered in the link above.

String imagePath = getRealPathFromURI(imageUri);
ExifInterface exif = new ExifInterface(imagePath);
String lat = exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE);
String lon = exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE);

And the method that got it to work:

private String getRealPathFromURI(Uri contentUri) {
    String[] proj = { MediaStore.Images.Media.DATA };
    CursorLoader loader = new CursorLoader(getActivity(), contentUri, proj, null, null, null);
    Cursor cursor = loader.loadInBackground();
    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
    cursor.moveToFirst();
    return cursor.getString(column_index);
}

Also as Gabe Sechan mentioned, it MUST be after bitmap.compress otherwise it will be overwritten.

Community
  • 1
  • 1
basickarl
  • 37,187
  • 64
  • 214
  • 335
1

When you write to the FileStream in Bitmap.compress, you overwrite the file. This overwrites the tags. Reverse the order of those operations.

Gabe Sechan
  • 90,003
  • 9
  • 87
  • 127