Problem: I'm using an intent to allow the user to select photos. When they select the photos from images on the device, I am able to get the latitude and longitude using an ExifInterface. However when they choose photos from Google Photos I'm not able to get the geolocation from the uri returned.
Details: The intent I'm using looks like this:
Intent intent = new Intent();
// Show only images, no videos or anything else
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
// Always show the chooser (if there are multiple options available)
startActivityForResult(Intent.createChooser(intent, "Select Pictures"), PICK_IMAGES_REQUEST);
When the user selects a photo from Google Photos that is not stored on the device, Google Photos first downloads the photo and returns a URI which does not include a location on the device. I'm using this to write the stream to a local file to get the photo. I then try to use a ContentResolver to get date taken, latitude and longitude from the stream like so:
Cursor cursor = context.getContentResolver().query(uri,
new String[] {
MediaStore.Images.ImageColumns.DATE_TAKEN,
MediaStore.Images.ImageColumns.LATITUDE,
MediaStore.Images.ImageColumns.LONGITUDE
}, null, null, null);
if (null != cursor) {
if (cursor.moveToFirst()) {
int dateColumn = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATE_TAKEN);
photoItem.date = new Date(cursor.getLong(dateColumn));
int latitudeColumn = cursor.getColumnIndex(MediaStore.Images.ImageColumns.LATITUDE);
double latitude = cursor.getDouble(latitudeColumn);
int longitudeColumn = cursor.getColumnIndex(MediaStore.Images.ImageColumns.LONGITUDE);
double longitude = cursor.getDouble(longitudeColumn);
photoItem.photoGeoPoint = new LatLng(latitude, longitude);
}
cursor.close();
}
This works for date taken. However latitude and longitude are always 0. I have verified that the photos I am trying this with have geo locations embedded in the exif. Any ideas?
--EDIT--
So using @CommonsWare's advice I updated my code to write directly from the stream to a file without converting it to a bitmap first. The code looks like this (where in is the InputStream from the Google Photos contentResolver):
try {
File outputDir = AppState.getInstance().getCacheDir();
File outputFile = File.createTempFile("tempImageFile", ".jpg", outputDir);
OutputStream out = new FileOutputStream(outputFile);
byte[] buf = new byte[1024];
int len;
while((len=in.read(buf))>0){
out.write(buf,0,len);
}
out.close();
in.close();
ExifInterface exif = new ExifInterface(outputFile.getPath());
Logger.d(LOG_TAG, "lat is: " + exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE));
Logger.d(LOG_TAG, "lon is: " + exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE));
} catch (Exception e) {
e.printStackTrace();
}
However Latitude and Longitude are still null (again, I've verified that in the photo the location data exists). The only values in the ExifInterface are LightSource = 0, Orientation = 1, ImageLength = 3264, MeteringMode = -1 and ImageWidth = 2448.