Android: App crashes while entering invalid location - android

In my app, I have to find whether a given location comes under a specified area. I am taking Connaught Place, New Delhi as center point. and I got the addresses which come under area of 200 miles from center point. But, if I enter any invalid location, like "abcdfdfkc", the app crashes, because it is trying to find coordinates of this location and I want to avoid this.
Below I am posting the code:
public static boolean isServicedLocation(Context _ctx, String strAddress){
boolean isServicedLocation = false;
Address sourceAddress = getAddress(_ctx, "Connaught Place, New Delhi, India");
Location sourceLocation = new Location("");
sourceLocation.setLatitude(sourceAddress.getLatitude());
sourceLocation.setLongitude(sourceAddress.getLongitude());
Address targetAddress = getAddress(_ctx, strAddress);
Location targetLocation = new Location("");
if (targetLocation != null) {
targetLocation.setLatitude(targetAddress.getLatitude());
targetLocation.setLongitude(targetAddress.getLongitude());
float distance = Math.abs(sourceLocation.distanceTo(targetLocation));
double distanceMiles = distance/1609.34;
isServicedLocation = distanceMiles <= 200;
//Toast.makeText(_ctx, "Distance "+distanceMiles, Toast.LENGTH_LONG).show();
}
return isServicedLocation;
}
getAddress method:
public static Address getAddress(Context _ctx, String addressStr) {
Geocoder geoCoder = new Geocoder(_ctx, Locale.getDefault());
try {
List<Address> addresses = geoCoder.getFromLocationName(addressStr,
1);
if (addresses.size() != 0) {
return addresses.get(0);
}
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}

It's because when you don't find an address from the GeoCoder (ie, if addresses.size() == 0), you return null.
Then, regardless of that, you dereference the value, which is what's crashing your app.
Address targetAddress = getAddress(_ctx, strAddress);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
:
if (targetLocation != null) {
targetLocation.setLatitude(targetAddress.getLatitude());
^^^^^^^^^^^^^
You should probably also be checking targetAddress for null to avoid this (either in addition to (likely), or instead of (less likely), the check of targetLocation).
So I'd be looking at changing:
if (targetLocation != null) {
into:
if ((targetLocation != null) && (targetAddress != null)) {
That way, an invalid address automatically becomes an unserviced location.

Related

how to get current Location with android studio

I want get current location then i press one button in the app but it dont give me that instead it give unknown address but if i change my location to USA it gives the address? I dont get any errors everything is working good only the address dont show up? here is my code, If you could help me I would appreciate it.
try {
Geocoder geo = new Geocoder(this.getApplicationContext(), Locale.getDefault());
List<Address> addresses = geo.getFromLocation(currentLocation.getCoordinates().latitude, currentLocation.getCoordinates().longitude, 1);
if (addresses.isEmpty()) {
autocompleteFragmentFrom.setText(R.string.waiting_for_location);
} else {
addresses.size();
if (addresses.get(0).getThoroughfare() == null) {
pickupLocation.setName(addresses.get(0).getLocality());
} else if (addresses.get(0).getLocality() == null) {
pickupLocation.setName("unknown address");
} else {
pickupLocation.setName(addresses.get(0).getLocality() + ", " + addresses.get(0).getThoroughfare());
}
autocompleteFragmentFrom.setText(pickupLocation.getName());
}
} catch (IOException e) {
e.printStackTrace();
}
}
enter image description here
After request location permission and enable GPS use FusedLocationProviderClient.
private val mFusedLocationProviderClient: FusedLocationProviderClient by lazy {
LocationServices.getFusedLocationProviderClient(requireActivity())
}
mFusedLocationProviderClient.lastLocation?.addOnSuccessListener(this) { location:Location? ->
val lat = location?.latitude
val lon = location?.longitude
}

Android Geocoder returns null city name

I am new to Android development, following is my code about use Geocoder to get city name of current location, it returns null:
private void updateCurrentLocation(Location location) {
double lat = 0.0, lng = 0.0;
if (location != null) {
lat = location.getLatitude();
lng = location.getLongitude();
Log.i("tag", "Latitute is" + lat + ", Longtitute is" + lng);
} else {
City_Name = "Unavailable";
}
List<Address> list = null;
Geocoder geocoder = new Geocoder(this.getActivity());
try {
list = geocoder.getFromLocation(lat, lng, 1);
} catch (IOException e) {
e.printStackTrace();
}
//may provide multiple locations.
if (list != null && list.size() > 0) {
Address address = list.get(0);
City_Name = address.getLocality();
}
Log.i("Try", "CityName:" + City_Name);
//send empty message
handler.sendEmptyMessage(1);
}
I opened GPS services, add ACCESS_FINE_LOCATION and INTERNET permission in Manifest already. Also, I searched similar questions in Stackoverflow about Geocoder returns null, but haven't found useful solutions. One of them is analyze JSON from Geocoder website, but it doesn't work either.
Can anyone help with this? Thank you!
BTW, is there any better solution to receive a city name? Thank you!
If the "getFromLocation" method gives you an empty set then it's because the server that is being looked up doesn't have the address information for the coordinates you're passing it. This is also noted in the docs. So I think that you should let it go and use another service like the Google Maps geocoding service or another one like Nominatim from the OpenStreetMap project.

App Crashes when entering invalid or null location using geocoder

I have been working on google maps and want the user can access location using geocoding, although it is working but the problem arises when the user enters invalid location or null location in edit text, my app gets crashed.
This is my code: (on search button click)
public void onSearch(View view) {
EditText addressSearch = (EditText) findViewById(R.id.edtSearchAddress);
String location = addressSearch.getText().toString();
List<Address> addressList = null;
if (location != null || !location.equals("")) {
addressSearch.setText("");
Geocoder geocoder = new Geocoder(this, Locale.getDefault());
try {
addressList= geocoder.getFromLocationName(location, 7);
} catch (IOException e) {
e.printStackTrace();
}
// location exists
Address address = addressList.get(0);
LatLng latLng = new LatLng(address.getLatitude(), address.getLongitude());
map.addMarker(new MarkerOptions().position(latLng).title("Find Pro"));
map.animateCamera(CameraUpdateFactory.newLatLng(latLng));
} else {
addressSearch.setText("Location does not exist");
}
}
Your kind support will be appreciated.
According to documentation the call of geocoder.getFromLocationName can throw IllegalArgumentException or return empty list. Both cases will crash your app. My bet the list is empty.
So guard your code:
if (addressList.size() > 0) {
Address address = addressList.get(0);
LatLng latLng = new LatLng(address.getLatitude(), address.getLongitude());
map.addMarker(new MarkerOptions().position(latLng).title("Find Pro"));
map.animateCamera(CameraUpdateFactory.newLatLng(latLng));
}
when you pass null value that time addressList return 0 value so please set IF condition before get value from addressList.
if (addressList.size() > 0) {
Address address = addressList.get(0);
}

After a period of time address researching doesn't generate results. java.io.IOException: Service not Available

I have a big problem.
I wrote this code that get Address informations relating to coordinates:
public static Address getAddressFromLocation(Context c, Location location){
Address address = null;
if(location!=null){
final Double addrLat=location.getLatitude();
final Double addrLng=location.getLongitude();
final Geocoder geocoder = new Geocoder(c, Locale.getDefault());
try {
List<Address> addresses = geocoder.getFromLocation(getRound(addrLat, 15), getRound(addrLng, 15), 1);
if (addresses.size() > 0) {
Address returnedAddress = addresses.get(0);
Locale locale = returnedAddress.getLocale();
address = new Address(locale);
address = returnedAddress;
if(address.getLocality()==null || address.getLocality().equals("")){
int line = address.getMaxAddressLineIndex()-1;
if(line<0)line=0;
address.setLocality(address.getAddressLine(line));
}
}else{
address=null;
}
}catch (IOException e) {
address=null;
}
}else{
address=null;
}
return address;
}
After performing the search several times I get no Address and I don't understand why.
I can restart the device or do a search after a period of time and I'm not able to find any Address anymore.
The error is:
java.io.IOException: Service not Available
Which is the problem?

Android: Reverse geocoding - getFromLocation

I am trying to get an address based on the long/lat. it appears that something like this should work?
Geocoder myLocation = Geocoder(Locale.getDefault());
List myList = myLocation.getFromLocation(latPoint,lngPoint,1);
The issue is that I keep getting : The method Geocoder(Locale) is undefined for the type savemaplocation
Any assistance would be helpful. Thank you.
Thanks, I tried the context, locale one first, and that failed and was looking at some of the other constructors (I had seen one that had mentioned just locale). Regardless,
It did not work, as I am still getting : The method Geocoder(Context, Locale) is undefined for the type savemaplocation
I do have : import android.location.Geocoder;
The following code snippet is doing it for me (lat and lng are doubles declared above this bit):
Geocoder geocoder = new Geocoder(this, Locale.getDefault());
List<Address> addresses = geocoder.getFromLocation(lat, lng, 1);
Here is a full example code using a Thread and a Handler to get the Geocoder answer without blocking the UI.
Geocoder call procedure, can be located in a Helper class
public static void getAddressFromLocation(
final Location location, final Context context, final Handler handler) {
Thread thread = new Thread() {
#Override public void run() {
Geocoder geocoder = new Geocoder(context, Locale.getDefault());
String result = null;
try {
List<Address> list = geocoder.getFromLocation(
location.getLatitude(), location.getLongitude(), 1);
if (list != null && list.size() > 0) {
Address address = list.get(0);
// sending back first address line and locality
result = address.getAddressLine(0) + ", " + address.getLocality();
}
} catch (IOException e) {
Log.e(TAG, "Impossible to connect to Geocoder", e);
} finally {
Message msg = Message.obtain();
msg.setTarget(handler);
if (result != null) {
msg.what = 1;
Bundle bundle = new Bundle();
bundle.putString("address", result);
msg.setData(bundle);
} else
msg.what = 0;
msg.sendToTarget();
}
}
};
thread.start();
}
Here is the call to this Geocoder procedure in your UI Activity:
getAddressFromLocation(mLastKownLocation, this, new GeocoderHandler());
And the handler to show the results in your UI:
private class GeocoderHandler extends Handler {
#Override
public void handleMessage(Message message) {
String result;
switch (message.what) {
case 1:
Bundle bundle = message.getData();
result = bundle.getString("address");
break;
default:
result = null;
}
// replace by what you need to do
myLabel.setText(result);
}
}
Don't forget to put the following permission in your Manifest.xml
<uses-permission android:name="android.permission.INTERNET" />
It looks like there's two things happening here.
1) You've missed the new keyword from before calling the constructor.
2) The parameter you're passing in to the Geocoder constructor is incorrect. You're passing in a Locale where it's expecting a Context.
There are two Geocoder constructors, both of which require a Context, and one also taking a Locale:
Geocoder(Context context, Locale locale)
Geocoder(Context context)
Solution
Modify your code to pass in a valid Context and include new and you should be good to go.
Geocoder myLocation = new Geocoder(getApplicationContext(), Locale.getDefault());
List<Address> myList = myLocation.getFromLocation(latPoint, lngPoint, 1);
Note
If you're still having problems it may be a permissioning issue. Geocoding implicitly uses the Internet to perform the lookups, so your application will require an INTERNET uses-permission tag in your manifest.
Add the following uses-permission node within the manifest node of your manifest.
<uses-permission android:name="android.permission.INTERNET" />
The reason for this is the non-existent Backend Service:
The Geocoder class requires a backend service that is not included in the core android framework. The Geocoder query methods will return an empty list if there no backend service in the platform.
First get Latitude and Longitude using Location and LocationManager class. Now try the code below for Get the city,address info
double latitude = location.getLatitude();
double longitude = location.getLongitude();
Geocoder gc = new Geocoder(this, Locale.getDefault());
try {
List<Address> addresses = gc.getFromLocation(lat, lng, 1);
StringBuilder sb = new StringBuilder();
if (addresses.size() > 0) {
Address address = addresses.get(0);
for (int i = 0; i < address.getMaxAddressLineIndex(); i++)
sb.append(address.getAddressLine(i)).append("\n");
sb.append(address.getLocality()).append("\n");
sb.append(address.getPostalCode()).append("\n");
sb.append(address.getCountryName());
}
City info is now in sb. Now convert the sb to String (using sb.toString() ).
Well, I am still stumped. So here is more code.
Before I leave my map, I call SaveLocation(myMapView,myMapController); This is what ends up calling my geocoding information.
But since getFromLocation can throw an IOException, I had to do the following to call SaveLocation
try
{
SaveLocation(myMapView,myMapController);
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
Then I have to change SaveLocation by saying it throws IOExceptions :
public void SaveLocation(MapView mv, MapController mc) throws IOException{
//I do this :
Geocoder myLocation = new Geocoder(getApplicationContext(), Locale.getDefault());
List myList = myLocation.getFromLocation(latPoint, lngPoint, 1);
//...
}
And it crashes every time.
Use this
Geocoder geocoder = new Geocoder(this, Locale.getDefault());
List<Address> addresses = geocoder.getFromLocation(lat, lng, 1);

Categories

Resources