Android: Reading and Writing Geotagging Information GPS Latitude Longitude on File Photos

Android: Reading and Writing Geotagging Information GPS Latitude Longitude on File PhotosPhotos taken using a camera that supports geotagging contain GPS information such as latitude and longitude. Android is able to read information from a file that has the photo geotagging information and is able to also write or update geotagging information into the photo files.

Create a project in Eclipse or the Android android Studio. Add the following code to MainActivity.java:

package com.example.image_geotagging_get_latitude_longitude_gps;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.app.Activity;
import android.location.Location;
import android.media.ExifInterface;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity {
	Button button1;
	Button button2;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		button1 = (Button)findViewById(R.id.button1);
		button1.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				Location loc = readGeoTagImage("//sdcard/test-geotagging.jpg");
				Toast.makeText(getApplicationContext(), "OK " + String.valueOf(loc.getLatitude()) + " " + String.valueOf(loc.getLongitude()), Toast.LENGTH_LONG).show();
			}
		});
		
		button2 = (Button)findViewById(R.id.button2);
		button2.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				Location loc = new Location("");
				loc.setLatitude(-7);
				loc.setLongitude(110);
				MarkGeoTagImage("//sdcard/test-geotagging.jpg", loc);
				Toast.makeText(getApplicationContext(), "OK ", Toast.LENGTH_LONG).show();
			}
		});
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.activity_main, menu);
		return true;
	}
	
	public Location readGeoTagImage(String imagePath)
	{
		Location loc = new Location("");
		try {
			ExifInterface exif = new ExifInterface(imagePath);
			float [] latlong = new float[2] ;
			if(exif.getLatLong(latlong)){
			loc.setLatitude(latlong[0]);
			loc.setLongitude(latlong[1]);
			}
			String date = exif.getAttribute(ExifInterface.TAG_DATETIME);
			SimpleDateFormat fmt_Exif = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");
			loc.setTime(fmt_Exif.parse(date).getTime());
	
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return loc;
	}
	
	public void MarkGeoTagImage(String imagePath,Location location)
	{
		try {
			ExifInterface exif = new ExifInterface(imagePath);
			exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE, GPS.convert(location.getLatitude()));
			exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE_REF, GPS.latitudeRef(location.getLatitude()));
			exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE, GPS.convert(location.getLongitude()));
			exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF, GPS.longitudeRef(location.getLongitude()));
			SimpleDateFormat fmt_Exif = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");
			exif.setAttribute(ExifInterface.TAG_DATETIME,fmt_Exif.format(new Date(location.getTime())));
			exif.saveAttributes();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}

Create a class named GPS.java :

package com.example.image_geotagging_get_latitude_longitude_gps;

class GPS {
	private static StringBuilder sb = new StringBuilder(20);
	/**
	* returns ref for latitude which is S or N.
	*
	* @param latitude
	* @return S or N
	*/
	public static String latitudeRef(final double latitude) {
		return latitude < 0.0d ? "S" : "N";
	}
	
	/**
	* returns ref for latitude which is S or N.
	*
	* @param latitude
	* @return S or N
	*/
	public static String longitudeRef(final double longitude) {
		return longitude < 0.0d ? "W" : "E";
	}
	/**
	* convert latitude into DMS (degree minute second) format. For instance<br/>
	* -79.948862 becomes<br/>
	* 79/1,56/1,55903/1000<br/>
	* It works for latitude and longitude<br/>
	*
	* @param latitude could be longitude.
	* @return
	*/
	public static final String convert(double latitude) {
		latitude = Math.abs(latitude);
		final int degree = (int)latitude;
		latitude *= 60;
		latitude -= degree * 60.0d;
		final int minute = (int)latitude;
		latitude *= 60;
		latitude -= minute * 60.0d;
		final int second = (int)(latitude * 1000.0d);
		sb.setLength(0);
		sb.append(degree);
		sb.append("/1,");
		sb.append(minute);
		sb.append("/1,");
		sb.append(second);
		sb.append("/1000,");
		return sb.toString();
	}
}

Add xml code to create the interface in activity_main.xml like this:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:id="@+id/LinearLayout1"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical"
 tools:context=".MainActivity" >

 <Button
 android:id="@+id/button1"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="Get Geotagging Latitude Longitude" />

 <Button
 android:id="@+id/button2"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="Set Geotagging Latitude Longitude" />
 
</LinearLayout>

Do not forget to add the following permissions on the file Android manifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 package="com.example.image_geotagging_get_latitude_longitude_gps"
 android:versionCode="1"
 android:versionName="1.0" >

 <uses-sdk
 android:minSdkVersion="8"
 android:targetSdkVersion="16" />
 <uses-permission android:name="android.permission.INTERNET"/>
 <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
 <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

 <application
 android:allowBackup="true"
 android:icon="@drawable/ic_launcher"
 android:label="@string/app_name"
 android:theme="@style/AppTheme" >
 <activity
 android:name="com.example.image_geotagging_get_latitude_longitude_gps.MainActivity"
 android:label="@string/app_name" >
 <intent-filter>
 <action android:name="android.intent.action.MAIN" />

 <category android:name="android.intent.category.LAUNCHER" />
 </intent-filter>
 </activity>
 </application>

</manifest>

Run this project, then we will get results like this:

 Android: Reading and Writing Geotagging Information GPS Latitude Longitude on File Photos

Download full source code of this project here.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>