Android get current GEO Coordinates - android

How to get GEO Coordinates ( latitude & longitude ) without using GPS in android ?
Any Suggestion ?..

/**
* This is a fast code to get the last known location of the phone. If there
* is no exact gps-information it falls back to the network-based location
* info. This code is using LocationManager. Code from:
* http://www.androidsnippets.org/snippets/21/
*
* #param ctx
* #return
*/
public static Location getLocation(Context ctx) {
LocationManager lm = (LocationManager) ctx
.getSystemService(Context.LOCATION_SERVICE);
List<String> providers = lm.getProviders(true);
/*
* Loop over the array backwards, and if you get an accurate location,
* then break out the loop
*/
Location l = null;
for (int i = providers.size() - 1; i >= 0; i--) {
l = lm.getLastKnownLocation(providers.get(i));
if (l != null)
break;
}
return l;
}

Related

Android MapsApiV2 Location.distanceTo is giving wrong values

This seems like a duplicate question but it is not. Please read before you mark it as duplicate
I was trying to get distance between two LatLng, so first i generated it's PolylineOptions,
Now the problem is - The output is not understandable.
It's different from other questions because it uses PolylineOptions.
Calculating Code
#Override
public void onParserTaskComplete(PolylineOptions points, int count) {
if (points != null) {
float totalDistance = 0;
for (int i = 1; i < points.getPoints().size(); i++) {
Location currLocation = new Location("this");
currLocation.setLatitude(points.getPoints().get(i).latitude);
currLocation.setLongitude(points.getPoints().get(i).longitude);
Location lastLocation = new Location("this");
currLocation.setLatitude(points.getPoints().get(i - 1).latitude);
currLocation.setLongitude(points.getPoints().get(i - 1).longitude);
totalDistance += lastLocation.distanceTo(currLocation);
}
items.get(count).setDistance(String.valueOf(totalDistance));
adapter.notifyDataSetChanged();
} else {
items.get(count).setDistance("");
adapter.notifyDataSetChanged();
}
}
According to Google Maps the distance should be around 5.5KM
but output is coming like 8783711.0
Question - How do i convert this value to KM?
You duplicated currLocation and don't set values for lastLocation.
This is correct way:
Location currLocation = new Location("this");
currLocation.setLatitude(points.getPoints().get(i).latitude);
currLocation.setLongitude(points.getPoints().get(i).longitude);
Location lastLocation = new Location("this");
// here you used currLocation
lastLocation.setLatitude(points.getPoints().get(i - 1).latitude);
lastLocation.setLongitude(points.getPoints().get(i - 1).longitude);

Chat Application with Maps

I want to build a basic chat application which includes location sharing. I proficient enough in Java, but haven't worked enough on Android Platform. How do I approach this problem and what are the steps to be taken?
Send location values latitude and longitude to the other person via chat message. You can get user's last known location by:
private double[] getGPS()
{
LocationManager lm = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
List<String> providers = lm.getProviders(true);
/* Loop over the array backwards, and if you get an accurate location, then break out the loop */
Location l = null;
for (int i = providers.size() - 1; i >= 0; i--)
{
l = lm.getLastKnownLocation(providers.get(i));
if (l != null)
break;
}
double[] gps = new double[2];
if (l != null)
{
gps[0] = l.getLatitude();
gps[1] = l.getLongitude();
}
return gps;
}

Avoid get multiple location when device is still stable in gps android

i using simple Listner Class for get location in onchage location
but the device is stable then gps is getting wrong lat long and get multliple location up to in 1000 meter.
MyLocationListener.java
public class MyLocationListener implements LocationListener{
#Override
public void onLocationChanged(Location location) {
// Toast.makeText(getBaseContext(), "change time", 5).show();
if(location.getAccuracy() < 100.0 && location.getSpeed() >0.95){
Log.v("ddddddd", "fffffffff"+location.getLongitude()+location.getProvider());
// if (location.hasAccuracy() && location.getAccuracy() <= minAccuracyMeters){
accuracy=location.getAccuracy();
longitude=location.getLongitude();
latitude=location.getLatitude();
speed=(int) ((location.getSpeed()*3600)/1000);
}
}
Please Help me i new in android i will workin on GPS last two month.
Filter the locations this way,
public static final int MINIMUM_ACCURACY = 50;
public static boolean isValidAndAccurateLocation(Location location) {
boolean validLocation = location != null
&& Math.abs(location.getLatitude()) <= 90
&& Math.abs(location.getLongitude()) <= 180;
if (validLocation && location.hasAccuracy()
&& location.getAccuracy() <= MINIMUM_ACCURACY) {
return true;
} else {
return false;
}
}
Provide minimum distance when requesting location updates, No need to calculate distance manually. use
mLocationManger.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, time, distance,
this);
Where time is time in milliseconds and distance is minimum distance in meters. See this for full explanation.

How to get the latitude and longitude or gps data quickly while we are indoor in an android phone?

I'm trying to get the latitude and longitude information from an android phone through GPS, when i'm outdoor or under the sky directly i'm able to get the values instantly but when i'm indoor or inside a room its taking more than a minute to get the values. Can anyone help me in getting this values fastly when I'm using my app inside a room.
I'm using the following code in getting the values:
LocationManager locManager;
locManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,1000L,500.0f,
locationListener);
Location location = locManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
and
private final LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
EditText myLocationText = (EditText)findViewById(R.id.editText1);
EditText myLocationText1 = (EditText)findViewById(R.id.editText2);
String latString = "";
String LongString = "";
if (location != null) {
double lat = location.getLatitude();
double lng = location.getLongitude();
latString = "" + lat;
LongString ="" + lng;
} else {
latString = "No location found";
LongString = "No location found";
}
myLocationText.setText(""+ latString);
myLocationText1.setText(""+ LongString);
}
Is there any other way in getting the GPS values other than using LocationManager??
You can get the last known location, and it's quite fast:
/**
* Gets the last known location.
*
* #param locationManager the location manager
* #return the last known location
*/
public static Location getLastKnownLocation(LocationManager locationManager)
{
Location bestResult = null;
float bestAccuracy = 10000;
long bestTime = 0;
List<String> matchingProviders = locationManager.getAllProviders();
for (String provider: matchingProviders) {
Log.d("LOCATION", "Provider: " + provider);
Location location = locationManager.getLastKnownLocation(provider);
Log.d("LOCATION", "Location found? "+ (location==null?"NO":"YES"));
if (location != null) {
float accuracy = location.getAccuracy();
long time = location.getTime();
Log.d("LOCATION", "Acc: "+ String.valueOf(accuracy) + " -- Time: " + String.valueOf(time));
if ((time > minTime && accuracy < bestAccuracy)) {
bestResult = location;
bestAccuracy = accuracy;
bestTime = time;
}
else if (time < minTime &&
bestAccuracy == Float.MAX_VALUE && time > bestTime){
bestResult = location;
bestTime = time;
}
}
}
Log.d("LOCATION", "BEST FOUND? "+ (bestResult==null?"NO":"YES"));
return bestResult;
}
You can get the last known location of the device using the following method in LocationManager, this is the location that has been last found system-wide.
This method is the key:
Location lastKnownLocation = locationManager.getLastKnownLocation(locationProvider);
See for more details Obtaining User Location
If you are indoors, you would be better of using LocationManager.NETWORK_PROVIDER as you are unlikely to get a signal inside. You could also use getLastKnownLocation(), but this may be non existent or out of date.
If you want get position in a room, gps provider is slowly. You can try changing:
locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,1000L,500.0f,
locationListener);
Location location = locManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
By:
locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,1000L,500.0f,
locationListener);
And you will receive location in 'public void onLocationChanged(Location location)' method.
I used Network provider to fetch the Co-Ordinates and it is always much faster inside the house in living room. But when I try the same in the Basement area, it doesn't fetch the coordinates at all though I waited almost couple of minutes.
Note: I could able to make a call from basement area and I am also able to browse as well..

How to save GPS coordinates in exif data on Android?

I am writing GPS coordinates to my JPEG image, and the coordinates are correct (as demonstrated by my logcat output) but it appears that it's being corrupted somehow. Reading the exif data results in either null values or, in the case of my GPS: 512.976698 degrees, 512.976698 degrees. Can anyone shed some light on this problem?
writing it:
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();
}
and reading it:
try {
ExifInterface exif = new ExifInterface("/sdcard/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();
}
It goes in (for example) 37.715183, -117.260489 and comes out 33619970/65540, 14811136/3368550, 33619970/65540, 14811136/3368550. Am I doing it wrong?
EDIT:
So, the problem is I am not encoding it in the properly defined format, which is something like you see here:
Can anyone explain what this format is? Obviously the first number is 22/1 = 22 degrees, but I can't figure out how to compute the decimal there.
GPSLatitude
Indicates the latitude. The latitude is expressed as three
RATIONAL values giving the degrees,
minutes, and seconds, respectively.
If latitude is expressed as degrees,
minutes and seconds, a typical format
would be dd/1,mm/1,ss/1. When degrees
and minutes are used and, for
example, fractions of minutes are
given up to two decimal places, the
format would be dd/1,mmmm/100,0/1.
https://docs.google.com/viewer?url=http%3A%2F%2Fwww.exif.org%2FExif2-2.PDF
The Android docs specify this without explanation: http://developer.android.com/reference/android/media/ExifInterface.html#TAG_GPS_LATITUDE
Exif data is standardized, and GPS data must be encoded using geographical coordinates (minutes, seconds, etc) described above instead of a fraction. Unless it's encoded in that format in the exif tag, it won't stick.
How to encode: http://en.wikipedia.org/wiki/Geographic_coordinate_conversion
How to decode: http://android-er.blogspot.com/2010/01/convert-exif-gps-info-to-degree-format.html
Here is some code I've done to geotag my pictures. It's not heavily tested yet, but it seems to be ok (JOSM editor and exiftool read location).
ExifInterface exif = new ExifInterface(filePath.getAbsolutePath());
exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE, GPS.convert(latitude));
exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE_REF, GPS.latitudeRef(latitude));
exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE, GPS.convert(longitude));
exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF, GPS.longitudeRef(longitude));
exif.saveAttributes();
And class GPS is here. (method could be shorter, but it's readable at least)
/*
* #author fabien
*/
public 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(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(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
*/
synchronized public static final String convert(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();
}
}
Other answers delivered nice background info and even an example. This is not a direct answer to the question but I would like to add an even simpler example without the need to do any math. The Location class delivers a nice convert function:
public String getLonGeoCoordinates(Location location) {
if (location == null) return "0/1,0/1,0/1000";
// You can adapt this to latitude very easily by passing location.getLatitude()
String[] degMinSec = Location.convert(location.getLongitude(), Location.FORMAT_SECONDS).split(":");
return degMinSec[0] + "/1," + degMinSec[1] + "/1," + degMinSec[2] + "/1000";
}
I stored the return value in my image and the tag is parsed fine. You can check your image and the geocoordinates inside here: http://regex.info/exif.cgi
Edit
#ratanas comment translated to code:
public boolean storeGeoCoordsToImage(File imagePath, Location location) {
// Avoid NullPointer
if (imagePath == null || location == null) return false;
// If we use Location.convert(), 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;
}
Here are some nice LatLong converter: latlong.net
ExifInterface exif = new ExifInterface(compressedImage.getPath());
exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE,gpsTracker.dec2DMS(gpsTracker.getLatitude()));
exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE,gpsTracker.dec2DMS(gpsTracker.getLongitude()));
Convertor double to String
String dec2DMS(double coord) {
coord = coord > 0 ? coord : -coord;
String sOut = Integer.toString((int)coord) + "/1,";
coord = (coord % 1) * 60;
sOut = sOut + Integer.toString((int)coord) + "/1,";
coord = (coord % 1) * 60000;
sOut = sOut + Integer.toString((int)coord) + "/1000";
return sOut;
}
The most modern and shortest solution (with AndroidX) is using ExifInterface.setGpsInfo(Location), for example:
ExifInterface exif = new ExifInterface(filename);
Location location = new Location(""); //may be empty
location.setLatitude(latitude); //double value
location.setLongitude(longitude); //double value
exif.setGpsInfo(location)
exif.saveAttributes();
Sources: one and two
check android source code: https://android.googlesource.com/platform/frameworks/base/+/android-4.4.2_r2/core/java/android/hardware/Camera.java
/**
* Sets GPS longitude coordinate. This will be stored in JPEG EXIF
* header.
*
* #param longitude GPS longitude coordinate.
*/
public void setGpsLongitude(double longitude) {
set(KEY_GPS_LONGITUDE, Double.toString(longitude));
}
So it's a direct print, my log supports it as well: ExifInterface.TAG_GPS_LONGITUDE : -121.0553966
My conclusion is setting it as direct print is fine.

Categories

Resources