I'm retrieving addresses from cooridnates using the Google API with the following method:
public static String[] getFromLocation(double lat, double lng, int retries) {
String address = String.format(Locale.getDefault(),
"https://maps.googleapis.com/maps/api/geocode/json?latlng=%1$f,%2$f&sensor=false&language="
+ Locale.getDefault(), lat, lng);
String[] res = new String[3];
String addressLine = "";
String locality = "";
String country = "";
String json = null;
HttpURLConnection conn = null;
StringBuilder jsonResults = new StringBuilder();
try {
URL url = new URL(address);
conn = (HttpURLConnection) url.openConnection();
InputStreamReader in = new InputStreamReader(conn.getInputStream());
int read;
char[] buff = new char[1024];
while ((read = in.read(buff)) != -1) {
jsonResults.append(buff, 0, read);
}
json = jsonResults.toString();
JSONObject jsonObject = new JSONObject(json);
if ("OK".equalsIgnoreCase(jsonObject.getString("status"))) {
JSONArray results = jsonObject.getJSONArray("results");
if (results.length() > 0) {
JSONObject result = results.getJSONObject(0);
//Address addr = new Address(Locale.getDefault());
JSONArray components = result.getJSONArray("address_components");
String streetNumber = "";
String route = "";
for (int a = 0; a < components.length(); a++) {
JSONObject component = components.getJSONObject(a);
JSONArray types = component.getJSONArray("types");
for (int j = 0; j < types.length(); j++) {
String type = types.getString(j);
if (type.equals("locality")) {
locality = component.getString("long_name");
} else if (type.equals("street_number")) {
streetNumber = component.getString("long_name");
} else if (type.equals("route")) {
route = component.getString("long_name");
} else if (type.equals("country")) {
country = component.getString("long_name");
}
}
}
addressLine = route + " " + streetNumber;
}
}
} catch (Exception e) {
Log.e(LOG_TAG, "Exception:", e);
LogsToServer.send(my_id, e);
if (json != null) LogsToServer.send(my_id, json);
System.out.println("retries: " + retries);
if (retries > 0){
try {
Thread.sleep(500);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
return getFromLocation(lat, lng, retries-1);
}
}
res[0] = addressLine;
res[1] = locality;
res[2] = country;
return res;
}
The problem is that I very often get the exception:
03-12 23:54:01.387: E/GetAddressDetails(25248): java.io.FileNotFoundException: https://maps.googleapis.com/maps/api/geocode/json?latlng=48,2&sensor=false&language=en_GB
03-12 23:54:01.387: E/GetAddressDetails(25248): at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:197)
03-12 23:54:01.387: E/GetAddressDetails(25248): at com.android.okhttp.internal.http.DelegatingHttpsURLConnection.getInputStream(DelegatingHttpsURLConnection.java:210)
03-12 23:54:01.387: E/GetAddressDetails(25248): at com.android.okhttp.internal.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:25)
If I launch the method with 4 retries, they may all fail, or sometimes after 2 or 3 I get the address. Do you know why it fails so often? When I access the same site in my browser I always get the page without errors!
EDIT: I checked the error message returned by Google and it goes like this:
We're sorry... but your computer or network may be sending automated queries. To protect our users, we can't process your request right now.
Is it a joke? Automated queries? Isn't it the whole purpose of APIs to be called by automatic processes?
Also, this happens from many phones and started yesterday. How does google know that all the requests come from the same app?
If you want to get address from cooridnates, you can use Geocoder api.
I used following code in my app to get the city name:
private double mLongitude; // current longitude
private double mLatitude; // current latitude
private String mCityName; // output cityName
private void getCityName() {
Geocoder gcd = new Geocoder(this, Locale.getDefault());
List<Address> addresses;
try {
addresses = gcd.getFromLocation(mLatitude, mLongitude, 1);
if (addresses.size() != 0) {
mCityName = addresses.get(0).getAddressLine(1);
mCityName = mCityName.replaceAll("[\\d.]", "");
Log.d(TAG + "!!!!!!!!!!!", mCityName);
}
} catch (IOException e) {
e.printStackTrace();
}
}
If you want get whole address, as I changed a little bit, just do this way:
private double mLongitude; // current longitude
private double mLatitude; // current latitude
private String mAddress; // output address
private void getAddress() {
Geocoder gcd = new Geocoder(this, Locale.getDefault());
List<Address> addresses;
try {
addresses = gcd.getFromLocation(mLatitude, mLongitude, 1);
if (addresses.size() != 0) {
mAddress = addresses.get(0).getAddressLine(0) + " " +
addresses.get(0).getAddressLine(1) + " " +
addresses.get(0).getAddressLine(2);
//mAddress = mAddress.replaceAll("[\\d.]", "");
Log.d(TAG + "!!!!!!!!!!!", mAddress);
}
} catch (IOException e) {
e.printStackTrace();
}
}
Related
i have the problem as this question and i also did the same hardcoding for the lat and lon.
i get the exception to confirm the size as
Exception for the locationjava.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
When I try the same code on the Redmi a4, it works fine and give me the size as 1, and also the geocoding works fine, returning me all the addresses. The same code when I run on Lenovo it gives the exception. I checked the lat and lon and they have values which when i trace is pointing to my location. So what should I do to make the app run on both of the phones.
Lenovo phone running Android 4.4.4
Redmi running 6.0.0
if(lat != null && lon !=null) {
try{
Geocoder geocoder;
List<Address> addresses;
geocoder = new Geocoder(this, Locale.getDefault());
addresses = geocoder.getFromLocation(dlat, dlon, 1); // Here 1 represent max location result to returned, by documents it recommended 1 to 5
System.out.println("this is the size of address size"+addresses.size());
String address = addresses.get(0).getAddressLine(0); // If any additional address line present than only, check with max available address lines by getMaxAddressLineIndex()
String city = addresses.get(0).getLocality();
String state = addresses.get(0).getAdminArea();
String country = addresses.get(0).getCountryName();
String postalCode = addresses.get(0).getPostalCode();
String knownName = addresses.get(0).getFeatureName();
complete_address=address + "_" + city + "_" + address + "_" + postalCode + "_" + knownName + "_" + country;
txtOutputLat.setText(complete_address);
txtOutputLon.setText("Map Address");
}
catch(Exception e)
{
System.out.println("Exception for the location"+e.toString());
}
}
Create this class and copy the code this works perfectly for me also this works in background and stops the main thread from ANR dialog
import android.content.Context;
import android.location.Address;
import android.location.Geocoder;
import android.os.AsyncTask;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
public class GetLocationAsync extends AsyncTask<String, Void, String> {
private String fulladdress = "";
private String smallAddress = "";
private String city = "";
private String state = "";
private String country = "";
private String zipcode = "";
private String placeName = "";
private AsyncResponse asyncResponseDelegate = null;
private double x, y;
private Context context;
public interface AsyncResponse {
void onProcessFinished(String fulladdress, String smallAddress, String state, String city, String country, String zipCode, String placeName);
}
public GetLocationAsync(double latitude, double longitude, final Context context, AsyncResponse asyncResponse) {
x = latitude;
y = longitude;
this.context = context;
this.asyncResponseDelegate = asyncResponse;
}
#Override
protected void onPreExecute() {
}
#Override
protected String doInBackground(String... params) {
Geocoder geocoder = new Geocoder(context, Locale.ENGLISH);
try {
List<Address> addressList = geocoder.getFromLocation(x, y, 1);
StringBuilder sb = new StringBuilder();
if (addressList != null && addressList.size() > 0) {
Address address = addressList.get(0);
fulladdress = "";
smallAddress = "";
placeName = "";
if (sb.append(address.getAddressLine(0)) != null) {
smallAddress = address.getAddressLine(0);
fulladdress = smallAddress;
}
if (address.getLocality() != null) {
city = address.getLocality();
if (!fulladdress.contains(city))
fulladdress = fulladdress + " " + city;
}
if (address.getFeatureName() != null) {
placeName = address.getFeatureName();
}
if (address.getAdminArea() != null) {
state = address.getAdminArea();
if (!fulladdress.contains(state))
fulladdress = fulladdress + " " + state;
}
if (address.getPostalCode() != null) {
zipcode = address.getPostalCode();
if (!fulladdress.contains(zipcode))
fulladdress = fulladdress + " " + zipcode;
}
if (address.getCountryName() != null) {
country = address.getCountryName();
if (!fulladdress.contains(country))
fulladdress = fulladdress + " " + country;
}
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
try {
if (fulladdress != null && !fulladdress.isEmpty()) {
asyncResponseDelegate.onProcessFinished(fulladdress, smallAddress, state, city, country, zipcode, placeName);
} else {
asyncResponseDelegate.onProcessFinished("", "", "", "", "", "", "");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
to call this class
GetLocationAsync locationAsync = new GetLocationAsync(latitude,
longitude, getActivity(), new GetLocationAsync.AsyncResponse() {
#Override
public void onProcessFinished(String fulladdress, String smallAddress, String state, String city, String country, String zipCode, String placeName) {
etAddress.setText(fulladdress);
}
});
locationAsync.execute();
What happens is when you try to get the postal code,city,country etc etc only from the address is that you might not recieve it for the very first time since its trying to get all zipcode, country, state and city from a single provider, which may not be available at times. Instead if you loop through the providers you may find it in one of them. Try this hope it helps!
List<Address> addresses = null;
try {
addresses =geocoder.getFromLocation(latitude,longitude, 5);
if (addresses.size() > 0) {
zipCode = addresses.get(0).getPostalCode();
city = addresses.get(0).getLocality();
country = addresses.get(0).getCountryName();
state = addresses.get(0).getAdminArea();
address = addresses.get(0).getAddressLine(0);
knownName = addresses.get(0).getFeatureName();
//if 1st provider does not have data, loop through other providers to find it.
int count = 0;
while ( count < addresses.size()) {
zipCode = addresses.get(count).getPostalCode();
city= addresses.get(count).getLocality();
country = addresses.get(count).getCountryName();
state = addresses.get(count).getAdminArea();
address = addresses.get(count).getAddressLine(0);
knownName = addresses.get(count).getFeatureName();
count++;
}
}
} catch (IOException e) {
e.printStackTrace();
}
Check for internet connection before calling geocoder.
if(isConnectingToInternet(getContext()){
//write your code of calling geocoder
}
public boolean isConnectingToInternet(Context context) {
try {
if (context != null) {
ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivity != null) {
NetworkInfo[] info = connectivity.getAllNetworkInfo();
if (info != null)
for (int i = 0; i < info.length; i++)
if (info[i].getState() == NetworkInfo.State.CONNECTED) {
return true;
}
}
}
} catch (Exception e) {
e.printStacktrace
}
return false;
}
I want to get location address from LatLng
I tried some ways but i did not get answer, because it seems this service closed by google, so i getting timeout error when i using following code, is there another solution?
Geocoder geocoder;
List<Address> addresses;
geocoder = new Geocoder(this, Locale.getDefault());
addresses = geocoder.getFromLocation(latitude, longitude, 1);
String address = addresses.get(0).getAddressLine(0);
String city = addresses.get(0).getAddressLine(1);
String country = addresses.get(0).getAddressLine(2);
private String getCompleteAddressString(double LATITUDE, double LONGITUDE) {
String strAdd = "";
Geocoder geocoder = new Geocoder(this, Locale.getDefault());
try {
List<Address> addresses = geocoder.getFromLocation(LATITUDE, LONGITUDE, 1);
if (addresses != null) {
Address returnedAddress = addresses.get(0);
StringBuilder strReturnedAddress = new StringBuilder("");
for (int i = 0; i < returnedAddress.getMaxAddressLineIndex(); i++) {
strReturnedAddress.append(returnedAddress.getAddressLine(i)).append("\n");
}
strAdd = strReturnedAddress.toString();
Log.w("My Current loction address", "" + strReturnedAddress.toString());
} else {
Log.w("My Current loction address", "No Address returned!");
}
} catch (Exception e) {
e.printStackTrace();
Log.w("My Current loction address", "Canont get Address!");
}
return strAdd;
}
Try this function, it is working fine.
This is working fine, check code below and keep your geocoder.getFromLocation() method in try block
Click Here
Try this one
public static String getAddressInString(Context context, LatLng latLng) {
Geocoder geocoder = new Geocoder(context, Locale.getDefault());
try {
List<Address> addresses = geocoder.getFromLocation(latLng.latitude, latLng.longitude, 1);
if (addresses != null && addresses.size() > 0) {
return convertToString(addresses.get(0));
} else {
return "";
}
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
public static String convertToString(Address obj) {
String add = "";
if (obj == null)
return "";
add = obj.getAddressLine(0);
if (obj.getSubAdminArea() != null)
add = add + "\n" + obj.getSubAdminArea();
if (obj.getPostalCode() != null)
add = add + " - " + obj.getPostalCode();
if (obj.getAdminArea() != null)
add = add + "\n" + obj.getAdminArea();
if (obj.getCountryName() != null)
add = add + "\n" + obj.getCountryName();
return add;
}
As the title writes, I would like to get the name of city (only) and not the address from coordinates. I find the code below but it returns me all the address and not only the city.
Geocoder geoCoder = new Geocoder(this, Locale.getDefault());
StringBuilder builder = new StringBuilder();
try {
List<Address> address = geoCoder.getFromLocation(latitude, longitude, 1);
int maxLines = address.get(0).getMaxAddressLineIndex();
for (int i=0; i<maxLines; i++) {
String addressStr = address.get(0).getAddressLine(i);
builder.append(addressStr);
builder.append(" ");
}
String finalAddress = builder.toString(); //This is the complete address.
} catch (IOException e) {}
catch (NullPointerException e) {}
Please if someone could help me I'll be very pleasure.
Thank's a lot in advance!
Geocoder geoCoder = new Geocoder(this, Locale.getDefault());
StringBuilder builder = new StringBuilder();
try {
List<Address> address = geoCoder.getFromLocation(latitude, longitude, 1);
if (addresses.size() > 0) {
String city = addresses.get(0).getLocality();
}
//the rest of your code
I don't think there is a better way to get the City name ONLY, except using getLocality(). When we use getLocality(), you can see that we have City name, country name etc. Just analyze the output of this function and you will encounter that all the bits are separated by "Comma". City name is at 0th index.
private void getLocation(String lat, String longt) {
String myCity = " ";
Geocoder geocoder = new Geocoder(MainActivity.this, Locale.getDefault());
try {
List<Address>addresses = geocoder.getFromLocation(Double.parseDouble(lat),Double.parseDouble(longt), 1);
String address = addresses.get(0).getAddressLine(0);
myCity = addresses.get(0).getLocality();
Log.d("myLog", "Address: " + address);
String arrp[] = address.split(",");
Log.d("myLog", "City: " + arrp[0]);
}
catch (IOException e) {
e.printStackTrace();
}
In my app I am using osm map. I have latitude and longitude.
using this method
proj = mapView.getProjection();
loc = (GeoPoint) proj.fromPixels((int) e.getX(), (int) e.getY());
String longitude = Double
.toString(((double) loc.getLongitudeE6()) / 1000000);
String latitude = Double
.toString(((double) loc.getLatitudeE6()) / 1000000);
Toast toast = Toast.makeText(getApplicationContext(), "Longitude: "
+ longitude + " Latitude: " + latitude, Toast.LENGTH_SHORT);
toast.show();
So from here how I will query to get the city name from osm database. Please help me.
How can I convert this into human understandable form. Here is my code which I am using.link
Try this code for getting address.
Geocoder geocoder;
List<Address> addresses;
geocoder = new Geocoder(this, Locale.getDefault());
addresses = geocoder.getFromLocation(latitude, longitude, 1);
String address = addresses.get(0).getAddressLine(0);
String city = addresses.get(0).getAddressLine(1);
String country = addresses.get(0).getAddressLine(2);
for openstreammap
final String requestString = "http://nominatim.openstreetmap.org/reverse?format=json&lat=" +
Double.toString(lat) + "&lon=" + Double.toString(lon) + "&zoom=18&addressdetails=1";
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, URL.encode(requestString));
try {
#SuppressWarnings("unused")
Request request = builder.sendRequest(null, new RequestCallback() {
#Override
public void onResponseReceived(Request request, Response response) {
if (response.getStatusCode() == 200) {
String city = "";
try {
JSONValue json = JSONParser.parseStrict(response);
JSONObject address = json.isObject().get("address").isObject();
final String quotes = "^\"|\"$";
if (address.get("city") != null) {
city = address.get("city").toString().replaceAll(quotes, "");
} else if (address.get("village") != null) {
city = address.get("village").toString().replaceAll(quotes, "");
}
} catch (Exception e) {
}
}
}
});
} catch (Exception e) {
}
here is my solution. i think it works for you also.
public String ConvertPointToLocation(GeoPoint point) {
String address = "";
Geocoder geoCoder = new Geocoder( getBaseContext(), Locale.getDefault());
try {
List<Address> addresses = geoCoder.getFromLocation(
point.getLatitudeE6() / 1E6,
point.getLongitudeE6() / 1E6, 1);
if (addresses.size() > 0) {
for (int index = 0; index < addresses.get(0).getMaxAddressLineIndex(); index++)
address += addresses.get(0).getAddressLine(index) + " ";
}
Toast.makeText(getBaseContext(), address, Toast.LENGTH_SHORT).show();
}
catch (IOException e) {
e.printStackTrace();
}
return address;
}
I reffred many questions from Stack overflow and implemented the above procedure. But I am unable to get the adress. Please let me know If i missed something.. ?
myLoc = (TextView) findViewById(R.id.id1);
Geocoder geocoder = new Geocoder(getBaseContext(),Locale.getDefault());
try {
address = geocoder.getFromLocation(latitude, longitude, 1);
if (address.size() > 0) {
for (int i = 0; i < address.get(0)
.getMaxAddressLineIndex(); i++) {
display = "";
display += address.get(0).getAddressLine(i)
+ "\n";
}
}
} catch (Exception e2) {
// TODO: handle exception
}
myLoc.setText("Current Location:"+display);
System.out.println(display);
You can use Reverse geo coding to and Google apis to get address from latitude and longitude.
Reverse Geo Coding:
double currentLatitude;
double currentLongitude;
void getAddress(){
try{
Geocoder gcd = new Geocoder(this, Locale.getDefault());
List<Address> addresses =
gcd.getFromLocation(currentLatitude, currentLongitude,100);
if (addresses.size() > 0) {
StringBuilder result = new StringBuilder();
for(int i = 0; i < addresses.size(); i++){
Address address = addresses.get(i);
int maxIndex = address.getMaxAddressLineIndex();
for (int x = 0; x <= maxIndex; x++ ){
result.append(address.getAddressLine(x));
result.append(",");
}
result.append(address.getLocality());
result.append(",");
result.append(address.getPostalCode());
result.append("\n\n");
}
addressText.setText(result.toString());
}
}
catch(IOException ex){
addressText.setText(ex.getMessage().toString());
}
}
Google API: See this api which retrun address from latitude and longitude
http://maps.googleapis.com/maps/api/geocode/json?latlng=17.734884,83.299507&sensor=true
To know more read this
getMaxAddressLineIndex() returns an index which start from zero and thus your for-loop condition should be 0 <= maxIndex instead of 0 < maxIndex
You overwrite previous address lines on every iteration by assigning display = ""; and thus will end up with the last address line only. Is that on purpose?
Another good idea is to implement the LocationListener interface and register your Activity as a listener using LocationManager requestLocationUpdates() method. You can then override onLocationUpdate() to be informed whenever the location of the device changes. You provide the requestLocationUpdates() method the minimum amount of time that must pass before you will accept another update and how far the device must move before you get an update.
You can do like this to get complete address. In case you want country name
, state etc seperately .Then, I will not prefer you this method .
public class ParentHomeActivity extends AppCompatActivity {
...
private Geocoder geocoder;
private TextView mAddressTxtVu;
...
// I assume that you got latitude and longitude correctly
mLatitude = 20.23232
mLongitude = 32.999
String errorMessage = "";
geocoder = new Geocoder(context, Locale.getDefault());
List<Address> addresses = null;
try {
addresses = geocoder.getFromLocation(
mlattitude,
mlongitude,
1);
} catch (IOException e) {
errorMessage = getString(R.string.service_not_available);
Log.e(TAG, errorMessage, e);
} catch (IllegalArgumentException illegalArgumentException) {
// Catch invalid latitude or longitude values.
errorMessage = getString(R.string.invalid_lat_long_used);
Log.e(TAG, errorMessage + ". " + "Latitude = " + mlattitude +",
Longitude = " + mlongitude, illegalArgumentException);
}
// Handle case where no address was found.
if (addresses == null || addresses.size() == 0) {
if (errorMessage.isEmpty()) {
errorMessage = getString(R.string.no_address_found);
Log.e(TAG, errorMessage);
}
} else {
Address address = addresses.get(0);
ArrayList<String> addressFragments = new ArrayList<String>();
// Fetch the address lines using getAddressLine,
// join them, and send them to the thread.
for (int i = 0; i <= address.getMaxAddressLineIndex(); i++) {
addressFragments.add(address.getAddressLine(i));
}
// Log.i(TAG, getString(R.string.address_found));
mAddressTxtVu.setText(TextUtils.join(System.getProperty("line.separator"),
addressFragments));
}