Reverse GeoCoding Android Issue - java

I'm having trouble converting coordinates to an actual address.
I have two variables that pull coordinates but I'm getting many errors when I tweak the code. The first error is "unreported exception IOException; must be caught or declared to be thrown" and then I add the try catch then another error pops up, "yourAddresses might not have been initialized.
I'm just trying to get the address, street, and city so I can append it into a textView.
#Override
public void onLocationChanged(Location location)
{
double latitude = location.getLongitude();
double longitude = location.getLatitude();
//t.append("\n " + location.getLongitude() + " " + location.getLatitude());
Geocoder geocoder;
List<Address> yourAddresses;
geocoder = new Geocoder(context, Locale.getDefault());
yourAddresses = geocoder.getFromLocation(latitude, longitude, 1);
if (yourAddresses.size() > 0) {
String yourAddress = yourAddresses.get(0).getAddressLine(0);
String yourCity = yourAddresses.get(0).getAddressLine(1);
String yourCountry = yourAddresses.get(0).getAddressLine(2);
}
}
Thanks!

I used this code and its works for me....
public void getAddressFromLocation(final double latitude, final double longitude,
final Context context, final Handler handler)
{
Thread thread = new Thread()
{
#Override
public void run()
{
Geocoder geocoder = new Geocoder(context, Locale.getDefault());
String result = null;
Address address = null;
try
{
List<Address> addressList = geocoder.getFromLocation(latitude, longitude, 1);
if (addressList != null && addressList.size() > 0)
{
address = addressList.get(0);
}
}
catch (Exception e)
{
Log.e(TAG, "getAddressFromLocation:run: exception while getting address from location");
e.printStackTrace();
}
finally
{
Message message = Message.obtain();
message.setTarget(handler);
if (address != null)
{
message.what = 1;
Bundle bundle = new Bundle();
bundle.putString("thoroughFare", address.getThoroughfare());
bundle.putString("subThoroughFare", address.getSubThoroughfare());
bundle.putString("city", address.getLocality());
bundle.putString("state", address.getAdminArea());
bundle.putString("country", address.getCountryName());
bundle.putString("postalCode", address.getPostalCode());
bundle.putString("subAdminArea", address.getSubAdminArea());
bundle.putString("subLocality", address.getSubLocality());
message.setData(bundle);
}
else
{
message.what = 1;
Bundle bundle = new Bundle();
result = "Latitude: " + latitude + "Longitude: " + longitude +
"\n Unable to get address for this location.";
bundle.putString("address", result);
message.setData(bundle);
}
message.sendToTarget();
}
}
};
thread.start();
}
This is my GeoCoderHandler class....
private class GeoCoderHandler extends Handler
{
#Override
public void handleMessage(Message msg)
{
switch (msg.what)
{
case 1:
String address = "";
Bundle bundle = msg.getData();
if (bundle.getString("subThoroughFare") != null)
{
if (!bundle.getString("subThoroughFare").equalsIgnoreCase("null"))
{
address = bundle.getString("subThoroughFare") + ", " +
bundle.getString("thoroughFare");
}
}
else
{
address = bundle.getString("thoroughFare");
}
tvAddress1.setText("");
tvAddress1.setText(address);
tvAddress2.setText("");
tvAddress2.setText(bundle.getString("subLocality"));
tvAddress3.setText("");
tvAddress3.setText(bundle.getString("subAdminArea"));
edtPinCode.setText("");
edtPinCode.setText(bundle.getString("postalCode"));
tvCity.setText("");
tvCity.setText(bundle.getString("city"));
tvState.setText("");
tvState.setText(bundle.getString("state"));
tvCountry.setText("");
tvCountry.setText(bundle.getString("country"));
break;
default:
tvAddress1.setText(getResources().getString(R.string.address_not_found));
tvAddress2.setText("");
tvAddress3.setText("");
edtPinCode.setText("");
tvCity.setText("");
tvState.setText("");
tvCountry.setText("");
break;
}
}
}

your need some initialized for yourAddress
List<Address> yourAddresses = new ArrayList();

Related

How to restrict to particular city results using Places API android

I had a requirement that if suppose the city is Hyderabad then using places search API I need to get only Hyderabad places while searching. But I am getting only a few places in search. how to get all the places related to Hyderabad city. Please anyone can help me out.
I have tried the code:
if (!Places.isInitialized()) {
Places.initialize(getApplicationContext(), "apikey");
}
final AutocompleteSupportFragment autocompleteFragment = (AutocompleteSupportFragment)
getSupportFragmentManager().findFragmentById(R.id.autofill);
autocompleteFragment.setCountry("IN");
final Button closeBtn = dialog.findViewById(R.id.close_btn);
dialog.show();
autocompleteFragment.setLocationRestriction(RectangularBounds.newInstance(
new LatLng(17.387140, 78.491684),
new LatLng(17.440081, 78.348915)));
autocompleteFragment.setPlaceFields(Arrays.asList(Place.Field.ID, Place.Field.NAME, Place.Field.ADDRESS, Place.Field.LAT_LNG));
autocompleteFragment.setTypeFilter(TypeFilter.ADDRESS);
autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
#Override
public void onPlaceSelected(Place place) {
// TODO: Get info about the selected place.
if (place.getAddress() != null) {
Log.e("Place", "Place: " + place.getName() + ", " + place.getId() + " , " + place.getAddress() + " , " + place.getLatLng());
// progressDialog.show();
// progressDialog.setCancelable(false);
double latitude = Objects.requireNonNull(place.getLatLng()).latitude;
Log.d("lat:", String.valueOf(latitude));
double longitude = place.getLatLng().longitude;
Log.d("lng:", String.valueOf(longitude));
String name = place.getName();
Geocoder geocoder = new Geocoder(PlacesSearch.this, Locale.getDefault());
List<Address> addresses = null;
try {
addresses = geocoder.getFromLocation(latitude, longitude, 1);
} catch (IOException e) {
e.printStackTrace();
}
String aa = addresses.get(0).getAddressLine(0);
Log.e("aa:", aa);
String[] ad = aa.split(",");
String street = ad[0] + "," + ad[1] + "," + ad[2];
String city1 = addresses.get(0).getLocality();
String state1 = addresses.get(0).getAdminArea();
String zip1 = addresses.get(0).getPostalCode();
String country1 = addresses.get(0).getCountryName();
String countryCode = addresses.get(0).getCountryCode();
System.out.println("countryCode"+countryCode);
placesearch.setText(aa);
// progressDialog.dismiss();
dialog.dismiss();
}
}
#Override
public void onError(Status status) {
// TODO: Handle the error.
Log.e("Place", "An error occurred: " + status);
}
});

Android - Static Nested Class (context)

I've a static AsyncTask and i need to get context, what can i do to get it?
I tried using WeakReference, example:
private WeakReference<ScanActivity> activityReference;
FetchPositionAsyncTask(ScanActivity context) {
activityReference = new WeakReference<>(context);
}
But Android Studio says:
Geocoder (android.content.Context, Locale) in Geocoder cannot be applied to (java.lang.ref.WeakReference, Locale)
This is my code:
private static class FetchPositionAsyncTask extends AsyncTask<String, Void, String> {
private WeakReference<ScanActivity> activityReference;
FetchPositionAsyncTask(ScanActivity context) {
activityReference = new WeakReference<>(context);
}
#Override
protected String doInBackground(String... params) {
return null;
}
protected void onPostExecute(String result) {
//TODO da mettere in doInBackground
final AlertDialog.Builder builder;
//GET ADDRESS FROM COORDINATES
Geocoder geocoder = new Geocoder(activityReference, Locale.getDefault());
try {
DATA_LOCALITY = geocoder.getFromLocation(latitude, longitude, 1);
} catch (IOException e) {
e.printStackTrace();
}
String DATA_ADDRESS = DATA_LOCALITY.get(0).getAddressLine(0);
//TEST
builder = new AlertDialog.Builder(activityReference.this);
builder.setTitle("").setMessage("Latitude: " + latitude + " " + "Longitude: " + longitude + " " + "Accuracy: " + accuracy + " " + "Address: " + DATA_ADDRESS).setNeutralButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}).show().setCanceledOnTouchOutside(false);
}
}
Here is how I set the code:
Geocoder geocoder = new Geocoder(activityReference, Locale.getDefault());
builder = new AlertDialog.Builder(activityReference);
You need to use activityReference.get() to use the Context from your reference variable.
WeakReference<ScanActivity> and ScanActivity are different, you should use the real object using activityReference.get() and pass it to Geocoder. I.e.
Geocoder geocoder = new Geocoder(activityReference.get(), Locale.getDefault());

Geocoder is not working in android above kitkat version

I was working with geocoder in my android app to get country name using latitude and longitude. I found that it was working good in kitkat version and below. But when i test my app in above versions it was giving null. So my question is simple that how to use geocoder above kitkat versions.
If there is any other better option instead of geocoder then please suggest me!
Thanks in advance!
I post my code for Geocoder. Follow it
//Keep this GeocodingLocation.java in a separate file.
public class GeocodingLocation {
private static final String TAG = "GeocodingLocation";
public static void getAddressFromLocation( final String locationAddress,
final Context context, final Handler handler) {
Thread thread = new Thread() {
#Override
public void run() {
Geocoder geocoder = new Geocoder(context, Locale.getDefault());
String result = null;
String latitude = null;
String longitude = null;
try {
List<Address> addressList = geocoder.getFromLocationName(locationAddress, 1);
if (addressList != null && addressList.size() > 0) {
Log.e("GeocodingLocation --> getAddressFromLocation ==>" +
addressList.toString());
Address address = (Address) addressList.get(0);
StringBuilder sb = new StringBuilder();
latitude = String.valueOf(address.getLatitude());
longitude = String.valueOf(address.getLongitude());
Logger.infoLog("GeocodingLocation --> Lat & Lang ==>" + latitude +" "+longitude);
//sb.append(address.getLatitude()).append("\n");
//sb.append(address.getLongitude()).append("\n");
}
} catch (IOException e) {
Log.e(TAG, "Unable to connect to Geocoder", e);
} finally {
Message message = Message.obtain();
message.setTarget(handler);
if (latitude != null && longitude != null) {
message.what = 1;
Bundle bundle = new Bundle();
bundle.putString("latitude", latitude);
bundle.putString("longitude", longitude);
message.setData(bundle);
} else {
message.what = 1;
Bundle bundle = new Bundle();
result = "Address: " + locationAddress +
"\n Unable to get Latitude and Longitude for this address location.";
bundle.putString("address", result);
message.setData(bundle);
}
message.sendToTarget();
}
}
};
thread.start();
}
}
call the class from your fragment.
private void getAddressLatitudeLongitude(String branchAddress) {
Log.e("getAddressLatitudeLongitude ==>" + branchAddress);
GeocodingLocation.getAddressFromLocation(branchAddress, thisActivity, new GeocoderHandler());
}
Keep this class as inner class in same fragment
private class GeocoderHandler extends Handler {
#Override
public void handleMessage(Message message) {
switch (message.what) {
case 1:
try {
Bundle bundle = message.getData();
latitude = bundle.getString("latitude");
longitude = bundle.getString("longitude");
Log.e("CreateBranch --> GeocoderHandler ==>" + latitude + " " + longitude);
}catch (Exception e){
e.printStackTrace();
}
break;
default:
latitude = null;
longitude = null;
}
latitudeList.add(latitude);
longitudeList.add(longitude);
if(latitude==null || longitude==null){
showAlertDialog("Please enter correct address", Constants.APP_NAME);
}
Log.e("Latitude list =>" + latitudeList);
Log.e("Longitude list =>" + longitudeList);
}
}
Output will get latitude and longitude. Hope this answer helps.

Android Geocoder

In my android application I do reverse Geocode (address from latitude and longitude) . My layout display 9 addresses from Geocoder, but sometimes from start activity to display adresses it takes 15 seconds. How to make it faster? Here is my one method (one of nine) to get one address:
public void aktualizujRynek() {
Thread thread1 = new Thread(new Runnable() {
public void run() {
HttpURLConnection connection = null;
try {
URL myUrl = new URL("http://......http request....................");
connection = (HttpURLConnection) myUrl.openConnection();
InputStream iStream = connection.getInputStream();
final String fResponse = IOUtils.toString(iStream);
final TextView fView = (TextView) findViewById(R.id.button8);
fView.post(new Runnable() {
#Override
public void run() {
// fView.setText("RESPONSE" + fResponse);
}
});
final boolean post = fView.post(new Runnable() {
#Override
public void run() {
//parse
JSONObject root = null;
try {
root = new JSONObject(fResponse);
} catch (JSONException e) {
e.printStackTrace();
}
try {
//Lat Lon
String Lat = root.getString("Lat");
double Lat_double = Double.parseDouble(Lat);
String Lon = root.getString("Lon");
double Lon_double = Double.parseDouble(Lon);
//not current measurement
String epoch_czujnik = root.getString("Epoch");
long epoch_czujnik_long = Long.parseLong(epoch_czujnik); //czas ostatniego odczytu
long epoch = System.currentTimeMillis() / 1000; //current time
long roznica1 = epoch - epoch_czujnik_long;
//lokalizacja ze współrzędnych
Geocoder geocoder;
List < Address > addresses;
geocoder = new Geocoder(MainActivity.this, Locale.getDefault());
addresses = geocoder.getFromLocation(Lat_double, Lon_double, 1);
String address = addresses.get(0).getAddressLine(0);
String firstWords = address.substring(0, address.lastIndexOf(" "));
String city = addresses.get(0).getLocality();
//localization
if (roznica1 > 7200) {
String komunikat = "(czujnik nie działa)";
if (city.equals(firstWords)) {
final TextView fView102 = (TextView) findViewById(R.id.button8);
fView102.setText(city + System.getProperty("line.separator") + komunikat);
} else {
final TextView fView102 = (TextView) findViewById(R.id.button8);
fView102.setText(city + System.getProperty("line.separator") + firstWords + System.getProperty("line.separator") + komunikat);
}
} else {
if (city.equals(firstWords)) {
final TextView fView102 = (TextView) findViewById(R.id.button8);
fView102.setText(city);
} else {
final TextView fView102 = (TextView) findViewById(R.id.button8);
fView102.setText(city + System.getProperty("line.separator") + firstWords);
}
}
//color
String kolor = root.getString("Color");
TextView test = (TextView) findViewById(R.id.button8);
if (roznica1 > 7200) {
test.setBackgroundColor(Color.parseColor("#b3b3b3"));
} else {
test.setBackgroundColor(Color.parseColor(kolor));
}
//IJP
String ijp1 = root.getString("IJP");
} catch (JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//end parse
}
});
} catch (MalformedURLException ex) {
Log.e(TAG, "Invalid URL", ex);
} catch (IOException ex) {
Log.e(TAG, "IO / Connection Error", ex);
} finally {
if (connection != null)
connection.disconnect();
}
}
});
thread1.start();
}

How to pass onReceived data between classes Android

I have 2 different class, first class Tracking.java and second class ReportingService.java. how to passing location address on ReportingService.java to Tracking.java?
private void doLogout(){
Log.i(TAG, "loginOnClick: ");
//ReportingService rs = new ReportingService();
//rs.sendUpdateLocation(boolean isUpdate, Location);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(NetHelper.getDomainAddress(this))
.addConverterFactory(ScalarsConverterFactory.create())
.build();
ToyotaService toyotaService = retrofit.create(ToyotaService.class);
// caller
Call<ResponseBody> caller = toyotaService.logout("0,0",
AppConfig.getUserName(this),
"null");
// async task
caller.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
Log.i(TAG, "onResponse: "+response.body().string());
}catch (IOException e){}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e(TAG, "onFailure: ", t);
}
});
AppConfig.saveLoginStatus(this, AppConfig.LOGOUT);
AppConfig.storeAccount(this, "", "");
Intent intent = new Intent(this, Main2Activity.class);
startActivity(intent);
finish();
}
This code for location address
Call<ResponseBody> caller = toyotaService.logout("0,0",
AppConfig.getUserName(this),
"null");
And this is class ReportingService.java location of code get longtitude, latitude and location address from googlemap
private void sendUpdateLocation(boolean isUpdate, Location location) {
Log.i(TAG, "onLocationChanged "+location.getLongitude());
Geocoder geocoder;
List<Address> addresses;
geocoder = new Geocoder(this, Locale.getDefault());
String street = "Unknown";
try {
addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
if (addresses != null) {
String address = addresses.get(0).getAddressLine(0);
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 knowName = addresses.get(0).getFeatureName();
street = address + " " + city + " " + state + " " + country + " " + postalCode + " " + knowName;
Log.i(TAG, "street "+street);
}
} catch (IOException e) {
e.printStackTrace();
}
if (isUpdate)
NetHelper.report(this, AppConfig.getUserName(this), location.getLatitude(),
location.getLongitude(), street, new PostWebTask.HttpConnectionEvent() {
#Override
public void preEvent() {
}
#Override
public void postEvent(String... result) {
try {
int nextUpdate = NetHelper.getNextUpdateSchedule(result[0]); // in second
Log.i(TAG, "next is in " + nextUpdate + " seconds");
if (nextUpdate > 60) {
dismissNotification();
isRunning = false;
} else if (!isRunning){
showNotification();
isRunning = true;
}
handler.postDelayed(location_updater, nextUpdate * 1000 /*millisecond*/);
}catch (JSONException e){
Log.i(TAG, "postEvent error update");
e.printStackTrace();
handler.postDelayed(location_updater, getResources().getInteger(R.integer.interval) * 1000 /*millisecond*/);
}
}
});
else
NetHelper.logout(this, AppConfig.getUserName(this), location.getLatitude(),
location.getLongitude(), street, new PostWebTask.HttpConnectionEvent() {
#Override
public void preEvent() {
}
#Override
public void postEvent(String... result) {
Log.i(TAG, "postEvent logout "+result);
}
});
}
Thanks
Use this library and follow the provided example inside it.
Its for passing anything you wish to anywhere you wish.
i think just using an interface will solve your problem.
pseudo code
ReportingException.java
add this
public interface myLocationListner{
onRecievedLocation(String location);
}
private myLocationListner mylocation;
//add below line where you get street address
mylocation.onRecievedLocation(street);
then implement myLocationListner in Tracking.java
there you go :)
You can use an intent:
The intent will fire the 2nd Receiver and will pass the data into that
If BroadcastReceiver:
Intent intent = new Intent();
intent.setAction("com.example.2ndReceiverFilter");
intent.putExtra("key" , ); //put the data you want to pass on
getApplicationContext().sendBroadcast(intent);
If Service:
Intent intent = new Intent();`
intent.putExtra("key" , value ); //put the data you want to pass on
startService( ReportingService.this , Tracking.class);
in Tracking.java, to retrieve the Data you passed on:
inside onReceive, put this code first
intent.getExtras().getString("key");//if int use getInt("key")

Categories

Resources