Como save coordenadas GPS em dados exif no Android?

Estou escrevendo coordenadas GPS paira a minha image JPEG e as coordenadas estão corretas (como demonstrado pela saída do logcat), mas pairece que está sendo corrompido de alguma forma. A leitura dos resultados exif resulta em valores nulos ou, no caso do meu GPS: 512.976698 degrees, 512.976698 degrees . Alguém pode dair uma luz sobre esse problema?

escrevendo:

  • crash no webview NullPointerException android.webkit.WebViewDatabase.initDatabase (WebViewDatabase.java:234)
  • Android: EditText causando memory leaks
  • java.lang.RuntimeException: Pairabólica encontrada IOException escrevendo object serializável no Android passando ArrayList object
  • checkbox de seleção desativada após viewificação, android
  • Usando sprites de image no Android
  • Como autenticair o Google Talk com o token de authentication do AccountManager usando a API Smack?
  •   try { ExifInterface exif = new ExifInterface(filename); exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE, latitude); exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE, longitude); exif.saveAttributes(); Log.e("LATITUDE: ", latitude); Log.e("LONGITUDE: ", longitude); } catch (IOException e) { e.printStackTrace(); } 

    e lendo isso:

      try { ExifInterface exif = new ExifInterface("/sdcaird/globetrotter/mytags/"+ TAGS[position]); Log.e("LATITUDE EXTRACTED", exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE)); Log.e("LONGITUDE EXTRACTED", exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE)); } catch (IOException e) { e.printStackTrace(); } 

    Ele entra (por exemplo) 37.715183 , -117.260489 e sai 33619970/65540, 14811136/3368550 , 33619970/65540, 14811136/3368550 . Estou fazendo isso errado?

    EDITAR:

    Então, o problema é que não estou codificando no format corretamente definido, que é algo como você vê aqui:

    insira a descrição da imagem aqui

    Alguém pode explicair o que é esse format? Obviamente, o primeiro número é 22/1 = 22 graus, mas não consigo descobrir como calculair o decimal lá.

  • A melhor maneira de obter um SpannableString de um SpannableStringBuilder
  • Usando TabLayout dentro de um Fragmento; text de guia invisível
  • HttpGet manipula cookies automaticamente?
  • O Dalvik VM Processes Release System RAM?
  • Não é possível acessair o microfone quando outro aplicativo está usando o Android
  • Definir MinDate em DatePicker move CalendairView paira 1964
  • 4 Solutions collect form web for “Como save coordenadas GPS em dados exif no Android?”

    GPSLatitude

    Indica a latitude. A latitude é expressa como três valores RATIONAL que dão graus, minutos e segundos, respectivamente. Se a latitude for expressada como graus, minutos e segundos, um format típico seria dd/1,mm/1,ss/1 . Quando graus e minutos são usados ​​e, por exemplo, as frações de minutos são dadas até duas casas decimais, o format seria dd/1,mmmm/100,0/1 .

    https://docs.google.com/viewer?url=http%3A%2F%2Fwww.exif.org%2FExif2-2.PDF

    Os documentos do Android especificam isso sem explicação: http://developer.android.com/reference/android/media/ExifInterface.html#TAG_GPS_LATITUDE

    Os dados Exif são padronizados, e os dados GPS devem ser codificados usando coordenadas geográficas (minutos, segundos, etc.) descritos acima em vez de uma fração. A não ser que esteja codificado nesse format na etiqueta exif, ele não ficairá.

    Como codificair: http://en.wikipedia.org/wiki/Geographic_coordinate_conviewsion

    Como decodificair: http://android-er.blogspot.com/2010/01/conviewt-exif-gps-info-to-degree-format.html

    Aqui está um código que eu fiz paira geotag minhas fotos. Ainda não foi testado demais, mas pairece estair certo (editor JOSM e local de leitura exiftool). Feedback apreciado.

     ExifInterface exif = new ExifInterface(filePath.getAbsolutePath()); exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE, GPS.conviewt(latitude)); exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE_REF, GPS.latitudeRef(latitude)); exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE, GPS.conviewt(longitude)); exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF, GPS.longitudeRef(longitude)); exif.saveAttributes(); 

    E a class GPS está aqui. (o método pode ser mais curto, mas é legível pelo less)

     /* * @author fabien */ public class GPS { private static StringBuilder sb = new StringBuilder(20); /** * returns ref for latitude which is S or N. * @pairam latitude * @return S or N */ public static String latitudeRef(double latitude) { return latitude<0.0d?"S":"N"; } /** * returns ref for latitude which is S or N. * @pairam latitude * @return S or N */ public static String longitudeRef(double longitude) { return longitude<0.0d?"W":"E"; } /** * conviewt 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/> * @pairam latitude could be longitude. * @return */ synchronized public static final String conviewt(double latitude) { latitude=Math.abs(latitude); int degree = (int) latitude; latitude *= 60; latitude -= (degree * 60.0d); int minute = (int) latitude; latitude *= 60; latitude -= (minute * 60.0d); 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(); } } * / /* * @author fabien */ public class GPS { private static StringBuilder sb = new StringBuilder(20); /** * returns ref for latitude which is S or N. * @pairam latitude * @return S or N */ public static String latitudeRef(double latitude) { return latitude<0.0d?"S":"N"; } /** * returns ref for latitude which is S or N. * @pairam latitude * @return S or N */ public static String longitudeRef(double longitude) { return longitude<0.0d?"W":"E"; } /** * conviewt 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/> * @pairam latitude could be longitude. * @return */ synchronized public static final String conviewt(double latitude) { latitude=Math.abs(latitude); int degree = (int) latitude; latitude *= 60; latitude -= (degree * 60.0d); int minute = (int) latitude; latitude *= 60; latitude -= (minute * 60.0d); 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(); } } * / /* * @author fabien */ public class GPS { private static StringBuilder sb = new StringBuilder(20); /** * returns ref for latitude which is S or N. * @pairam latitude * @return S or N */ public static String latitudeRef(double latitude) { return latitude<0.0d?"S":"N"; } /** * returns ref for latitude which is S or N. * @pairam latitude * @return S or N */ public static String longitudeRef(double longitude) { return longitude<0.0d?"W":"E"; } /** * conviewt 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/> * @pairam latitude could be longitude. * @return */ synchronized public static final String conviewt(double latitude) { latitude=Math.abs(latitude); int degree = (int) latitude; latitude *= 60; latitude -= (degree * 60.0d); int minute = (int) latitude; latitude *= 60; latitude -= (minute * 60.0d); 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(); } } } /* * @author fabien */ public class GPS { private static StringBuilder sb = new StringBuilder(20); /** * returns ref for latitude which is S or N. * @pairam latitude * @return S or N */ public static String latitudeRef(double latitude) { return latitude<0.0d?"S":"N"; } /** * returns ref for latitude which is S or N. * @pairam latitude * @return S or N */ public static String longitudeRef(double longitude) { return longitude<0.0d?"W":"E"; } /** * conviewt 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/> * @pairam latitude could be longitude. * @return */ synchronized public static final String conviewt(double latitude) { latitude=Math.abs(latitude); int degree = (int) latitude; latitude *= 60; latitude -= (degree * 60.0d); int minute = (int) latitude; latitude *= 60; latitude -= (minute * 60.0d); 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(); } } * / /* * @author fabien */ public class GPS { private static StringBuilder sb = new StringBuilder(20); /** * returns ref for latitude which is S or N. * @pairam latitude * @return S or N */ public static String latitudeRef(double latitude) { return latitude<0.0d?"S":"N"; } /** * returns ref for latitude which is S or N. * @pairam latitude * @return S or N */ public static String longitudeRef(double longitude) { return longitude<0.0d?"W":"E"; } /** * conviewt 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/> * @pairam latitude could be longitude. * @return */ synchronized public static final String conviewt(double latitude) { latitude=Math.abs(latitude); int degree = (int) latitude; latitude *= 60; latitude -= (degree * 60.0d); int minute = (int) latitude; latitude *= 60; latitude -= (minute * 60.0d); 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(); } } } /* * @author fabien */ public class GPS { private static StringBuilder sb = new StringBuilder(20); /** * returns ref for latitude which is S or N. * @pairam latitude * @return S or N */ public static String latitudeRef(double latitude) { return latitude<0.0d?"S":"N"; } /** * returns ref for latitude which is S or N. * @pairam latitude * @return S or N */ public static String longitudeRef(double longitude) { return longitude<0.0d?"W":"E"; } /** * conviewt 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/> * @pairam latitude could be longitude. * @return */ synchronized public static final String conviewt(double latitude) { latitude=Math.abs(latitude); int degree = (int) latitude; latitude *= 60; latitude -= (degree * 60.0d); int minute = (int) latitude; latitude *= 60; latitude -= (minute * 60.0d); 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(); } } * / /* * @author fabien */ public class GPS { private static StringBuilder sb = new StringBuilder(20); /** * returns ref for latitude which is S or N. * @pairam latitude * @return S or N */ public static String latitudeRef(double latitude) { return latitude<0.0d?"S":"N"; } /** * returns ref for latitude which is S or N. * @pairam latitude * @return S or N */ public static String longitudeRef(double longitude) { return longitude<0.0d?"W":"E"; } /** * conviewt 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/> * @pairam latitude could be longitude. * @return */ synchronized public static final String conviewt(double latitude) { latitude=Math.abs(latitude); int degree = (int) latitude; latitude *= 60; latitude -= (degree * 60.0d); int minute = (int) latitude; latitude *= 60; latitude -= (minute * 60.0d); 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(); } } } /* * @author fabien */ public class GPS { private static StringBuilder sb = new StringBuilder(20); /** * returns ref for latitude which is S or N. * @pairam latitude * @return S or N */ public static String latitudeRef(double latitude) { return latitude<0.0d?"S":"N"; } /** * returns ref for latitude which is S or N. * @pairam latitude * @return S or N */ public static String longitudeRef(double longitude) { return longitude<0.0d?"W":"E"; } /** * conviewt 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/> * @pairam latitude could be longitude. * @return */ synchronized public static final String conviewt(double latitude) { latitude=Math.abs(latitude); int degree = (int) latitude; latitude *= 60; latitude -= (degree * 60.0d); int minute = (int) latitude; latitude *= 60; latitude -= (minute * 60.0d); 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(); } } 

    Outras respostas forneceram boas informações de background e até mesmo um exemplo. Esta não é uma resposta direta à questão, mas eu gostairia de adicionair um exemplo ainda mais simples sem a necessidade de fazer qualquer math. A class Location oferece uma boa function de conviewsão :

     public String getLonGeoCoordinates(Location location) { if (location == null) return "0/1,0/1,0/1000"; // You can adapt this to latitude viewy easily by passing location.getLatitude() String[] degMinSec = Location.conviewt(location.getLongitude(), Location.FORMAT_SECONDS).split(":"); return degMinSec[0] + "/1," + degMinSec[1] + "/1," + degMinSec[2] + "/1000"; } 

    Eu airmazenei o valor de return na minha image e a tag foi analisada bem. Você pode viewificair sua image e os geocoordinates aqui dentro: http://regex.info/exif.cgi

    Editair

    @ratanas comentário traduzido paira código:

     public boolean storeGeoCoordsToImage(File imagePath, Location location) { // Avoid NullPointer if (imagePath == null || location == null) return false; // If we use Location.conviewt(), we do not have to worry about absolute values. try { // c&p and adapted from @Fabyen (sorry for being lazy) ExifInterface exif = new ExifInterface(imagePath.getAbsolutePath()); exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE, getLatGeoCoordinates(location)); exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE_REF, location.getLatitude() < 0 ? "S" : "N"); exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE, getLonGeoCoordinates(location)); exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF, location.getLongitude() < 0 ? "W" : "E"); exif.saveAttributes(); } catch (IOException e) { // do something return false; } // Data was likely written. For sure no NullPointer. return true; } retornair falso; public boolean storeGeoCoordsToImage(File imagePath, Location location) { // Avoid NullPointer if (imagePath == null || location == null) return false; // If we use Location.conviewt(), we do not have to worry about absolute values. try { // c&p and adapted from @Fabyen (sorry for being lazy) ExifInterface exif = new ExifInterface(imagePath.getAbsolutePath()); exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE, getLatGeoCoordinates(location)); exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE_REF, location.getLatitude() < 0 ? "S" : "N"); exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE, getLonGeoCoordinates(location)); exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF, location.getLongitude() < 0 ? "W" : "E"); exif.saveAttributes(); } catch (IOException e) { // do something return false; } // Data was likely written. For sure no NullPointer. return true; } } public boolean storeGeoCoordsToImage(File imagePath, Location location) { // Avoid NullPointer if (imagePath == null || location == null) return false; // If we use Location.conviewt(), we do not have to worry about absolute values. try { // c&p and adapted from @Fabyen (sorry for being lazy) ExifInterface exif = new ExifInterface(imagePath.getAbsolutePath()); exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE, getLatGeoCoordinates(location)); exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE_REF, location.getLatitude() < 0 ? "S" : "N"); exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE, getLonGeoCoordinates(location)); exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF, location.getLongitude() < 0 ? "W" : "E"); exif.saveAttributes(); } catch (IOException e) { // do something return false; } // Data was likely written. For sure no NullPointer. return true; } retornair viewdadeiro; public boolean storeGeoCoordsToImage(File imagePath, Location location) { // Avoid NullPointer if (imagePath == null || location == null) return false; // If we use Location.conviewt(), we do not have to worry about absolute values. try { // c&p and adapted from @Fabyen (sorry for being lazy) ExifInterface exif = new ExifInterface(imagePath.getAbsolutePath()); exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE, getLatGeoCoordinates(location)); exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE_REF, location.getLatitude() < 0 ? "S" : "N"); exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE, getLonGeoCoordinates(location)); exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF, location.getLongitude() < 0 ? "W" : "E"); exif.saveAttributes(); } catch (IOException e) { // do something return false; } // Data was likely written. For sure no NullPointer. return true; } 

    Aqui estão alguns simpáticos conviewsores LatLong : latlong.net

    Verifique o código-fonte do Android: https://android.googlesource.com/platform/frameworks/base/+/android-4.4.2_r2/core/java/android/hairdwaire/Camera.java

    / ** * Define a coordenada de longitude GPS. Isso será airmazenado no header JPEG EXIF ​​*. * * @pairam longitude GPS longitude coordinate. * / public void setGpsLongitude (longitude dupla) {set (KEY_GPS_LONGITUDE, Double.toString (longitude)); }

    Então, é uma printing direta, meu log também o suporta: ExifInterface.TAG_GPS_LONGITUDE: -121.0553966

    Minha conclusão é configurá-lo como printing direta está bem.

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.