Oct 21, 2011

Set latitude and longitude in Exif, setAttribute() and saveAttributes().

To modify Exit tag, you can call the method setAttribute(), and call saveAttributes() to save the tags in Exif.

Note 1: You have to grant permission of "android.permission.WRITE_EXTERNAL_STORAGE", otherwise the tags cannot be saved - But no error return to inform you!

Note 2: In this example, the Android build-in Gallery App doesn't recognize the updated Exif GPS location. In order to force MediaStore re-scan the updated file, read here.

Set latitude and longitude in Exif, setAttribute() and saveAttributes().

Modify main.xml to add a button to update Tags.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:orientation="vertical"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   >
<TextView 
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:text="@string/hello"
   />
<ScrollView
   android:orientation="vertical"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
>
<LinearLayout
   android:orientation="vertical"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   >
<TextView 
   android:id="@+id/exif"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   />
<ImageView 
   android:id="@+id/image"
   android:layout_width="300dp"
   android:layout_height="300dp"
   />
<Button 
   android:id="@+id/update"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:text="Update with dummy location"
   />
</LinearLayout>
</ScrollView>
</LinearLayout>


Implement UpdateExit() to update Exif Tags, with dummy LATITUDE and LONGITUDE.
package com.AndroidExif;

import java.io.IOException;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.ExifInterface;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class AndroidExifActivity extends Activity {

String imagefile ="/sdcard/DCIM/DSC_9599.jpg";
ImageView image;
TextView Exif;
Button updateDummyLoc;

ExifInterface exifInterface;

   /** Called when the activity is first created. */
   @Override
   public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.main);
       image = (ImageView)findViewById(R.id.image);
       Exif = (TextView)findViewById(R.id.exif);
      
       Bitmap bm = BitmapFactory.decodeFile(imagefile);
       image.setImageBitmap(bm);
      
       Exif.setText(ReadExif(imagefile));
      
       updateDummyLoc = (Button)findViewById(R.id.update);
       updateDummyLoc.setOnClickListener(new Button.OnClickListener(){

  @Override
  public void onClick(View arg0) {
   // TODO Auto-generated method stub
   UpdateExit();
  }});
   }
  
   void UpdateExit(){
    String dummyLATITUDE = "0/1,16/1,5935883/125557";
    String dummyLATITUDE_REF = "N";
    String dummyLONGITUDE = "0/1,7/1,1429891026/483594097";
    String dummyLONGITUDE_REF = "E";
   
    exifInterface.setAttribute(ExifInterface.TAG_GPS_LATITUDE, dummyLATITUDE);
 exifInterface.setAttribute(ExifInterface.TAG_GPS_LATITUDE_REF, dummyLATITUDE_REF);
 exifInterface.setAttribute(ExifInterface.TAG_GPS_LONGITUDE, dummyLONGITUDE);
 exifInterface.setAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF, dummyLONGITUDE_REF);

 try {
  exifInterface.saveAttributes();
  Toast.makeText(AndroidExifActivity.this,
    "saveAttribute finished",
    Toast.LENGTH_LONG).show();
 } catch (IOException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
  Toast.makeText(AndroidExifActivity.this,
    e.toString(),
    Toast.LENGTH_LONG).show();
 }
   }
  
   String ReadExif(String file){
    String exif="Exif: " + file;
    try {
  exifInterface = new ExifInterface(file);

  exif += "\nIMAGE_LENGTH: " + exifInterface.getAttribute(ExifInterface.TAG_IMAGE_LENGTH);
  exif += "\nIMAGE_WIDTH: " + exifInterface.getAttribute(ExifInterface.TAG_IMAGE_WIDTH);
  exif += "\n DATETIME: " + exifInterface.getAttribute(ExifInterface.TAG_DATETIME);
  exif += "\n TAG_MAKE: " + exifInterface.getAttribute(ExifInterface.TAG_MAKE);
  exif += "\n TAG_MODEL: " + exifInterface.getAttribute(ExifInterface.TAG_MODEL);
  exif += "\n TAG_ORIENTATION: " + exifInterface.getAttribute(ExifInterface.TAG_ORIENTATION);
  exif += "\n TAG_WHITE_BALANCE: " + exifInterface.getAttribute(ExifInterface.TAG_WHITE_BALANCE);
  exif += "\n TAG_FOCAL_LENGTH: " + exifInterface.getAttribute(ExifInterface.TAG_FOCAL_LENGTH);
  exif += "\n TAG_FLASH: " + exifInterface.getAttribute(ExifInterface.TAG_FLASH);
  exif += "\nGPS related:";

  float[] LatLong = new float[2];
  if(exifInterface.getLatLong(LatLong)){
   exif += "\n latitude= " + LatLong[0];
   exif += "\n longitude= " + LatLong[1];
  }else{
   exif += "Exif tags are not available!";
  }
 
  Toast.makeText(AndroidExifActivity.this,
    "finished",
    Toast.LENGTH_LONG).show();
 
 } catch (IOException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
  Toast.makeText(AndroidExifActivity.this,
    e.toString(),
    Toast.LENGTH_LONG).show();
 }
   
    return exif;
   }

}

6 comments:

  1. Hi, I was just wondering how you convert:

    double fLat = location.getLatitude();
    double fLng = location.getLongitude();

    to the sample / dummy coordinate format you mentioned:

    String dummyLATITUDE = "0/1,16/1,5935883/125557";
    String dummyLATITUDE_REF = "N";
    String dummyLONGITUDE = "0/1,7/1,1429891026/483594097";
    String dummyLONGITUDE_REF = "E";

    ReplyDelete
  2. i have the same question Above , how to convert from latitude to your dummy

    ReplyDelete
  3. Wikipedia has a great article on it-even has the code!
    http://en.wikipedia.org/wiki/Geographic_coordinate_conversion#Conversion_from_Decimal_Degree_to_DMS

    ReplyDelete
  4. Actually code is working.
    You need to check it in another device by sending via bluetooth. Our device maintains lat and long of image in its own database where as TAG_GPS_LATITUDE is saved with image. And gallery displays lat and long from database.

    So check from other device...

    by the way nice post..keep it up.... :)

    ReplyDelete
    Replies
    1. Hello chirag patel,

      Thanks.

      Yes, it's found that if the device reboot, it can recognize it.

      I think if I can force Gallery to re-scan the photo, it can be recognized. but I don't know how!

      Delete
  5. this is not working in emulator, set values are being retrieved when we do a get*(), but the image details doesn't reflect the new set values

    ReplyDelete

Infolinks In Text Ads