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.
Related
I created a seperate activity to create a Google Map and set a marker on the users current location. In another fragment class, I'd like to set the text of a text view to the location from the map activity.
CheckInFragment
mLocation = (TextView) v.findViewById(R.id.checkin_location_text);
mLocation.setText();
MapsActivity
private void handleNewLocation(Location location){
//SET THESE TWO VARIABLES TO THE TEXT vv
double currentLatitude = location.getLatitude();
double currentLongitude = location.getLongitude();
LatLng latLng = new LatLng(currentLatitude, currentLongitude);
MarkerOptions options = new MarkerOptions()
.position(latLng)
.title("Check In Location");
mMap.addMarker(options);
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
float zoomLevel = 16.0f;
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, zoomLevel));
}
You can try below code to get the string value of location:
Geocoder geocoder = new Geocoder(getApplicationContext(), Locale.getDefault());
try {
List<Address> addressList = geocoder.getFromLocation(location.getLatitude(),
location.getLongitude(), 1);
String fullAddress = "";
if (addressList != null && addressList.size() > 0) {
if (addressList.get(0).getAddressLine(0) != null) {
fullAddress += addressList.get(0).getAddressLine(0) + " ";
}
if (addressList.get(0).getSubAdminArea() != null) {
fullAddress += addressList.get(0).getSubAdminArea() + " ";
}
} else {
Log.d("Address:", "Couldn't find Address");
}
} catch (IOException e) {
e.printStackTrace();
}
Then you can pass the fullAddress string value in a bundle when calling the your fragment class, something like:
YourFragment fragment = new YourFragment();
Bundle args = new Bundle();
args.putString("location_string", fullAddress);
fragment.setArguments(args);
Finally in onCreate method of your Fragment class fetch the string value as below:
if (getArguments() != null)
{
_location = getArguments().getString("location_string");
}
Hope this helps!!!
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());
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();
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")
I am trying to pass geocoder values from MapFragment to LocationDetailsActivity.
I get the correct values for lat and lng, but when I try to display any of the other values, most of the times I get null values instead of the city and zip (but not always), while a lot of the times I get the correct country and state (also not always).
MapFragment Code:
// Set default latitude and longitude
double latitude = 15.4825766;
double longitude = -5.0076589;
// Get latitude and longitude of the current location and a LatLng object
if (myLocation != null) {
latitude = myLocation.getLatitude();
longitude = myLocation.getLongitude();
}
mMap.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
#Override
public void onMapLongClick(LatLng arg0) {
Geocoder geocoder = new Geocoder(getActivity(), Locale.getDefault());
try {
List<Address> allAddresses = geocoder.getFromLocation(arg0.latitude, arg0.longitude, 1);
if (allAddresses.size() > 0 && allAddresses != null) {
Address address = allAddresses.get(0);
Intent intent = new Intent(getActivity(), LocationDetailsActivity.class);
intent.putExtra("latitude", arg0.latitude);
intent.putExtra("longitude", arg0.longitude);
intent.putExtra("city", allAddresses.get(0).getLocality());
intent.putExtra("zip", allAddresses.get(0).getPostalCode());
intent.putExtra("state", allAddresses.get(0).getAdminArea());
intent.putExtra("country", allAddresses.get(0).getCountryName());
startActivity(intent);
}
} catch (IOException e) {
e.printStackTrace();
}
}
});
LocationDetailsActivity Code:
Bundle bundle = getIntent().getExtras();
double lat = bundle.getDouble("latitude");
double lng = bundle.getDouble("longitude");
String city = intent.getStringExtra("city");
String zip = intent.getStringExtra("zip");
String state = intent.getStringExtra("state");
String country = intent.getStringExtra("country");
// I display my values here
mFirstValueDisplay.setText(String.valueOf(city));
mSecondValueDisplay.setText(String.valueOf(zip));
Android's geocoding api is pretty unreliable up-to my experience, I usually make a request to the Google's geocoding webservices on Url : "https://maps.googleapis.com/maps/api/geocode"
(If you are familiar with retrofit)
#GET("/json")
void reverseGeoCode(#Query("latlng") String latlng, #Query("language") String language,
#Query("key") String key, Callback<ReverseGeoCode> callback);
latlng The latitude and longitude you want to reverse geocode.
language language of the geocoded response
key Your Api key
Go here for more info
Geocoder often got the values right, but more often than not I got null values. Based on #insomniac's advice I modified my code:
public void onMapLongClick(final LatLng arg0) {
RequestQueue queue = Volley.newRequestQueue(getActivity());
String url = "https://maps.googleapis.com/maps/api/geocode/json?latlng=" + String.valueOf(arg0.latitude) + "," + String.valueOf(arg0.longitude) + "&key=myKeyCode";
// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONArray jObj = new JSONObject(response).getJSONArray("results").getJSONObject(0).getJSONArray("address_components");
Intent intent = new Intent(getActivity(), LocationDetailsActivity .class);
for (int i = 0; i < jObj.length(); i++) {
String componentName = new JSONObject(jObj.getString(i)).getJSONArray("types").getString(0);
if (componentName.equals("postal_code") || componentName.equals("locality")) {
intent.putExtra(componentName, new JSONObject(jObj.getString(i)).getString("short_name"));
}
}
intent.putExtra("latitude", arg0.latitude);
intent.putExtra("longitude", arg0.longitude);
startActivity(intent);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
int x = 1;
}
});
// Add the request to the RequestQueue.
queue.add(stringRequest);
It still displays some areas as null. But those are smaller areas. Hope someone finds it helpful.