I am trying to display current loaction and longitude, latitude. I can easily fetch longitude & latitude but not able to display current location.
I am displaying my code below.
public class MainActivity extends Activity implements LocationListener{
LocationManager locationManager ;
String provider;
Context context;
#Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
if(provider!=null && !provider.equals("")){
// Get the location from the given provider
Location location = locationManager.getLastKnownLocation(provider);
locationManager.requestLocationUpdates(provider, 20000, 1, this);
if(location!=null)
{
onLocationChanged(location);
//Toast.makeText(getApplicationContext(),"Hello1",Toast.LENGTH_SHORT).show();
}
else
Toast.makeText(getBaseContext(), "Location can't be retrieved", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(getBaseContext(), "No Provider Found", Toast.LENGTH_SHORT).show();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
#Override
public void onLocationChanged(final Location location) {
// Getting reference to TextView tv_longitude
TextView tvLongitude = (TextView)findViewById(R.id.tv_longitude);
// Getting reference to TextView tv_latitude
TextView tvLatitude = (TextView)findViewById(R.id.tv_latitude);
// Setting Current Longitude
tvLongitude.setText("Longitude:" + location.getLongitude());
// Setting Current Latitude
tvLatitude.setText("Latitude:" + location.getLatitude() );
// From here i want to get the location, as i pass current longitude &
latitude here. It passes null
in address means here it executes else instead of if.
try {
Toast.makeText(getApplicationContext(),"Hello1",Toast.LENGTH_SHORT).show();
Geocoder geocoder = new Geocoder(getApplicationContext(), Locale.getDefault());
List<Address> addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
if (addresses != null ) {
Address address = addresses.get(0);
// sending back first address line and locality
String result = address.getAddressLine(0) + ", " + address.getLocality();
Toast.makeText(getApplicationContext(),"result",Toast.LENGTH_SHORT).show();
}
if (addresses.size() > 0) {
String address = "";
for (int index = 0; index < addresses.get(0).getMaxAddressLineIndex(); index++)
address += addresses.get(0).getAddressLine(index) + " ";
Toast.makeText(getApplicationContext(),"Hello",Toast.LENGTH_SHORT).show();
Log.v("AddressTag", address);
}
else
{
Toast.makeText(getApplicationContext(),"Hello2",Toast.LENGTH_SHORT).show();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
Are you sure the Geocoder is working on your device? This is what they specify in the description of Geocoder.
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. Use the isPresent() method to determine whether a Geocoder implementation exists.
This is only working on a few devices, if you really want to get the address you should use the google api. https://developers.google.com/maps/documentation/geocoding/
have you given these permissions in your manifest
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
And is your device connected to internet?
check with Geocoder.isPresent() whether geocoder is present or not
If List is empty/null I bet that you do not have a Geocode backend service to do the actual lookups. The documentation says that "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."
If you want to use the Google Maps API for reverse lookup you need to include it in your project and obtain a Maps API key. "In previous versions of the SDK, the com.google.android.maps package was included in the standard Android library and system image. In the Android 1.5 SDK, that is not the case. The Android 1.5 library and system image do not include the Maps external library (com.google.android.maps). However, the Maps external library is available as part of the Google APIs add-on for the Android SDK"
Update: Since you mention that the GeoCoder.isPresent() returns true it means that a backend service exists and the problem lies elsewhere. I had a look at the Google Maps API FAQ and it mentions that lat/long to address lookups doesn't work everywhere. Have a look at this spreadsheet and set the Geocode filter to No. Is the country you're doing lookups for listed?
Related
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.
i m using google Reverse Geocoding API in my app, i m succussfully able to get get coordinate using google geolocation API. Now i m trying to get Location Name from Reverse Geocoding API , but always returns Location not found error
here is my code:
Geocoder geocoder= new Geocoder(MainActivity.this, Locale.ENGLISH);
if(geocoder.isPresent()){
List<Address> list;
try {
list = geocoder.getFromLocation(37.42279, -122.08506,1);
Address address = list.get(0);
Log.d("this is working","thsi sis working");
StringBuffer str = new StringBuffer();
str.append("Name: " + address.getLocality() + "\n");
str.append("Sub-Admin Ares: " + address.getSubAdminArea() + "\n");
str.append("Admin Area: " + address.getAdminArea() + "\n");
str.append("Country: " + address.getCountryName() + "\n");
str.append("Country Code: " + address.getCountryCode() + "\n");;
String strAddress = str.toString();
JsonDatas.setText(strAddress);
Log.d("Address", strAddress);
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
i have several question
how google know that which app requested the API and how google determine of Quota that app. in google API developer Console, google gave Quota for app API
Why i m getting location not found error but searching on google map location is showing
do i need to add google Geocoder APi key into my app - right now i m only Geolocation API key using for retrieve Coordinates
Please correct me if i m wrong, Please give suggestion so my code will work fine
thanks
Make sure you have latest Google play library in your project. I am using this code and working for me.
private class ReverseGeocodingTask extends AsyncTask<LatLng, Void, String> {
Context mContext;
public ReverseGeocodingTask(Context context) {
super();
mContext = context;
}
// Finding address using reverse geocoding
#Override
protected String doInBackground(LatLng... params) {
Geocoder geocoder = new Geocoder(mContext);
double latitude = params[0].latitude;
double longitude = params[0].longitude;
List<Address> addresses = null;
String addressText = "";
try {
addresses = geocoder.getFromLocation(latitude, longitude, 1);
Thread.sleep(500);
if (addresses != null && addresses.size() > 0) {
Address address = addresses.get(0);
addressText = String.format(
"%s",
address.getMaxAddressLineIndex() > 0 ? address
.getAddressLine(1) : "", "", "");
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return addressText;
}
#Override
protected void onPostExecute(String addressText) {
}
}
Where LatLng is Latitude and longitute, check this for doc.
and to use write down new ReverseGeocodingTask(this).execute(latlng); where you want to get data.
Make sure you are adding permission into your manifest file.
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
OnCreateMethod,
LocationManager manager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
LocationListener listener = new LocationListener() {
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
coordinates = new GeoPoint((int)location.getLatitude(), (int)location.getLongitude()).toString();
}
};
manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener);
}
and when i try to show coordinates (setText) in a TextView, it says "null"
Android Manifest,
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
Even though my TextView displays "null", i get a notification on my status bar which says "Searching for GPS"
Here is my approach:
Always use a Asynch Task for getting Coordinates etc.
This is because GPS locking etc takes time and you don't want to bog down your main UI thread. Using a asynch task will enable you to throw a process in the background and auto update the UI field once the method has effectively executed.
Here is a code snippet: For the do in background part of the Asynch task
protected String doInBackground(Location... params) {
/*
* Get a new geocoding service instance, set for localized addresses.
* This example uses android.location.Geocoder, but other geocoders that
* conform to address standards can also be used.
*/
// Show user progress bar
pd.show();
Geocoder geocoder = new Geocoder(mContext, Locale.getDefault());
// Get the current location from the input parameter list
Location location = params[0];
// Create a list to contain the result address
List<Address> addresses = null;
// Try to get an address for the current location. Catch IO or network
// problems.
try {
/*
* Call the synchronous getFromLocation() method with the latitude
* and longitude of the current location. Return at most 1 address.
*/
addresses = geocoder.getFromLocation(location.getLatitude(),
location.getLongitude(), 1);
// Catch network or other I/O problems.
} catch (IOException exception1) {
// Log an error and return an error message
Log.e(LocationUtils.APPTAG,
mContext.getString(R.string.IO_Exception_getFromLocation));
// print the stack trace
exception1.printStackTrace();
// Return an error message
return (mContext.getString(R.string.IO_Exception_getFromLocation));
// Catch incorrect latitude or longitude values
} catch (IllegalArgumentException exception2) {
// Construct a message containing the invalid arguments
String errorString = mContext.getString(
R.string.illegal_argument_exception,
location.getLatitude(), location.getLongitude());
// Log the error and print the stack trace
Log.e(LocationUtils.APPTAG, errorString);
exception2.printStackTrace();
//
return errorString;
}
// If the reverse geocode returned an address
if (addresses != null && addresses.size() > 0) {
// Get the first address
Address address = addresses.get(0);
// Format the first line of address
addressText = mContext.getString(
R.string.address_output_string,
// If there's a street address, add it
address.getMaxAddressLineIndex() > 0 ? address
.getAddressLine(0) : "",
// Locality is usually a city
address.getLocality(),
// The country of the address
address.getCountryName());
// Return the text
return addressText;
// If there aren't any addresses, post a message
} else {
return mContext.getString(R.string.no_address_found);
}
}
After the background task has finished executing you can run a onPostExecute method.
protected void onPostExecute(String result) {
delegate.processFinished(result);
// Update the EditText on the UI Thread.
ed.setText(result);
// Hide progress bar
pd.hide();
}
In your relevant Main Class you can then call the Aysch Task and ask it to display the results.
public void getAddress(View v) {
// In Gingerbread and later, use Geocoder.isPresent() to see if a
// geocoder is available.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD
&& !Geocoder.isPresent()) {
// No geocoder is present. Issue an error message
Toast.makeText(getActivity(), R.string.no_geocoder_available,
Toast.LENGTH_LONG).show();
return;
}
if (servicesConnected()) {
// Get the current location
Location currentLocation = mLocationClient.getLastLocation();
Lat = currentLocation.getLatitude();
Lng = currentLocation.getLongitude();
LatLng = Double.toString(Lat) + "," + Double.toString(Lng);
// Message to show results
Toast.makeText(getActivity(), LatLng, 0).show();
// Turn the indefinite activity indicator on
// Start the background task
GetAddressTask getAddressTask = new GetAddressTask(getActivity(),
locationAddress, pd);
getAddressTask.delegate = this;
getAddressTask.execute(currentLocation);
} else {
Toast.makeText(getActivity(), "servicesConnected() == false",
Toast.LENGTH_SHORT).show();
}
}
Note: this is only the relevant code snippets you need. Refer to my github if you require more detailed approach. Don't forget to upvote and accept answer!
Ps:
I included a couple of pictures of an app I made to illustrate what the code can do don't worry about the map and stuff. It just shows events I have added and shared with friends who have the same app on their phone via a Google Cloud Server.
I have an activity which first uses an AsyncTask to get and parse data from a server.
The entries contain a latitude and a longitude.
Then, in onPostExecute() I load my adapter and display my listView. And in my adapter's getView() I try to display the location with the latitude and the longitude :
private String getPosition(String longitude, String latitude)
{
float lon = Float.parseFloat(longitude),
lat = Float.parseFloat(latitude);
Geocoder geocoder = new Geocoder(MyActivity.this, Locale.getDefault());
List<Address> addresses = null;
try
{
addresses = geocoder.getFromLocation(lat, lon, 1);
} catch (IOException e)
{
e.printStackTrace();
}
if(addresses == null || addresses.size() == 0) return "No location found.";
else
{
String city = addresses.get(0).getAddressLine(1);
String country = addresses.get(0).getAddressLine(2);
return (city + ", " + country.toUpperCase());
}
}
I always get "No location found." but I'm sure some entries are correct. For example one has a latitude of 39.017 and a longitude of 125.73. Google's API show there is at least one address for it :
http://maps.googleapis.com/maps/api/geocode/json?latlng=39.017,125.73&sensor=true
I've also declared this in my Manifest :
<uses-permission android:name="android.permission.INTERNET" >
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
But all this won't return any address. Any idea why?
geoCoder.getFromLocation (Reverse Geocoding) method will work when you build avd (virtual device) target as Google API 19 and also the application is built with the target set as "Google API 19" (you can modify the build target using Project->Properties). This worked for me. Should you need more details please reply to this post.
I'm trying to build a string with origin and destination gps coordinates for google mapping purposes. The first thing that I need to do is to get the gps coordinates of my current location, since this is the origin point. Then, I need to concatenate these coordinates into a larger string that I use to get directions.
I have code that gets these coordinates, and also code that concatenates them into the correct string format. However, my problem is that my string building code is running first, which is leaving me with null pointer issues since the string is referencing gps coordinates that haven't processed yet.
Here it is. The gotLocation() method comes from implementing advice in this post:
Public class DirectionsActivity extends Activity {
String myLat, myLng;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Parser parser;
LocationResult locationResult = new LocationResult(){
#Override
public void gotLocation(final Location location){
try {
Double lat = location.getLatitude();
Double lng = location.getLongitude();
if (lat != 0.0 && lng != 0.0) {
myLat = Double.toString(lat);
myLng = Double.toString(lng);
String gps_location = myLat + " " + myLng;
Toast.makeText(getBaseContext(), "First Message", Toast.LENGTH_SHORT).show();
}
}catch (Exception e) {
}
}
};
MyLocation myLocation = new MyLocation();
myLocation.getLocation(this, locationResult);
Toast.makeText(getBaseContext(), "Second Message", Toast.LENGTH_LONG).show();
buildString();
setContentView(R.layout.activity_directions);
}
The toast output when I run this is "Second Message" followed by "First Message". They should display in the opposite order.
Getting a location is an asynchronous operation, you don't have control on the time at which you get the answer from the system.
How would you be sure to find a satellite or cell phone mat before your toast appears ? :)