I'm attempting to extract the City and State only from the Geocoder in Android. I've gotten pretty far to where it extracts the city fine, but the state I'm having issues with its printing the zip along side it.
I'm looking for "City, State" whereas the final output now is "City, State Zip"
Any ideas?
Geocoder geoCoder = new Geocoder(getActivity(), Locale.getDefault());
List<Address> addresses;
try {
addresses = geoCoder.getFromLocation(mLatitude, mLongitude, 10);
int i=1;
for(Address addObj:addresses)
{
// Looping once
if(i==1)
{
String add_line1_extract;
add_line1_extract=addObj.getAddressLine(1);
String string = add_line1_extract;
String[] parts = string.split(",");
//Setting city
mCity = parts[0];
//setting state
mState = parts[1];
// Final Output
String cityAndState = mCity + ", " + mState;
i++;
}
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
You could get the state name by calling the getAdminArea() method from Address class. However, it might not work for all the countries. Also, you could call the getLocality() to retrieve the city name.
So for your code, you can do the following:
String cityName = addObject.getLocality();
String stateName = addObject.getAdminArea();
String cityAndState = cityName + ", " + stateName;
If you want the abbreviation of a state name, you can do further split in your String[] parts. You can do the following:
String[] moreSplit = parts[1].split(" ");
String mStateAbbr = moreSplit[0];
String mCityAndStateAbbr = mCity + mStateAbbr;
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 have found this solution: here to get the location name but I don't know how to display it in my textView:
LocationManager locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
String provider = locationManager.getBestProvider(new Criteria(), true);
Location locations = locationManager.getLastKnownLocation(provider);
List<String> providerList = locationManager.getAllProviders();
if(null!=locations && null!=providerList && providerList.size()>0){
double longitude = locations.getLongitude();
double latitude = locations.getLatitude();
Geocoder geocoder = new Geocoder(getApplicationContext(), Locale.getDefault());
try {
List<Address> listAddresses = geocoder.getFromLocation(latitude, longitude, 1);
if(null!=listAddresses&&listAddresses.size()>0){
String _Location = listAddresses.get(0).getAddressLine(0);
}
} catch (IOException e) {
e.printStackTrace();
t.append("\n " + ????? + " ");
}
}
The t is the textView
You have the name address in the String _Location. Therefore, you could set the value of TextView in the try block.
try {
List<Address> listAddresses = geocoder.getFromLocation(latitude, longitude, 1);
if(null!=listAddresses&&listAddresses.size()>0){
String _Location = listAddresses.get(0).getAddressLine(0);
}
t.setText(_Location);
}
Further Infomation
String address1 = listAddresses.get(0).getAddressLine(0);
String city = listAddresses.get(0).getLocality();
String state = listAddresses.get(0).getAdminArea();
String country = listAddresses.get(0).getCountryName();
String postalCode = listAddresses.get(0).getPostalCode();
String knownName = listAddresses.get(0).getFeatureName();
t.setText(address1 + " " + city + "\n" + state + " " + postalCode);
You could use this code to get further information about the adress
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();
}
}
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();
}
I need to add to my application a text box where I type address (street, city) and then app will displayed markers fulfilling this criteria. Any ideas or tutorials? My markers have adress written in snippet. Sorry for my poor english.
First pass address from text box to given method below which will give you latitude and longitude of that address and through this latitude and longitude you can place the marker on map.
//----Coding to get latitude and longitude from address----
private void searchFromLocationName(String name){
try {
Geocoder myGeocoder = new Geocoder(this);
List<Address> result = myGeocoder.getFromLocationName(name, 5);
if ((result == null)||(result.isEmpty()))
{
Toast.makeText(MapsActivity.this, "Sorry!No matches were found",Toast.LENGTH_LONG).show();
}
else{
String stringResult = "";
for (int i =0; i < result.size(); i++){
stringResult += "latitude: " + result.get(i).getLatitude() + "\n"
+ "longitude: " + result.get(i).getLongitude() + "\n";
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
And to show address on snippet:-
overlayItemsList.add(new OverlayItem(geoPoint, title, address));
Keep all your Markers in ArrayList<Marker> then loop over them and change visibility.
for (Marker marker : allMarkers) {
String snippet = marker.getSnippet();
boolean match = snippet.contains(myText);
marker.setVisible(match);
}