I have a simple App which currently simply asks for necessary permissions and in case GPS is OFF, you get an AlertDialog asking you if you want to switch it ON. After accepting, being taken to GPS options, enabling it, and going back to my App, I'd like to update location and here I get lost.
In other words, I'm trying to do what's stated here: https://stackoverflow.com/a/43396965/7060082
Unfortunately I can't manage to get it done and the example is a bit complicated for me to understand. Here is a piece of my code showing the relevant bits:
private void checkGPS() {
manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.GPS_error)
.setCancelable(false)
.setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() {
public void onClick(#SuppressWarnings("unused") final DialogInterface dialog, #SuppressWarnings("unused") final int id) {
Intent gps = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivityForResult(gps, 1);
getLatLon();
}
})
.setNegativeButton(R.string.deny, new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, #SuppressWarnings("unused") final int id) {
dialog.cancel();
}
});
final AlertDialog alert = builder.create();
alert.show();
} else {
getLatLon();
}
}
private void getLatLon() {
//manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
String provider = manager.getBestProvider(criteria, false);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
manager.getLastKnownLocation(provider);
if (location != null) {
Toast.makeText(this, "This is my location: " + location.getLongitude() + ", " + location.getLatitude(), Toast.LENGTH_SHORT).show();
} else {
// manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
//location = manager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
/*
double longitude = location.getLongitude();
double latitude = location.getLatitude();
Toast.makeText(this, "This is my location: " + longitude + ", " + latitude, Toast.LENGTH_SHORT).show();
*/
}
}
}
#Override
public void onLocationChanged(Location l) {
location = l;
double longitude = location.getLongitude();
double latitude = location.getLatitude();
Toast.makeText(this, "This is my location: " + longitude + ", " + latitude, Toast.LENGTH_SHORT).show();
}
After asking for ACCESS_FINE_LOCATION permission (which is also stated on the manifest) I call checkGPS(). As said before, let's you enable or not the GPS. If enabled, I call getLatLon(). If there is a lastKnownLocation, good, if not...
Here I get lost. I call requestLocationUpdates and then do nothing waiting for onLocationChanged to recieve a location update and execute the rest of the code. Am I doing it right? The result is me clicking the button, switching GPS on. Click on the button again and nothing happens.
Any help with this will help.
Many thanks for your time.
I've developed fused location api demo application and utility pack here.
General Utilities
Try it if useful for you. To get location using fused location api, you just have to write following snippet...
new LocationHandler(this)
.setLocationListener(new LocationListener() {
#Override
public void onLocationChanged(Location location) {
// Get the best known location
}
}).start();
And if you want to customise it, simply find documentation here...
https://github.com/abhishek-tm/general-utilities-android/wiki/Location-Handler
I've written a sample code according to your need, this will handle GPS enable/disable dialog internally, try this one...
import android.content.Intent;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import in.teramatrix.utilities.service.LocationHandler;
import in.teramatrix.utilities.util.MapUtils;
/**
* Lets see how to use utilities module by implementing location listener.
*
* #author Khan
*/
public class MainActivity extends AppCompatActivity implements OnMapReadyCallback, LocationListener {
private GoogleMap map;
private Marker marker;
private LocationHandler locationHandler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Obtaining an instance of map
FragmentManager manager = getSupportFragmentManager();
SupportMapFragment mapFragment = (SupportMapFragment) manager.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
this.locationHandler = new LocationHandler(this)
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(5000)
.setFastestInterval(10000)
.setLocationListener(this);
}
#Override
public void onMapReady(GoogleMap map) {
this.map = map;
this.locationHandler.start();
}
#Override
public void onLocationChanged(Location location) {
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
if (marker == null) {
marker = MapUtils.addMarker(map, latLng, R.drawable.ic_current_location);
map.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 14), 500, null);
} else {
marker.setPosition(latLng);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if (locationHandler != null) {
locationHandler.stop();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == LocationHandler.REQUEST_LOCATION) {
locationHandler.start();
}
}
}
Hope it will help you.
Your current code doesn't wait for the user to make a choice before calling getLatLon() in the case where GPS is disabled.
You will need to add a onActivityResult() override that will be called when the user goes back to your app.
First, remove the call to getLatLon() in the checkGPS() method for the case where GPS is disabled:
private void checkGPS() {
manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.GPS_error)
.setCancelable(false)
.setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() {
public void onClick(#SuppressWarnings("unused") final DialogInterface dialog, #SuppressWarnings("unused") final int id) {
Intent gps = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivityForResult(gps, 1);
//Remove this:
//getLatLon();
}
})
.setNegativeButton(R.string.deny, new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, #SuppressWarnings("unused") final int id) {
dialog.cancel();
}
});
final AlertDialog alert = builder.create();
alert.show();
} else {
getLatLon();
}
}
Then, add the onActivityResult() override, check the setting again, and if it's now enabled then call getLatLon():
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
getLatLon();
}
}
after some time busy with other projects, got back to this one and I removed the getLatLon(); function from the checkGPS(); function and that's it, code is fine. I was using the emulator to check if this was working, but I forgot that the emulator has a fixed value for the latitude and longitude, so you get no updates like a real mobile phone, and thus it looked as if it was not working properly.
Sort of a newby mistake. Regardless, thanks for your offers. Was interesting looking at different ways of doing the same thing.
Sartox
Related
My app uses users location and have fragments. In main activity this fragments changes.
But there is a problem here. I implement "Location Listener" interface to my fragment class, and drop the breakpoint in "onLocationChanged" event. And program never hit the breakpoint.
Why I can not reach the users location?
Here is my code:
public class NearestCoffeeVenueFragment extends Fragment implements LocationListener{
// GPS Variables
private LocationManager locationManager;
private Location lastLocation;
private String provider;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
locationManager = (LocationManager)getActivity().getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,0,0,this);
provider = LocationManager.NETWORK_PROVIDER;
Location location = locationManager.getLastKnownLocation(provider);
if(location != null){
lastLocation = location;
Toast.makeText(getActivity(), getString(R.string.gps_success), Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(getActivity(),getString(R.string.gps_fail),Toast.LENGTH_SHORT).show();
cannotReachGpsWarning();
}
return inflater.inflate(R.layout.fragment_nearest_coffee_venue, container, false);
}
/** LocationListener Interface Functions
* */
#Override
public void onLocationChanged(Location location){
Toast.makeText(getActivity(),"Long: "+location.getLongitude()+" Lat:"+location.getLatitude(),Toast.LENGTH_LONG).show();
lastLocation = location;
}
#Override
public void onStatusChanged(String provider,int status,Bundle extras){
}
#Override
public void onProviderEnabled(String provider){
Toast.makeText(getActivity(),getString(R.string.gps_enabled_provider)+provider,Toast.LENGTH_LONG).show();
}
#Override
public void onProviderDisabled(String provider){
Toast.makeText(getActivity(),getString(R.string.gps_disabled_provider)+provider,Toast.LENGTH_LONG).show();
}
/// warning messages and buttons setted from strings file.
private void cannotReachGpsWarning(){
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage(getString(R.string.gps_disabled))
.setCancelable(false)
.setPositiveButton(getString(R.string.gps_enable),
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
showGPSOptions();
}
});
builder.setNegativeButton(getString(R.string.gps_disable),
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}
private void showGPSOptions(){
Intent gpsOptionsIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(gpsOptionsIntent);
}
As I say, I don't see any toasts or anything else. The fragment's doesn't hit the breakpoint on "onLocationChanged" function. This means fragment can't reach location. And when fragment starts, I see "Can not reach location" error even the phone's location was on.
Did you enable location in the device for both sources GPS ans NETWORK? Currently in your code your'e asking for network provider, if this provider is disabled the method getLastKnownLocation will return null.
Im experimenting with android development, and getting the location of a device.
my GPSTracker class is listed below with the error being thrown.
import android.app.AlertDialog;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.util.Log;
/**
* Created by informationservices on 29/08/14.
*/
public class GPSTracker extends Service implements LocationListener {
private final Context mContext;
//flag for GPS status
boolean isGPSEnabled = false;
//flag for network status
boolean isNetworkEnabled = false;
boolean canGetLocation = false;
Location location;
double latitude; //latitude variable
double longitude; //longitude variable
//The minimum distance to change updates in meters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 1;
private static final long MIN_TIME_BW_UPDATES = 1000;
//declare location manager
protected LocationManager locationManager;
public GPSTracker(Context context){
this.mContext = context;
getLocation();
}
//function to get latitude
public double getLatitude(){
if (location != null){
latitude = location.getLatitude();
}
//must have a return (as its a function)
return latitude;
}
public double getLongitude(){
if (location !=null){
longitude = location.getLongitude();
}
return longitude;
}
public Location getLocation() {
try {
locationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE);
//getting GPS Status
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
//getting Network Status
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled) {
//No Network provider is enabled
}else{
this.canGetLocation=true;
//first get location from Network Provider
if(isNetworkEnabled){
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,MIN_TIME_BW_UPDATES,MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("Network", "Network");
if (locationManager !=null){
location=locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if(location !=null){
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
}
catch (Exception e){
e.printStackTrace();
}
return location;
}
//check if this is the best network provider
public boolean canGetLocation(){
return this.canGetLocation;
}
//show GPs settings in alert box
public void showSettingsAlert(){
AlertDialog.Builder alertDialog = new AlertDialog(mContext);//AlertDialog(android.content.Context) has protected access in 'android.app.AlertDialog'
//set alert title
alertDialog.setTitle("GPS is Settings");
//set Dialog message
alertDialog.setMessage("GPS is not Enabled. Do you want to go to settings menu?");
alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int which){
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivities(new Intent[]{intent});
}
});
alertDialog.setNegativeButton("Cancel",new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int which){
dialog.cancel();
}
});
//show alert
alertDialog.show();
}
#Override
public void onLocationChanged(Location location) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
This is my first attempt at coding for android. I have been googling for a while, but can't see why it is throwing this error.
Could someone please explain what this error means, and how to fix it.
a thorough explication, and link to any relevant google docs would also be appreciated.
The error means that the AlertDialog constructor is not accessible (public). It is declared protected so the programmers are forced to use a builder pattern when working with AlertDialogs.
To show an AlertDialog, you use the AlertDialog.Builder to set everything up and then call show() to build and show the AlertDialog.
// Use the AlertDialog.Builder to configure the AlertDialog.
AlertDialog.Builder alertDialogBuilder =
new AlertDialog.Builder(this)
.setTitle("GPS is Settings")
.setMessage("GPS is not Enabled. Do you want to go to settings menu?")
.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivities(new Intent[]{intent});
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
// Show the AlertDialog.
AlertDialog alertDialog = alertDialogBuilder.show();
I counterd this problem because just now i was going to learn about the difference
between AlertDialog.Builder and AlertDialog so when i wrote
AlertDialog dialog=new AlertDialog();
so it gave me the same problem like yours
but since you wrote
AlertDialog.Builder alertDialog = new AlertDialog(mContext);
//.Builder was missing
AlertDialog.Builder = new AlertDialog.Builder(mContext)
and if you want to use AlertDialog then do it like this
AlertDialog = new AlertDialog.Builder(mContext)
This should work.
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(
MapActivity.this);
dialogBuilder.setPositiveButton("ok", null);
dialogBuilder.setNegativeButton("cancel", null);
dialogBuilder.setCancelable(false);
dialogBuilder.setView(saySomething);
final AlertDialog mAlertDialog = dialogBuilder.create();
mAlertDialog.setOnShowListener(new DialogInterface.OnShowListener() {
#Override
public void onShow(DialogInterface dialog) {
Button b = mAlertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// TODO Do something
// To close once you are done with your operation call below method.
// mAlertDialog.dismiss();
}
});
}
});
mAlertDialog.show();
I've been trying to remove location updates from my location manager however the GPS symbol continuously shows even after removeupdates has been called. I've ensured the correct listener variable name has been passed and the code is executed for the listener update. I only want to find the user's location once.
Thanks
public class MapActivity extends FragmentActivity implements OnInfoWindowClickListener, OnCameraChangeListener {
Map<Marker, Integer> markers = new HashMap<Marker, Integer>();
VenueManager venueManager;
GoogleMap map;
long last_map_refresh = 0;
Button search_btn;
CameraPosition previous_position = null;
private LocationManager locationManager;
private static final long MIN_TIME = 400;
private static final float MIN_DISTANCE = 1000;
private ProgressDialog loading;
private Button add_venue;
SharedPreferences sharedPreferences;
private LatLng user_position = null;
private NetworkManager network_manager;
private Boolean first_map_render = false;
private LocationListener location_listener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
if( !locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) ) {
AlertDialog.Builder builder = new AlertDialog.Builder(MapActivity.this);
builder.setTitle("GPS not enabled"); // GPS not found
builder.setMessage("This application requires you to enable GPS location settings. We recommend that you enable 'Use wireless networks' and 'Use GPS satellites'. Would you like to enable this setting now?"); // Want to enable?
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int i) {
finish();
MapActivity.this.startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
}
});
builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int i) {
Intent home_intent = new Intent(MapActivity.this, HomeActivity.class);
startActivity(home_intent);
Toast.makeText(MapActivity.this, "You will not be able to use the map features of this application until you enable gps settings", Toast.LENGTH_LONG).show();
finish();
}
});
builder.create().show();
return;
}
else
{
network_manager = new NetworkManager();
location_listener = new LocationListener() {
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, 16);
map.animateCamera(cameraUpdate);
draw_map(new CameraPosition.Builder().target(new LatLng(location.getLatitude(), location.getLongitude())).build());
user_position = latLng;
locationManager.removeUpdates(location_listener);
};
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME, MIN_DISTANCE, location_listener);
}
}
First of all when using LocationManager.NETWORK_PROVIDER you should not see the GPS symbol at all.
I see you are using Google Maps Android API v2, so my guess is outside of the code you put here you have
map.setMyLocationEnabled(true);
which shows blue dot and continuously updates it while showing Activity with MapFragment/MapView.
the method startSightManagement() is called twice throug my program, so i have two location Manager objects.
private void startSightManagement() {
String locationService = Context.LOCATION_SERVICE;
locationManager = (LocationManager)getSystemService(locationService);
// Get the GPS provider and request location updates
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
provider = locationManager.getBestProvider(criteria, true);
locationManager.requestLocationUpdates(provider, 2000, 2, this);
// Obtain last known location and update the UI accordingly
Location location = locationManager.getLastKnownLocation(provider);
updateWithNewLocation(location);
sightManager = new SightManager(this);
// Set up the first sight
setSight();
}
my onPause() Activity with removeUpdates(this)-->This only removes one instance, how do i remove the other one??
protected void onPause() {
myLocationOverlay.disableMyLocation();
locationManager.removeUpdates(this);
locationManager=null;
// TODO Auto-generated method stub
super.onPause();
//Shutdown TTS everytime when activity is paused(Tolga)
if (mTts != null) {
mTts.stop();
}
// Unregister the proximity intent receiver. This also prevents the app from
// leaking when it is closed.
if (proximityIntentReceiver!=null) {
unregisterReceiver(proximityIntentReceiver);
}
}
Second problem is: app crashes when gps isnt enabled on start and i click yes when asked if gps should be enabled. when i remove these two lines everything works fine:
locationManager.removeUpdates(this);
locationManager=null;
here is the buildAlert method if gps isnt enabled on start:
private void buildAlertMessageNoGps() {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("GPS ist deaktiviert. Standorteinstellungen anzeigen?")
.setCancelable(false)
.setPositiveButton("Ja", new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, final int id) {
startActivityForResult(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS), ENABLE_GPS_SUB);
}
})
.setNegativeButton("Nein", new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, final int id) {
dialog.cancel();
finish();
}
});
final AlertDialog alert = builder.create();
alert.show();
}
I'm beta testing my first Android app and have had a few users mention that when they attempt to lookup by GPS it hangs. In order to improve error handling around this I wanted to get the opinion of people who have apps in the wild.
My current activity does the following to kick off the lookup
findViewById(R.id.gpsButton).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
LocationManager mlocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
MyLocationListener mlocListener = new MyLocationListener();
Criteria locationCriteria = new Criteria();
locationCriteria.setAccuracy(Criteria.ACCURACY_FINE);
mlocManager.requestLocationUpdates(mlocManager.getBestProvider(locationCriteria, true), 0, 0, mlocListener);
}
});
The implementation of my custom location lookup class is below
public class MyLocationListener implements LocationListener {
private boolean alreadyLocatedDevice;
private ProgressDialog dialog;
public MyLocationListener() {
this.dialog = ProgressDialog.show(LocationLookup.this, "", "Loading...");
}
#Override
public void onProviderDisabled(String provider) {
this.dialog.dismiss();
DialogHelper.showDialogWithMessageAndTitle("", "You don't currently have location services turned on", LocationLookup.this);
}
#Override
public void onLocationChanged(android.location.Location location) {
if (!alreadyLocatedDevice) {
alreadyLocatedDevice = true;
Location loc = new Location();
loc.setLng(Double.toString(location.getLongitude()));
loc.setLat(Double.toString(location.getLatitude()));
((AppDelegate) getApplicationContext()).setSelectedLocation(loc);
Intent findKioskLocation = new Intent(LocationLookup.this, FindKioskLocation.class);
this.dialog.dismiss();
startActivity(findKioskLocation);
}
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
//To change body of implemented methods use File | Settings | File Templates.
}
#Override
public void onProviderEnabled(String s) {
//To change body of implemented methods use File | Settings | File Templates.
}
}
And finally I've added both the ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION permissions in my manifest file.
Any help would be much appreciated!
Here is a nice implementation that I recnetly looked at. Basically by default it uses GPS to get a location. If no location can be found within a certain time period or no satellites are available it switches to Network.
Hope this helps
A Stacktrace from the logcat would have helped you and other developers here understand where the problem is coming from. Try to ask the users to recreate the problem if possible and find out when it is occurring.
As for guidance with the locaton manager, Google Developers just posted a blog recently and also updated the docs on how to use location manager. Check the documentation here and also the blog post which explains it with an example. That might help you better. The blog post also explains how to use different location providers and how to be user friendly and guidance necessary in most ases when using location in Android applications.
For anyone who might follow this thread -I found a mixture of my own approach (admittedly hackish in this code example) and the one mentioned by #bear to work without any issues (plus the location lookup was fast/accurate and error free)
I found the example listed by #bear to be a little more complex than I needed. For starters I wanted to kick off the GPS lookup when a button was clicked and have a simple async task wrapping this so it would throw up a dialog/etc
Next I wanted the exact latitude and longitude (no need to pass this off to another class because my example was simply to use the lat + lng to locate a resource and plot it)
So if you can follow my untested rather copy/paste approach here goes...
Inside your activity you would spin up the service during an onclick lets say ...
LocationManager networkManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
LocationManager gpsManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
LocationService locationProcessor = new LocationService(YourActivityName.this, networkManager, gpsManager, dialog);
locationProcessor.onStartCommand();
Now the location service itself
package com.epicsoftware.android.global;
import android.app.ProgressDialog;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import com.epicsoftware.android.activity.LocationLookup;
public class LocationService {
private LocationManager networkLm;
private LocationManager gpsLm;
private LocationListener networkListener;
private LocationListener gpsListener;
private boolean isRunning;
private boolean networkLocDisabled;
private boolean gpsLocDisabled;
private Context activity;
private LocationManager tmpNetworkManager;
private LocationManager tmpGpsManager;
private Handler locationHandler;
private ProgressDialog dialog;
private boolean gpsUpdated;
private boolean done;
public LocationService(final Context activity, LocationManager networkManager, LocationManager gpsManager, ProgressDialog dialog) {
this.tmpNetworkManager = networkManager;
this.tmpGpsManager = gpsManager;
this.activity = activity;
this.dialog = dialog;
}
public void onStartCommand() {
if (!isRunning) {
isRunning = true;
startLocationListeners();
locationHandler = new Handler();
getLocationByZip.start();
}
}
private void startLocationListeners() {
networkListener = new NetworkLocationListener();
gpsListener = new GpsLocationListener();
networkLm = tmpNetworkManager;
gpsLm = tmpGpsManager;
networkLm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, networkListener);
gpsLm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, gpsListener);
}
private Thread getLocationByZip = new Thread() {
public void run() {
try {
for (int i = 0; i < 15;) {
if (!locationDisabled() || !gpsUpdated) {
try {
Thread.sleep(1000);
} catch (Exception e) {
break;
}
i++;
} else {
break;
}
}
locationHandler.post(monitorTheNetworkAndGpsProviders);
} catch (Exception e) {
killService();
done = true;
}
}
};
private Runnable monitorTheNetworkAndGpsProviders = new Runnable() {
#Override
public void run() {
killService();
dialog.dismiss();
if (!done) {
done = true;
((LocationLookup) activity).warnUserThatLocationServicesAreDisabledOrFailed();
}
}
};
private boolean locationDisabled() {
if (gpsLocDisabled && networkLocDisabled) {
done = true;
((LocationLookup) activity).warnUserThatLocationServicesAreDisabledOrFailed();
return true;
} else {
return false;
}
}
private void updateDb(Double lat, Double lon) {
done = true;
((LocationLookup) activity).setLocationDataAndSpinUpNextActivity(lat, lon);
}
public void killService() {
networkLm.removeUpdates(networkListener);
gpsLm.removeUpdates(gpsListener);
}
public class NetworkLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location location) {
if (location != null) {
updateDb(location.getLatitude(), location.getLongitude());
}
}
#Override
public void onProviderDisabled(String provider) {
networkLocDisabled = true;
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
public class GpsLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location location) {
if (location != null) {
gpsUpdated = true;
updateDb(location.getLatitude(), location.getLongitude());
}
}
#Override
public void onProviderDisabled(String provider) {
gpsLocDisabled = true;
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
}