Is there any code that lets you show your active coordinates in a self-made app? I am having troubles with my google maps and want to see what my active coordinates are. I prefer to show it as I am looking at the google maps in my app ie like a second layer of information. Thanks all !
You can set up a LocationListener.
In the onLocationChanged callback, you will receive a Location. You can then .getLatitude() and .getLongitude() from the location, and apply it to your layout.
public class MyActivity extends MapActivity implements LocationListener {
private LocationManager locationManager;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
requestFineAccuracyLocationUpdates();
}
private void requestFineAccuracyLocationUpdates() {
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
List<String> providers = locationManager.getProviders(true);
for (String provider : providers) {
locationManager.requestLocationUpdates(provider, 5000, 1000, this);
}
}
#Override
public void onLocationChanged(Location location) {
/* You can get your latitude and longitude here, and do whatever. */
}
}
Related
In my Android application (Wheather app), I have a main activity (displaying the wheater on the screen) and a class (getting the current location of the phone).
The "Position" class gets the latitude and longitude, which I would like to send in my main activity to use them. To do that, I tried to use getters but that does not seem to work. Here is the code for both classes :
Location class: (just pay attention to the getters at the end)
public class Position extends AppCompatActivity implements LocationListener {
private double longitude;
private double latitude;
private LocationManager locationManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
return;
}
Location location = locationManager.getLastKnownLocation(locationManager.NETWORK_PROVIDER);
onLocationChanged(location);
}
#Override
public void onLocationChanged(Location location) {
longitude=location.getLongitude();
latitude=location.getLatitude();
}
public double getLongitude1() {
return this.longitude;
}
public double getLatitude1() {
return this.latitude;
}
Main_Activity: (again just pay attention to the last four lines where I i'm trying to use latitude and longitude)
public class MainActivity extends AppCompatActivity {
TextView cityField, detailsField, currentTemperatureField, humidity_field, pressure_field, weatherIcon, updatedField;
Typeface weatherFont;
Position position = new Position();
private double latitude1;
private double longitude1;
private String latitude2;
private String longitude2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().hide();
setContentView(R.layout.activity_main);
weatherFont = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/weathericons-regular-webfont.ttf");
cityField = (TextView)findViewById(R.id.city_field);
updatedField = (TextView)findViewById(R.id.updated_field);
detailsField = (TextView)findViewById(R.id.details_field);
currentTemperatureField = (TextView)findViewById(R.id.current_temperature_field);
humidity_field = (TextView)findViewById(R.id.humidity_field);
pressure_field = (TextView)findViewById(R.id.pressure_field);
weatherIcon = (TextView)findViewById(R.id.weather_icon);
weatherIcon.setTypeface(weatherFont);
Function.placeIdTask asyncTask =new Function.placeIdTask(new Function.AsyncResponse() {
public void processFinish(String weather_city, String weather_description, String weather_temperature, String weather_humidity, String weather_pressure, String weather_updatedOn, String weather_iconText, String sun_rise) {
cityField.setText(weather_city);
updatedField.setText(weather_updatedOn);
detailsField.setText(weather_description);
currentTemperatureField.setText(weather_temperature);
humidity_field.setText("Humidity: "+weather_humidity);
pressure_field.setText("Pressure: "+weather_pressure);
weatherIcon.setText(Html.fromHtml(weather_iconText));
}
});
latitude1 = position.getLatitude1();
longitude1 = position.getLongitude1();
latitude2 = String.valueOf(latitude1);
longitude2 = String.valueOf(longitude1);
asyncTask.execute(latitude2, longitude2); // asyncTask.execute("Latitude", "Longitude")
}
Why do I always get latitude2 = 0.0 and longitude2 = 0.0 in my android monitor ?
You have two different activities. Not an activity and a background service. There is only a single UI thread that runs the Activities. So when MainActivity is running, the Position activity is in the background and not running. And you can't create an object of an Activity using Position position = new Position();.
Why is your Position class an Activity? The onCreate method will never be called there unless you start the class as an Activity. Remove the AppCompatActivity from it and move the onCreate method in a separate method e.g. getLocation.
You also want to pass the Context to the Position class. Create a constructor for that
public Position(Context context) {
this.context = context;
}
and use that for the system calls.
Private variables can't be shared. Change it to.
public double longitude1;
public double latitude1;
You don't really need Position extend from an Activity. I can understand what you are trying to do, you just want to get the location from LocationManager, and send the result to the MainActivity. It should be fine if you just make a LocationManager instance in your MainActivity and pass the result of the location to whatever you want inside MainActivity.
public class MainActivity extends AppCompatActivity {
TextView cityField, detailsField, currentTemperatureField, humidity_field, pressure_field, weatherIcon, updatedField;
Typeface weatherFont;
Position position = new Position();
private double latitude1;
private double longitude1;
private String latitude2;
private String longitude2;
private LocationManager mLocationManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().hide();
setContentView(R.layout.activity_main);
weatherFont = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/weathericons-regular-webfont.ttf");
cityField = (TextView)findViewById(R.id.city_field);
updatedField = (TextView)findViewById(R.id.updated_field);
detailsField = (TextView)findViewById(R.id.details_field);
currentTemperatureField = (TextView)findViewById(R.id.current_temperature_field);
humidity_field = (TextView)findViewById(R.id.humidity_field);
pressure_field = (TextView)findViewById(R.id.pressure_field);
weatherIcon = (TextView)findViewById(R.id.weather_icon);
weatherIcon.setTypeface(weatherFont);
mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
// do check permission staff as you post before
Location location = locationManager.getLastKnownLocation(locationManager.NETWORK_PROVIDER);
// do what you want with the location now.
Basically I think you don't have to make a Position class. You can get location directly and just use it then.
I suggest you to add following reforms to your code.
You need to create object of Position class inside onCreate() method of MainActivity. As onCreate() runs before everything else, it's necessary to have the definition of Position class inside this method.
Make your variables for longitude and latitude public to make them accessible in other class.
Position class need not to extend AppCompatActivity. Instead of using this and OnCreate() method, you can use Constructor and define all your stuff there.
I'm intercepting the click from the mylocation button like so:
map.setMyLocationEnabled(true);
map.setOnMyLocationButtonClickListener(new GoogleMap.OnMyLocationButtonClickListener() {
#Override
public boolean onMyLocationButtonClick() {
bMyLocationClicked = true;
return false;
}
});
and then making it zoom in like so:
// Acquire a reference to the system Location Manager
LocationManager locationManager = (LocationManager) parentActivity.getSystemService(Context.LOCATION_SERVICE);
LocationListener myLocationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
if (bMyLocationClicked) {
bMyLocationClicked = false;
map.moveCamera(CameraUpdateFactory.zoomTo(18f));
}
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
};
// Register the listener with the Location Manager to receive location updates
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, myLocationListener);
Everything works fine, except that there's an extremely long delay between pressing the mylocation button and the zoom in actually happening. The centering of the map finishes and about 2 seconds later the map actually zooms in. How can I speed this up?
I'm looking for an answer where I stay using the mylocation button rather than implementing my own.. although, if there's absolutely no alternative, I'll build a custom center/zoom button.
So I have implemented the new Fused Location Provider API to get a location of the user but for some reason, I cannot get any location unless the GPS is on. Not always, will users have their GPS on and I would like to not have to ask them to turn their GPS on every time the load the app.
How can I tell the API to give me a location with whatever provider it has available?
Here is my code:
public class FusedLocationService implements
LocationListener,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
public interface OnLocationChangedListener {
public void OnLocationChanged(Location location);
}
private final String TAG = "SE8611";
private boolean mRequestingLocationUpdates = true;
private OnLocationChangedListener mCallBack;
Service locationService;
private LocationRequest locationRequest;
private GoogleApiClient googleApiClient;
private Location mCurrentLocation;
private FusedLocationProviderApi fusedLocationProviderApi = LocationServices.FusedLocationApi;
public FusedLocationService(Service locationService, final long INTERVAL, final long FASTEST_INTERVAL) {
Logger.log(TAG, "FusedLocationService called");
this.mCallBack = (OnLocationChangedListener)locationService;
locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(INTERVAL);
locationRequest.setFastestInterval(FASTEST_INTERVAL);
this.locationService = locationService;
googleApiClient = new GoogleApiClient.Builder(locationService)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
if (googleApiClient != null) {
googleApiClient.connect();
}
}
#Override
public void onConnected(Bundle connectionHint) {
if(mRequestingLocationUpdates) {
startLocationUpdates();
}else{
Logger.log(TAG, "Location updates are already running.");
}
}
protected void startLocationUpdates() {
this.fusedLocationProviderApi.requestLocationUpdates(
googleApiClient, locationRequest, this);
this.mRequestingLocationUpdates = false;
}
#Override
public void onLocationChanged(Location mCurrentLocation) {
Logger.log(TAG, "onLocationChanged called");
this.mCurrentLocation = mCurrentLocation;
this.mCallBack.OnLocationChanged(this.mCurrentLocation);
}
public void startLocationUpdatesAfterResume(){
if (googleApiClient.isConnected() && !mRequestingLocationUpdates) {
Logger.log(TAG, "startLocationUpdatesAfterResume called");
this.startLocationUpdates();
}
}
public void stopLocationUpdates() {
Logger.log(TAG, "stopping Location Updates");
LocationServices.FusedLocationApi.removeLocationUpdates(
googleApiClient, this);
}
public Location getLocation() {
return this.mCurrentLocation;
}
#Override
public void onConnectionSuspended(int i) {
this.mRequestingLocationUpdates = true;
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
this.mRequestingLocationUpdates = true;
}
}
I had the same issue like you, which is not an issue at all.
Android used to have a GPS button that let you control it directly, but they replaced it with a Location button which works different.
In order to get any type of location, you must turn it on.
Like you, I thought the Location button turns on and off the GPS only, but that's not the case.
You can control the GPS by changing the location mode:
1. High accuracy (GPS, Wi-Fi and mobile networks)
2. Power Saving (Wi-Fi and mobile networks)
3. GPS only
I think I have found the solution of the problem.
If you go to Settings -> Privacy and Safety -> Location, you would notice that Location is not only GPS, but it actually lets user decide which providers can be used. For example, you can set that only WiFi and Cellular should be used to obtain any locations
Disabling Location option will disable all providers at once, not only GPS.
To test that app for users with only WiFi can get a location – change setting to "Wifi+Cellular".
you seem to be using LocationRequest.PRIORITY_HIGH_ACCURACY, which prefers using GPS above and over other methods. You might want to use PRIORITY_BALANCED_POWER_ACCURACY, which will use WiFi and cell towers before using GPS.
Also, since PRIORITY_BALANCED_POWER_ACCURACY is a "coarse" level of accuracy, you might want to change the location permission in your manifest appropriately.
The training documentation details more information about the priority flags, you might also want to go through it.
We have a strong GPS signal I have an app for testing how fast a GPS lock can be established I even tested the navigation app on my phone they all get pretty much insta lock bellow 10 if I just turned on the GPS.
But with this app I just never get a lock, the wile loop just keeps going on and on and the Log never shows I let it run for 10min and nothing. Am I missing something here I know there is a possible > 10min delay but other apps have no problem that are not using lastKnownLocation but pulling an actual location.
Also the gpsLocation() method is in a static Locator class.
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Location location = Locator.gpsLocation(this);
while(location == null)
{
location = Locator.gpsLocation(this);
}
Log.w("GPS LOCATION", "LOCATION FOUND");
}
/**
* Finds users location using gps
* satelite network.
*
* #param FragmentActivity
* #return Location
*/
public static Location gpsLocation(FragmentActivity context)
{
// Fetch LocationManager service & instance of UserLocator
LocationManager provider = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
UserLocator locator = new UserLocator();
// Attempt to get a fix on users location
provider.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locator);
// Return users location using GPS Service
return locator.location;
}
/**
* Use to listen for user location updates
* TODO: Reimplement as a anonymous class
*/
class UserLocator implements LocationListener
{
// Public accessor
public Location location;
public void onLocationChanged(Location location)
{
if(location != null)
{
// We have a fix on users location
this.location = location;
}
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
}
I think your problem is that your location updates listener is updating the location variable inside your UserLocation class, however the variable you are checking is the one you get back from the method gpsLocation, which is null.
What you are doing is you are signing up for location updates and immediately returning the value of null and checking it over and over again, while your real location is being updated in another place.
All this is also assuming that you have declares the proper permission in your manifest file.
Try this:
Location location;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
gpsLocation(this);
while(location == null)
continue;
Log.w("GPS LOCATION", "LOCATION FOUND");
}
public static void gpsLocation(FragmentActivity context)
{
LocationManager provider = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
UserLocator locator = new UserLocator();
provider.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locator);
}
class UserLocator implements LocationListener
{
public void onLocationChanged(Location loc)
{
if(loc != null)
location = loc;
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
}
With this implementation, both the listener and the while loop address the same instance of Location, so once this changes from null you will get the log message.
I would however strongly discourage putting such a while(true) loop in your onCreate method, you will be blocking the main thread, and this is generally a bad thing to do.
I'm trying to set a textview text when the user location changes. All the code for the GPS portion works. I have been testing using Log();
Now instead of using Log, I wish to display the same information on the main layout, but the LocationChanged event is in a different class so I don't have access to the layout.
public class mylocationlistener implements LocationListener
{
#Override
public void onLocationChanged(Location location)
{
if (location != null)
{
Log.v("kjdv", location.getLatitude() + ", " + location.getLongitude());
//I would like to set a textview here, but don't have access to the object
}
}
This class gets created here:
public class gps extends ListActivity implements View.OnClickListener
{
#Override
public void onCreate(Bundle icicle)
{
super.onCreate(icicle);
setContentView(R.layout.main);
SetupLocationListener();
}
public void SetupLocationListener()
{
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
LocationListener ll = new mylocationlistener(this);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, ll);
}
So how, from the myLocationListener class can I set text in the onLocationChanged event?
Thanks!
We have 2 options.
one is just like as MisterSquonk said. keeping the Location listener as the inner class and the other one is to pass the object of the textView to the constructor of the mylocationlistener. Dont forget to handle null clause in second step.