Hola vergasianos hoy veremos como obtener los metadatos de una imagen, es un tema muy importante. Déjenme contarles quien les escribe tiene un diplomado en seguridad informática y otro en seguridad de la información. Ya con los conocimientos que tengo les puedo contar que muchas personas se puede saber en parte de un país se encuentra, quizás a que horas suele caminar o visitar ligares y muchas cosas mas gracias a los metadatos inclusive saber que marca de celular tiene, sin necesidad de ser chaman o recurrir a los poderes de los antiguos ancestro del mal. Cuando nosotros nos tomamos una imagen esta imagen tiene metadatos como por ejemplo a que distancia fue tomada, en donde se tomo, que dispositivo y marca del dispositivo donde se tomo, la fecha que se tomo y etc de datos y no solo son las imágenes también los archivos que creamos en word, este es un tema muy extenso son táctica de recopilación de datos que usan algunos hacker o detectives informáticos para dar con alguien. Bueno sin mas rodeos empezamos.
Como obtener los metadatos de una imagen en android studio
Contenidos
Cosas que necesitamos saber sobre los Metadatos
Los Metadatos permiten a una persona ubicar y entender los datos, incluyen información requerida para determinar qué conjuntos de datos existen para una localización geográfica particular, la información necesaria para determinar si un conjunto de datos es apropiado para fines específicos.
Fuente: geoidep.gob.pe
MainActivity
import android.Manifest; import android.app.Activity; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Handler; import android.support.v4.app.ActivityCompat; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.ImageButton; import android.widget.Toast; public class MainActivity extends Activity { Button iniciar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.READ_EXTERNAL_STORAGE}, 1000); }else { } iniciar = (Button) findViewById(R.id.btnIniciar); iniciar.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent ListSong = new Intent(getApplicationContext(), EfixImagen.class); startActivity(ListSong); } }); } }
activity_main
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btnIniciar" android:background="@drawable/btn_play" android:layout_centerVertical="true" android:layout_centerHorizontal="true" /> <TextView android:text="CLIC PARA INICIAR" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_above="@+id/btnIniciar" android:layout_alignParentStart="true" android:layout_marginStart="65dp" android:layout_marginBottom="57dp" android:id="@+id/textView" android:textSize="28sp" /> </RelativeLayout>
EfixImagen
import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.database.Cursor; import android.media.ExifInterface; import android.net.Uri; import android.os.Build; import android.provider.DocumentsContract; import android.provider.MediaStore; import android.support.design.widget.AppBarLayout; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; import android.support.design.widget.TabLayout; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.view.ViewPager; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.Toolbar; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.EditText; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.TableLayout; import android.widget.TableRow; import android.widget.TextView; import com.bumptech.glide.Glide; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.MapView; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.Marker; import com.google.android.gms.maps.model.MarkerOptions; import java.io.File; import java.text.DecimalFormat; public class EfixImagen extends AppCompatActivity { int RESULTADO_FOTO_OK = 1; boolean addedMarker = false; ExifInterface exif; MarkerOptions posMarkerOptions = new MarkerOptions().position(new LatLng(0, 0)).visible(false).draggable(false); Marker posMarker; boolean selectedAnImage = false; Uri iURI = Uri.EMPTY; String iEXIFPath = ""; String iNombreArchivo = ""; String iWidth = ""; String iHeight = ""; Long iSize = 0l; String iLatitud = ""; String iLongitud = ""; String iLatitudRef = ""; String iLongitudRef = ""; Float iLatitudFloat = 0.0f; Float iLongitudFloat = 0.0f; ExifInterface iEXIF = null; public enum rellenar { CARGAR_IMAGEN, RELLENAR_DATOS } /** * The {@link android.support.v4.view.PagerAdapter} that will provide * fragments for each of the sections. We use a * {@link FragmentPagerAdapter} derivative, which will keep every * loaded fragment in memory. If this becomes too memory intensive, it * may be best to switch to a * {@link android.support.v4.app.FragmentStatePagerAdapter}. */ private SectionsPagerAdapter mSectionsPagerAdapter; /** * The {@link ViewPager} that will host the section contents. */ private ViewPager mViewPager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_efix_imagen); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); // Set up the ViewPager with the sections adapter. mViewPager = (ViewPager) findViewById(R.id.container); mViewPager.setAdapter(mSectionsPagerAdapter); TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs); tabLayout.setupWithViewPager(mViewPager); FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.select_photo_fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(Intent.createChooser(intent, getString(R.string.photo_selector)), RESULTADO_FOTO_OK); } }); ImageButton loadImage = (ImageButton) findViewById(R.id.load_image_button); loadImage.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //Uses intent to launch a photo selector Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(Intent.createChooser(intent, getString(R.string.photo_selector)), RESULTADO_FOTO_OK); } }); } @Override public void onPause() { final MapView gMap = (MapView) findViewById(R.id.map); GoogleMap gMapObj = gMap.getMap(); gMapObj.setMyLocationEnabled(false); super.onPause(); } @Override public void onResume() { try { final MapView gMap = (MapView) findViewById(R.id.map); GoogleMap gMapObj = gMap.getMap(); gMapObj.setMyLocationEnabled(true); } catch (NullPointerException e) { } super.onResume(); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == RESULT_OK) { //Successfully selected an image, load it into ImageView using Glide selectedAnImage = true; TableRow imageRow = (TableRow) findViewById(R.id.fila_imagen); imageRow.setBackgroundColor(getResources().getColor(R.color.colorBlack)); imageRow.setVisibility(View.VISIBLE); TableRow messageRow = (TableRow) findViewById(R.id.fila_mensaje); TableLayout table = (TableLayout) findViewById(R.id.layout_table); table.setVisibility(View.VISIBLE); FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.select_photo_fab); fab.setVisibility(View.VISIBLE); AppBarLayout appbar = (AppBarLayout) findViewById(R.id.appbar); appbar.setVisibility(View.VISIBLE); ImageButton loadImage = (ImageButton) findViewById(R.id.load_image_button); loadImage.setVisibility(View.GONE); TextView loadImageText = (TextView) findViewById(R.id.load_image_text); loadImageText.setVisibility(View.GONE); try { iURI = data.getData(); drawImage(); iEXIFPath = getRealPathFromURI(this.getApplicationContext(), iURI); iEXIF = new ExifInterface(iEXIFPath); String[] filepathComponents = iEXIFPath.split("/"); iNombreArchivo = filepathComponents[filepathComponents.length-1]; File image = new File(iEXIFPath); iSize = getImageSizeInKb(image.length()); iWidth = iEXIF.getAttribute(ExifInterface.TAG_IMAGE_WIDTH); iHeight = iEXIF.getAttribute(ExifInterface.TAG_IMAGE_LENGTH); iLatitud = iEXIF.getAttribute(ExifInterface.TAG_GPS_LATITUDE); iLongitud = iEXIF.getAttribute(ExifInterface.TAG_GPS_LONGITUDE); iLatitudRef = iEXIF.getAttribute(ExifInterface.TAG_GPS_LATITUDE_REF); iLongitudRef = iEXIF.getAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF); populateFields(iEXIF, rellenar.CARGAR_IMAGEN); iLatitudFloat = 0f; iLongitudFloat = 0f; addMapMarker(); displayCoordsInDegrees(); } catch (Exception e) { createErrorDialog(android.R.string.dialog_alert_title, R.string.photo_selector_error_text); } } else if (resultCode == RESULT_CANCELED){ } else { createErrorDialog(android.R.string.dialog_alert_title, R.string.photo_selector_error_text); } } public Long getImageSizeInKb(Long imageLength) { if (imageLength <= 0) { return 0l; } else { return imageLength / 1024; } } public void drawImage() { ImageView imageView = (ImageView) findViewById(R.id.foto); imageView.setVisibility(View.VISIBLE); Glide.with(EfixImagen.this).load(iURI).fitCenter().into(imageView); } public void populateFields(ExifInterface exif, rellenar mode) { TextView filename = (TextView) findViewById(R.id.img_nombre_archivo); filename.setText(iNombreArchivo); TextView width = (TextView) findViewById(R.id.img_width); width.setText(iWidth); TextView height = (TextView) findViewById(R.id.img_height); height.setText(iHeight); TextView size = (TextView) findViewById(R.id.img_size_bytes); size.setText(iSize.toString() + getString(R.string.EXIF_size)); if (mode.equals(rellenar.CARGAR_IMAGEN)) { TextView datetime = (TextView) findViewById(R.id.img_date_taken); datetime.setText(exif.getAttribute(ExifInterface.TAG_DATETIME)); TextView camera = (TextView) findViewById(R.id.img_camara); camera.setText(exif.getAttribute(ExifInterface.TAG_MAKE)); TextView lens = (TextView) findViewById(R.id.img_lens); lens.setText(exif.getAttribute(ExifInterface.TAG_APERTURE)); TextView exposure = (TextView) findViewById(R.id.img_exposure); exposure.setText(exif.getAttribute(ExifInterface.TAG_EXPOSURE_TIME)); TextView flash = (TextView) findViewById(R.id.img_flash); flash.setText(exif.getAttribute(ExifInterface.TAG_FLASH)); TextView focalLength = (TextView) findViewById(R.id.img_focal_length); focalLength.setText(exif.getAttribute(ExifInterface.TAG_FOCAL_LENGTH)); } } public void addMapMarker() { if (iLatitud != null && !iLatitud.equals("") && iLongitud != null && !iLongitud.equals("") && iLatitudRef != null && !iLatitudRef.equals("") && iLongitudRef != null && !iLongitudRef.equals("")) { if (iLatitudRef.equals("N")) { iLatitudFloat = toGrados(iLatitud); } else { iLatitudFloat = 0 - toGrados(iLatitud); } if (iLongitudRef.equals("E")) { iLongitudFloat = toGrados(iLongitud); } else { iLongitudFloat = 0 - toGrados(iLongitud); } } final MapView gMap = (MapView) findViewById(R.id.map); if (addedMarker == false) { posMarker = gMap.getMap().addMarker(posMarkerOptions); posMarker.setTitle(getString(R.string.map_position)); addedMarker = true; } posMarker.setVisible(true); posMarker.setPosition(new LatLng(iLatitudFloat, iLongitudFloat)); GoogleMap gMapObj = gMap.getMap(); gMapObj.setOnMapClickListener(new GoogleMap.OnMapClickListener() { @Override public void onMapClick(LatLng latLng) { posMarker.setPosition(latLng); displayCoordsInDegrees(); iLatitud = toGMS(posMarker.getPosition().latitude); iLongitud = toGMS(posMarker.getPosition().longitude); if (posMarker.getPosition().latitude > 0) { iLatitudFloat = toGrados(iLatitud); iLatitudRef = "N"; } else { iLatitudFloat = 0 - toGrados(iLatitud); iLatitudRef = "S"; } if (posMarker.getPosition().longitude > 0) { iLongitudFloat = toGrados(iLongitud); iLongitudRef = "E"; } else { iLongitudFloat = 0 - toGrados(iLongitud); iLongitudRef = "W"; } } }); } public void createErrorDialog(int title, int message) { new AlertDialog.Builder(EfixImagen.this) .setTitle(title) .setMessage(message) .setNeutralButton(android.R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { } }) .setIcon(android.R.drawable.ic_dialog_alert) .show(); } public void displayCoordsInDegrees() { DecimalFormat formato = new DecimalFormat("0.000"); String latFormato = formato.format(posMarker.getPosition().latitude); String lonFormato = formato.format(posMarker.getPosition().longitude); TextView latitud = (TextView) findViewById(R.id.latitud); TextView longitud = (TextView) findViewById(R.id.longitud); latitud.setText(latFormato); longitud.setText(lonFormato); } public Float toGrados(String ref) { if (ref.equals(null) || ref.equals("")) { return 0.0f; } Float result = null; String[] GMS = ref.split(",", 3); String[] stringG = GMS[0].split("/", 2); Double G0 = Double.valueOf(stringG[0]); Double G1 = Double.valueOf(stringG[1]); Double FloatG = G0 / G1; String[] stringM = GMS[1].split("/", 2); Double M0 = Double.valueOf(stringM[0]); Double M1 = Double.valueOf(stringM[1]); Double FloatM = M0 / M1; String[] stringS = GMS[2].split("/", 2); Double S0 = Double.valueOf(stringS[0]); Double S1 = Double.valueOf(stringS[1]); Double FloatS = S0 / S1; result = new Float(FloatG + (FloatM / 60) + (FloatS / 3600)); return result; } public String toGMS(double coordenadas) { int iGRADOS, iMINUTOS, iSEGUNDOS; String result, sGrados, sMinutos, sSegundos; if (coordenadas < 0) { coordenadas = -coordenadas; } iGRADOS = ((int) coordenadas); sGrados = String.valueOf(iGRADOS) + "/1,"; iMINUTOS = (int) (60 * (coordenadas % 1)); sMinutos = String.valueOf(iMINUTOS) + "/1,"; iSEGUNDOS = (int) (60000 * (iMINUTOS % 1)); sSegundos = String.valueOf(iSEGUNDOS) + "/1000"; return sGrados + sMinutos + sSegundos; } public static String getRealPathFromURI(Context context, Uri uri){ Cursor cursor = null; String filePath = ""; if (Build.VERSION.SDK_INT < 19) { try { String[] proj = { MediaStore.Images.Media.DATA }; cursor = context.getContentResolver().query(uri, proj, null, null, null); int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); filePath = cursor.getString(column_index); } finally { if (cursor != null) { cursor.close(); } } } else { String wholeID = DocumentsContract.getDocumentId(uri); String id = wholeID.split(":")[1]; String[] column = {MediaStore.Images.Media.DATA}; String sel = MediaStore.Images.Media._ID + "=?"; cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, column, sel, new String[]{id}, null); int columnIndex = cursor.getColumnIndex(column[0]); if (cursor.moveToFirst()) { filePath = cursor.getString(columnIndex); } cursor.close(); } return filePath; } public boolean saveImage() { try { iEXIF.setAttribute(ExifInterface.TAG_DATETIME, ((TextView) findViewById(R.id.img_date_taken)).getText().toString()); iEXIF.setAttribute(ExifInterface.TAG_MAKE, ((TextView) findViewById(R.id.img_camara)).getText().toString()); iEXIF.setAttribute(ExifInterface.TAG_APERTURE, ((TextView) findViewById(R.id.img_lens)).getText().toString()); iEXIF.setAttribute(ExifInterface.TAG_EXPOSURE_TIME, ((TextView) findViewById(R.id.img_exposure)).getText().toString()); iEXIF.setAttribute(ExifInterface.TAG_FLASH, ((TextView) findViewById(R.id.img_flash)).getText().toString()); iEXIF.setAttribute(ExifInterface.TAG_FOCAL_LENGTH, ((TextView) findViewById(R.id.img_focal_length)).getText().toString()); if (posMarker != null) { TextView latitude = (TextView) findViewById(R.id.latitud); TextView longitude = (TextView) findViewById(R.id.longitud); String lat = toGMS(posMarker.getPosition().latitude); String lon = toGMS(posMarker.getPosition().longitude); iEXIF.setAttribute(ExifInterface.TAG_GPS_LATITUDE, lat); iEXIF.setAttribute(ExifInterface.TAG_GPS_LONGITUDE, lon); if (posMarker.getPosition().latitude > 0) { iEXIF.setAttribute(ExifInterface.TAG_GPS_LATITUDE_REF, "N"); } else { iEXIF.setAttribute(ExifInterface.TAG_GPS_LATITUDE_REF, "S"); } if (posMarker.getPosition().longitude > 0) { iEXIF.setAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF, "E"); } else { iEXIF.setAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF, "W"); } } iEXIF.saveAttributes(); View coordLayout = findViewById(R.id.main_content); Snackbar successSnackbar = Snackbar.make(coordLayout, R.string.photo_save_success_text, Snackbar.LENGTH_SHORT); successSnackbar.show(); ViewGroup mapGroup = (ViewGroup) findViewById(R.id.map); int count = mapGroup.getChildCount(); return true; } catch (Exception e) { return false; } } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.action_settings) { return true; } if (id == R.id.action_save) { if (iEXIF == null) { createErrorDialog(R.string.photo_save, R.string.photo_missing_image_error_text); } else { boolean result = saveImage(); if (result == false) { createErrorDialog(R.string.photo_save, R.string.photo_save_error_text); } } } if (id == R.id.action_clear_EXIF) { try { ViewGroup detailsScroll = (ViewGroup) findViewById(R.id.layout_table); for (int i = 0; i < detailsScroll.getChildCount(); i++) { ViewGroup tableRow = (ViewGroup) detailsScroll.getChildAt(i); for (int j = 0; j < tableRow.getChildCount(); j++) { View view = tableRow.getChildAt(j); if (view instanceof EditText) { ((EditText) view).setText(" "); } } } TextView latitude = (TextView) findViewById(R.id.latitud); TextView longitude = (TextView) findViewById(R.id.longitud); posMarker.setPosition(new LatLng(0,0)); latitude.setText("0.000"); longitude.setText("0.000"); return true; } catch (Exception e) { createErrorDialog(R.string.action_clear_EXIF, R.string.clear_EXIF_error_text); } } return super.onOptionsItemSelected(item); } @Override public void onSaveInstanceState(Bundle savedInstanceState) { String stringURI = iURI.toString(); savedInstanceState.putString("URI", stringURI); savedInstanceState.putString("EXIF_PATH", iEXIFPath); savedInstanceState.putString("FILENAME", iNombreArchivo); savedInstanceState.putString("WIDTH", iWidth); savedInstanceState.putString("HEIGHT", iHeight); savedInstanceState.putLong("SIZE", iSize); savedInstanceState.putString("LAT", iLatitud); savedInstanceState.putString("LON", iLongitud); savedInstanceState.putString("LAT_REF", iLatitudRef); savedInstanceState.putString("LON_REF", iLongitudRef); savedInstanceState.putFloat("LAT_FLOAT", iLatitudFloat); savedInstanceState.putFloat("LON_FLOAT", iLongitudFloat); savedInstanceState.putBoolean("SELECTED_AN_IMAGE", selectedAnImage); //Always call the superclass so it can save the view hierarchy state super.onSaveInstanceState(savedInstanceState); } public void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); String stringURI = savedInstanceState.getString("URI"); iURI = Uri.parse(stringURI); iEXIFPath = savedInstanceState.getString("EXIF_PATH"); iNombreArchivo = savedInstanceState.getString("FILENAME"); iWidth = savedInstanceState.getString("WIDTH"); iHeight = savedInstanceState.getString("HEIGHT"); iSize = savedInstanceState.getLong("SIZE"); iLatitud = savedInstanceState.getString("LAT"); iLongitud = savedInstanceState.getString("LON"); iLatitudRef = savedInstanceState.getString("LAT_REF"); iLongitudRef = savedInstanceState.getString("LON_REF"); iLatitudFloat = savedInstanceState.getFloat("LAT_FLOAT"); iLongitudFloat = savedInstanceState.getFloat("LON_FLOAT"); selectedAnImage = savedInstanceState.getBoolean("SELECTED_AN_IMAGE"); try { iEXIF = new ExifInterface(iEXIFPath); } catch (Exception e) { } TableRow imageRow = (TableRow) findViewById(R.id.fila_imagen); imageRow.setBackgroundColor(getResources().getColor(R.color.colorBlack)); imageRow.setVisibility(View.VISIBLE); FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.select_photo_fab); ImageButton loadImageButton = (ImageButton) findViewById(R.id.load_image_button); AppBarLayout appbar = (AppBarLayout) findViewById(R.id.appbar); TableLayout table = (TableLayout) findViewById(R.id.layout_table); TextView loadImageText = (TextView) findViewById(R.id.load_image_text); if (selectedAnImage == false) { table.setVisibility(View.INVISIBLE); fab.setVisibility(View.INVISIBLE); loadImageButton.setVisibility(View.VISIBLE); appbar.setVisibility(View.INVISIBLE); loadImageText.setVisibility(View.VISIBLE); } else { table.setVisibility(View.VISIBLE); fab.setVisibility(View.VISIBLE); loadImageButton.setVisibility(View.GONE); appbar.setVisibility(View.VISIBLE); loadImageText.setVisibility(View.GONE); } drawImage(); populateFields(null, rellenar.RELLENAR_DATOS); addMapMarker(); displayCoordsInDegrees(); } public class SectionsPagerAdapter extends FragmentPagerAdapter { public SectionsPagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { switch (position) { case 0: return FragmentDetalles.newInstance(position); case 1: return FragmentMapa.newInstance(position); } return null; } @Override public int getCount() { return 2; } @Override public CharSequence getPageTitle(int position) { switch (position) { case 0: return getString(R.string.menu_header_details); case 1: return getString(R.string.menu_header_map); } return null; } } }
activity_efix_imagen
<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/main_content" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:context=".EfixImagen"> <android.support.design.widget.AppBarLayout android:id="@+id/appbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingTop="@dimen/appbar_padding_top" android:theme="@style/AppTheme.AppBarOverlay" android:visibility="invisible"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:popupTheme="@style/AppTheme.PopupOverlay" app:layout_scrollFlags="scroll|enterAlways"> </android.support.v7.widget.Toolbar> <android.support.design.widget.TabLayout android:id="@+id/tabs" android:layout_width="match_parent" android:layout_height="wrap_content" /> </android.support.design.widget.AppBarLayout> <android.support.v4.view.ViewPager android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> <android.support.design.widget.FloatingActionButton android:id="@+id/select_photo_fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="end|bottom" android:layout_margin="@dimen/fab_margin" android:src="@android:drawable/ic_menu_gallery" android:visibility="invisible" /> <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/load_image" android:id="@+id/load_image_button" android:layout_gravity="center" android:src="@drawable/ic_add_a_photo_48dp" android:background="@android:color/transparent" android:clickable="true" /> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge" android:text="@string/load_image" android:id="@+id/load_image_text" android:layout_gravity="center_horizontal|top" android:layout_marginTop="50dp" android:textSize="36dp" android:textIsSelectable="false" android:textStyle="bold" android:paddingTop="50dp" /> </android.support.design.widget.CoordinatorLayout>
FragmentDetalles
import android.net.Uri; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class FragmentDetalles extends Fragment { private static final String ARG_SECTION_NUMBER = "section_number"; private OnFragmentInteractionListener mListener; // TODO: Rename and change types and number of parameters public static FragmentDetalles newInstance(int sectionNumber) { FragmentDetalles fragment = new FragmentDetalles(); Bundle args = new Bundle(); args.putInt(ARG_SECTION_NUMBER, sectionNumber); fragment.setArguments(args); return fragment; } public FragmentDetalles() { } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment return inflater.inflate(R.layout.activity_fragment_detalles, container, false); } // TODO: Rename method, update argument and hook method into UI event public void onButtonPressed(Uri uri) { if (mListener != null) { mListener.onFragmentInteraction(uri); } } @Override public void onDetach() { super.onDetach(); mListener = null; } public interface OnFragmentInteractionListener { // TODO: Update argument type and name public void onFragmentInteraction(Uri uri); } }
activity_fragment_detalles
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".FragmentDetalles"> <!-- The error message should always be behind the image --> <!-- Make it focusable to stop default focus from going to EditText --> <ScrollView android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/scrollDetailsPage" android:layout_gravity="center_horizontal|" android:fillViewport="true" android:scrollbarAlwaysDrawVerticalTrack="true"> <TableLayout android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="75dp" android:measureWithLargestChild="false" android:stretchColumns="1" android:id="@+id/layout_table" android:visibility="gone"> <!--Photo panel--> <TableRow android:id="@+id/fila_mensaje"></TableRow> <!--Photo panel--> <TableRow android:id="@+id/fila_imagen"> <ImageView android:id="@+id/foto" android:layout_width="wrap_content" android:layout_height="200dp" android:scaleType="fitXY" android:contentDescription="@string/photo_viewer_desc" android:adjustViewBounds="true" android:scrollbars="none" android:layout_gravity="center_horizontal|top" android:layout_span="2" android:layout_column="0" android:background="#000000" /> </TableRow> <!--Basic Details Header--> <TableRow> android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/basic_details" android:id="@+id/detalles_basicos" android:layout_column="0" android:layout_weight="1" android:textStyle="bold" android:textSize="26dp" android:paddingBottom="10dp" android:gravity="center_vertical|center_horizontal" /> </TableRow> <!--Filename Field--> <TableRow> android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/EXIF_filename" android:id="@+id/label_EXIF_filename" android:layout_column="1" android:layout_weight="0.35" android:paddingBottom="5dp" android:paddingLeft="10dp" /> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/EXIF_value_unknown" android:id="@+id/img_nombre_archivo" android:layout_column="2" android:layout_weight="0.65" android:paddingBottom="5dp"/> </TableRow> <!--Image Width Field--> <TableRow> android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/EXIF_width" android:id="@+id/label_EXIF_width" android:layout_column="1" android:layout_weight="0.35" android:paddingBottom="5dp" android:paddingLeft="10dp" /> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/EXIF_value_unknown" android:id="@+id/img_width" android:layout_column="2" android:layout_weight="0.65" android:paddingBottom="5dp"/> </TableRow> <!--Image Height Field--> <TableRow> android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/EXIF_height" android:id="@+id/label_EXIF_height" android:layout_column="1" android:layout_weight="0.35" android:paddingBottom="5dp" android:paddingLeft="10dp" /> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/EXIF_value_unknown" android:id="@+id/img_height" android:layout_column="2" android:layout_weight="0.65" android:paddingBottom="5dp" android:paddingRight="10dp" /> </TableRow> <!--Image Size on Disk Field--> <TableRow> android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/EXIF_size_label" android:id="@+id/label_EXIF_size_bytes" android:layout_column="1" android:layout_weight="0.35" android:paddingBottom="5dp" android:paddingLeft="10dp" /> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/EXIF_value_unknown" android:id="@+id/img_size_bytes" android:layout_column="2" android:layout_weight="0.65" android:paddingBottom="5dp"/> </TableRow> <!--Image Date Taken--> <TableRow android:paddingLeft="0dp"> android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/EXIF_date_taken" android:id="@+id/label_EXIF_date_taken" android:layout_column="1" android:layout_weight="0.35" android:paddingBottom="5dp" android:paddingLeft="10dp" /> <EditText android:layout_width="0dp" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/EXIF_value_unknown" android:id="@+id/img_date_taken" android:layout_column="2" android:layout_weight="0.65" android:paddingBottom="5dp" android:paddingRight="10dp" /> </TableRow> <!--Image Camera--> <TableRow> android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/EXIF_camera" android:id="@+id/label_EXIF_camera" android:layout_column="1" android:layout_weight="0.35" android:paddingBottom="5dp" android:paddingLeft="10dp" /> <EditText android:layout_width="0dp" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/EXIF_value_unknown" android:id="@+id/img_camara" android:layout_column="2" android:layout_weight="0.65" android:paddingBottom="5dp" android:paddingRight="10dp" /> </TableRow> <!--Image Lens--> <TableRow> android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/EXIF_lens" android:id="@+id/label_EXIF_lens" android:layout_column="1" android:layout_weight="0.35" android:paddingBottom="5dp" android:paddingLeft="10dp" /> <EditText android:layout_width="0dp" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/EXIF_value_unknown" android:id="@+id/img_lens" android:layout_column="2" android:layout_weight="0.65" android:paddingBottom="5dp"/> </TableRow> <!--Image Exposure--> <TableRow> android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/EXIF_exposure" android:id="@+id/label_EXIF_exposure" android:layout_column="1" android:layout_weight="0.35" android:paddingBottom="5dp" android:paddingLeft="10dp" /> <EditText android:layout_width="0dp" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/EXIF_value_unknown" android:id="@+id/img_exposure" android:layout_column="2" android:layout_weight="0.65" android:paddingBottom="5dp"/> </TableRow> <!--Image Flash--> <TableRow> android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/EXIF_flash" android:id="@+id/label_EXIF_flash" android:layout_column="1" android:layout_weight="0.35" android:paddingBottom="5dp" android:paddingLeft="10dp" /> <EditText android:layout_width="0dp" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/EXIF_value_unknown" android:id="@+id/img_flash" android:layout_column="2" android:layout_weight="0.65" android:paddingBottom="5dp"/> </TableRow> <!--Focal length--> <TableRow> android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/EXIF_focal_length" android:id="@+id/label_EXIF_focal_length" android:layout_column="1" android:layout_weight="0.35" android:paddingBottom="5dp" android:paddingLeft="10dp" /> <EditText android:layout_width="0dp" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/EXIF_value_unknown" android:id="@+id/img_focal_length" android:layout_column="2" android:layout_weight="0.65" android:paddingBottom="5dp"/> </TableRow> <!--Location Details Header--> <TableRow> android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/location_details" android:id="@+id/location_details_header" android:layout_column="0" android:layout_weight="1" android:textStyle="bold" android:textSize="26dp" android:paddingBottom="10dp" android:gravity="center_vertical|center_horizontal" /> </TableRow> <!--Latitude Field--> <TableRow> android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/EXIF_latitude" android:id="@+id/label_EXIF_latitude" android:layout_column="1" android:layout_weight="0.35" android:paddingBottom="5dp" android:paddingLeft="10dp" /> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/EXIF_value_unknown" android:id="@+id/latitud" android:layout_column="2" android:layout_weight="0.65" android:paddingBottom="5dp"/> </TableRow> <!--Longitude Field--> <TableRow> android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/EXIF_longitude" android:id="@+id/label_EXIF_longitude" android:layout_column="1" android:layout_weight="0.35" android:paddingBottom="5dp" android:paddingLeft="10dp" /> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/EXIF_value_unknown" android:id="@+id/longitud" android:layout_column="2" android:layout_weight="0.65" android:paddingBottom="5dp"/> </TableRow> </TableLayout> </ScrollView> </FrameLayout>
FragmentMapa
import android.content.pm.PackageManager; import android.net.Uri; import android.os.Bundle; import android.support.v4.app.ActivityCompat; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.MapView; import com.google.android.gms.maps.OnMapReadyCallback; public class FragmentMapa extends Fragment implements OnMapReadyCallback { MapView gMapView; GoogleMap gMap = null; private static final String ARG_SECTION_NUMBER = "section_number"; private OnFragmentInteractionListener mListener; // TODO: Rename and change types and number of parameters public static FragmentMapa newInstance(int sectionNumber) { FragmentMapa fragment = new FragmentMapa(); Bundle args = new Bundle(); args.putInt(ARG_SECTION_NUMBER, sectionNumber); fragment.setArguments(args); return fragment; } public FragmentMapa() { // Required empty public constructor } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (ActivityCompat.checkSelfPermission(getContext(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getContext(), android.Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(getActivity(), new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION,}, 1000); return; } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View view = inflater.inflate(R.layout.activity_fragment_map, container, false); gMapView = (MapView) view.findViewById(R.id.map); gMapView.onCreate(savedInstanceState); gMap = gMapView.getMap(); gMap.setMapType(GoogleMap.MAP_TYPE_NORMAL); gMap.setMyLocationEnabled(true); //gMapView.getMapAsync(this); return view; } @Override public void onMapReady(GoogleMap map) { gMap = map; } // TODO: Rename method, update argument and hook method into UI event public void onButtonPressed(Uri uri) { if (mListener != null) { mListener.onFragmentInteraction(uri); } } @Override public void onDetach() { super.onDetach(); mListener = null; } public interface OnFragmentInteractionListener { // TODO: Update argument type and name public void onFragmentInteraction(Uri uri); } @Override public void onResume() { gMapView.onResume(); super.onResume(); } @Override public void onDestroy() { super.onDestroy(); gMapView.onDestroy(); } @Override public void onLowMemory() { super.onLowMemory(); gMapView.onLowMemory(); } }
activity_fragment_mapa
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".FragmentMapa"> <com.google.android.gms.maps.MapView android:id="@+id/map" android:layout_width="match_parent" android:layout_height="match_parent" /> </FrameLayout>
AndroidManifest
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.androfast.server.appobtenerefiximagen"> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <permission android:name="com.androfast.server.appobtenerefiximagen.permission.MAPS_RECEIVE" android:protectionLevel="signature" /> <uses-permission android:name="com.androfast.server.appobtenerefiximagen.permission.MAPS_RECEIVE" /> <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.INTERNET" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme.NoActionBar"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".EfixImagen" /> <meta-data android:name="com.google.android.geo.API_KEY" android:value="AQUÍ VA TU CLAVE API KEY PARA QUE FUNCIONE EL GOOGLE MAP" /> </application> </manifest>
build.gradle
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile 'com.android.support:appcompat-v7:23.1.0-alpha1' testCompile 'junit:junit:4.12' compile 'com.android.support:design:23.2.1' compile 'com.github.bumptech.glide:glide:3.6.1' compile 'com.android.support:support-v4:23.1.0' compile 'com.google.android.gms:play-services:8.1.0' }
Nota: He puesto solo las clases principales, aquí hay que hacer cambios como en el layout color o String entonces les recomiendo que se descarguen la aplicación sin antes recomendarle que solo es compatible con la Api 19 hacia arriba. No olviden poner su api key en AndroidManifest.
Adjunto algunas imágenes como captura los metadatos y luego hace seguimiento por medio de google Maps
Con eso hemos terminado, así que les voy dejar a continuación el enlace de descarga, pero recuerda. Copiar no es lo mismo que comparar.
Descargar:Como Obtener metadatos de una imagen en android studio
Password: www.androfast.com
También puedes revisar: 4 hosting gratuitos para hacer pruebas informáticas
Hola soy Alex Céspedes fundador de ANDROFAST, programo algunas cosas por diversión, me gusta aprender cosas nuevas y estoy pendiente de todo lo que tenga que ver con tecnología. Este blog lo cree para todas las personas que tengan dificultades en la programación, para ser sincero nunca fui bueno y reprobé algunos cursos de programación, pero mis ganas de aprender pudieron más. SI YO PUEDO TU PUEDES ANIMO!
Existirá la posibilidad de sacar la geolocalización de imágenes recibidas por Whatsapp? Es por cuestiones de trabajo, estaría dispuesto a pagar por ello
Tengo entendido que no se podria, la mayoria de redes sociales formatean sus imagenes al subirla a sus servidores, por consiguiente los metadatos originales se borran.