Seem to be having some issues getting the longitude and latitude to change on my gps app I am making. I am new to Android, and am not 100% sure I did it right. I also want to note that I do NOT want to use listners for only when the location changes. I specifically want it to update every 5 seconds as I have it in the thread. I also don't seem to be retrieving any satellite data from the stuff I used below either. I just keep writing an empty list to my log file. Am I missing a permission or is the code just wrong? All of the needed information is provided below. Thanks.
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initialize various GPS things
location = new Location("now");
lm = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
gps = lm.getGpsStatus(null);
// Create Entry List for later use
entries = new ArrayList<Entry>();
rows = new ArrayList<TableRow>();
// Turn off Stop by default
Button button = (Button)findViewById(R.id.stopButton);
button.setEnabled(false);
// GPS enabled?
final LocationManager manager = (LocationManager) getSystemService( Context.LOCATION_SERVICE );
if ( !manager.isProviderEnabled( LocationManager.GPS_PROVIDER ) ) {
buildAlertMessageNoGps();
}
criteria = new Criteria();
criteria.setBearingAccuracy(Criteria.ACCURACY_HIGH);
criteria.setAltitudeRequired(true);
criteria.setHorizontalAccuracy(Criteria.ACCURACY_HIGH);
criteria.setAccuracy(Criteria.ACCURACY_FINE);
backgroundThread.start();
}
Thread thread = new Thread()
{
#Override
public void run() {
while (keepGoing) {
// timestamp
long ts = System.currentTimeMillis() / 1000L;
// set location
location = lm.getLastKnownLocation(lm.getBestProvider(criteria, true));
// location stuff
float ac = location.getAccuracy();
double al = location.getAltitude();
double lat = location.getLatitude();
double lon = location.getLongitude();
DataEntry d = new DataEntry(ac, al, lat, lon);
// satellite stuff
List<GPSSatelliteEntry> GPSentries = new ArrayList<GPSSatelliteEntry>();
Iterable<GpsSatellite> sats = gps.getSatellites();
Iterator<GpsSatellite> satI = sats.iterator();
while (satI.hasNext()) {
GpsSatellite item = (GpsSatellite) satI.next();
float az = item.getAzimuth();
float el = item.getElevation();
int p = item.getPrn();
float s = item.getSnr();
GPSSatelliteEntry temp = new GPSSatelliteEntry(az, el, p, s);
GPSentries.add(temp);
}
Entry en = new Entry(ts, d, GPSentries);
entries.add(en);
try {
Thread.sleep(5000); // 5000 ms
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
writeData();
}
};
getLastKnownLocation only works if something on the device is generating the location updates. If nothing on your phone has called requestLocationUpdates, then thye will never update in getLastKnownLocation. The fix is to call requestLocationUpdates and either move your logic into those functions, or even ignore the calls to those functions but have them going off anyway. Remember to unregister when you no longer want updates, like in onStop.
Related
I am new to android programming. So please forgive me if it is a stupid question.
In my app,I am trying to develop a feature that if the location services would be turned off in a phone, then the app would prompt the user to turn it on by taking them to the location settings page on click of a button. The problem is that after turning on the location settings the phone is taking some time to give the location coordinates due to which the fragment that is suppose to show the coordinates is remaining empty for the same amount of time and is creating a confusion.
What I want to know is, if there is any way that I can schedule the execution of the function which is fetching the location coordinates after being sure that there is some coordinates to fetch.
I am using "getLastKnowLocation()". The code for fetching the location is below:-
public String getLocation()
{
// Get the location manager
LocationManager locationManager = (LocationManager)getSystemService(LOCATION_SERVICE);
Criteria criteria = new Criteria();
String bestProvider = locationManager.getBestProvider(criteria, false);
android.location.Location location = locationManager.getLastKnownLocation(bestProvider);
Double lat,lon;
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = new Date();
try {
lat = location.getLatitude ();
lon = location.getLongitude ();
}
catch (NullPointerException e){
}
}
Create a boolean variable locationLoaded. In your following lines of code:
try {
lat = location.getLatitude ();
lon = location.getLongitude ();
//set the value of variable to true once you get location
locationLoaded=true;
}
catch (NullPointerException e){
}
Then create a new recursive method, which will keep checking for location, until it is not loaded, like this:
private void keepCheckingLocation(){
if(locationLoaded){
//location is loaded
return;
}
else{
//location is not loaded yet
try {
//wait for two seconds
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//call the method again to check the location
keepCheckingLocation();
}
}
Once you have called this method, it won't let the next line of code execute until the locationLoaded is not true and locationLoaded will only be true, once the location is loaded. So you can use this method whenever you want to wait for the location to get loaded.
Note: Set locationLoaded=false; if you have to check for locations again. It will make code more efficient.
Please I have this code which has been working for me all this while, all of a sudden it is not working any more, it returns null pointer exception at
double lat = (double) (lastKnownLocation.getLatitude());.
I have set all required permission at the manifest file , but it seems not to work again. I think there must be a problem using the GPS provider now.
latituteField = (TextView) findViewById(R.id.TextViewLatitudeValue);
longitudeField = (TextView) findViewById(R.id.TextViewLongitudeValue);
SpeedField = (TextView) findViewById(R.id.textViewSpeedValue);
AltitudeField = (TextView) findViewById(R.id.textViewAltitudeValue);
AddressLabel=(TextView)findViewById(R.id.textViewAddress);
lbllatitude=(TextView)findViewById(R.id.lblLatDMS);
lbllongitude=(TextView)findViewById(R.id.lblLongDMS);
// Get the location manager
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
// GPS_PROVIDER
String locationProvider = LocationManager.GPS_PROVIDER;
Location lastKnownLocation = locationManager.getLastKnownLocation(locationProvider);
LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
boolean enabled = service.isProviderEnabled(LocationManager.GPS_PROVIDER);
// check if enabled and if not send user to the GSP settings
// Better solution would be to display a dialog and suggesting to
// go to the settings
if (!enabled)
{
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
else if (locationProvider!= null)
{
Toast.makeText(this, locationProvider +" has been selected",Toast.LENGTH_SHORT).show();
onLocationChanged(lastKnownLocation);
}
else
{
latituteField.setText("0.00");
longitudeField.setText("0.00");
AltitudeField.setText("0.00");
SpeedField.setText("0.00");
}
}
/* Request updates at startup */
#Override
protected void onResume() {
super.onResume();
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 400, 1, this);
}
/* Remove the locationlistener updates when Activity is paused */
#Override
protected void onPause() {
super.onPause();
locationManager.removeUpdates(this);
}
#Override
public void onLocationChanged(Location lastKnownLocation) {
double lat = (double) (lastKnownLocation.getLatitude());
double lng = (double) (lastKnownLocation.getLongitude());
double Alt = (double) (lastKnownLocation.getAltitude());
double Speed = (double) (lastKnownLocation.getSpeed());
latituteField.setText(String.format("%.5f",lat));
longitudeField.setText(String.format("%.5f",lng));
AltitudeField.setText(String.format("%.5f",Alt));
SpeedField.setText(String.format("%.5f",Speed));
LastKnownLocation will return null if either the location it has is too old or if the provider has never been turned on. You must take this into account. THe only way to be sure to get a valid location is to request updates and get it in onLocationChanged.
ALso, lastKnownLocation may return a value that's very wrong- something from 10 or 15 minutes ago is possible. You can use it, but don't expect accuracy.
i am getting different Gps coordinates in same location why its happening. But i need to change gps coordinates only moves after 10 meters . How can i do that.
Here is my code.
private static final long MINIMUM_TIME_BETWEEN_UPDATES = 1000;
private static final float MIN_GEOGRAPHIC_POOLING_DISTANCE = (float)10.0;
double myLat_Values;
double myLog_Vaues;
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MINIMUM_TIME_BETWEEN_UPDATES, MIN_GEOGRAPHIC_POOLING_DISTANCE, new MyLocationListener());
private class MyLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location location) {
longitude_str = String.valueOf(location.getLongitude());
latitude_str = String.valueOf(location.getLatitude());
Double longitude_number = Double.valueOf(longitude_str);
DecimalFormat dec = new DecimalFormat("#.000000");
longitude_message = dec.format(longitude_number);
Double latitude_number = Double.valueOf(latitude_str);
DecimalFormat decim = new DecimalFormat("#.000000");
latitude_message = decim.format(latitude_number);
try
{
myLat_Values = Double.valueOf(latitude_message);
myLog_Vaues = Double.valueOf(longitude_message);
}
catch(NullPointerException ex)
{
myLat_Values = 0;
myLog_Vaues = 0;
}
System.out.println("GPS Values Clockout:"+myLat_Values+"-"+myLog_Vaues);
}
public void onProviderDisabled(String s) {}
#Override
public void onProviderEnabled(String provider) {}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {}
}
also i used these into manifestfile :
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
I used this link
please anybody give a suggestion how to solve my problem.
Thank you in advanced.
When you use NETWORK_PROVIDER ,it returns GPS co-ordinates based on the Network Service Provider you are using. But when you are using GPS_PROVIDER it returns GPS co-ordinates based on the satelites.
For Accuracy Criteria, add following code,
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_HIGH);
locationManager.getBestProvider(criteria, true);
ACCURACY_HIGH less than 100 meters
ACCURACY_MEDIUM between 100 - 500 meters
ACCURACY_LOW greater than 500 meters
Also, you need to declare following GPS Permission in AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_GPS"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
i am trying to show on the map where i am.
I am in Israel and it shows me i am in Egypt.
I tried implementing all of the suggestions of different posts and non helped me solve my problem.
I turned on GPS.
I am connected to the Internet.
When i launch MAPS default android App it shows my real location!
MANIFEST PERMISSIONS:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
I also use the uses-library android:name="com.google.android.maps".
This is the relevant code from the MapActivity which extends LocationListener:
lm = (LocationManager) getSystemService(LOCATION_SERVICE);
boolean enabled = lm
.isProviderEnabled(LocationManager.GPS_PROVIDER);
// Check if enabled and if not send user to the GSP settings
// Better solution would be to display a dialog and suggesting to
// go to the settings
if (!enabled) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
if(came_from.matches("FollowLocation"))
{
Location location;
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
String providerName = lm.getBestProvider(criteria, true);
// If no suitable provider is found, null is returned.
if (providerName == null)
{
// reflecting changes if distance travel by
// user is greater than 20m from current location
// and every 1 minute
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
location=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
}
else
{
// reflecting changes if distance travel by
// user is greater than 20m from current location
// and every 1 minute
lm.requestLocationUpdates(providerName, 1*60*1000, 20, this);
location=lm.getLastKnownLocation(providerName);
}
gMapView = (MapView) findViewById(R.id.myGMap);
gMapView.setStreetView(true);
mc = gMapView.getController();
if (location != null)
{
lat = location.getLatitude();
lng = location.getLongitude();
mc.setZoom(14);
}
else //in case we didn't get the location yet
{
lat = 32.08;
lng = 35.84;
mc.setZoom(9);
}
p = new GeoPoint((int) lat * 1000000, (int) lng * 1000000);
mc.animateTo(p);
// Adding zoom controls to Map
gMapView.setBuiltInZoomControls(true);
// Add a location mark
MyLocationOverlay myLocationOverlay = new MyLocationOverlay();
List<Overlay> list = gMapView.getOverlays();
list.add(myLocationOverlay);
}
}
/* This method is called when use position will get changed */
public void onLocationChanged(Location location) {
if (location != null) {
double lat = location.getLatitude();
double lng = location.getLongitude();
p = new GeoPoint((int) lat * 1000000, (int) lng * 1000000);
mc.animateTo(p);
}
}
public void onProviderDisabled(String provider) {
// required for interface, not used
}
public void onProviderEnabled(String provider) {
// required for interface, not used
}
public void onStatusChanged(String provider, int status, Bundle extras) {
// required for interface, not used
}
protected boolean isRouteDisplayed() {
return false;
}
These coordinates: lat = 32.08 lng = 35.84 are some spot in israel...
So..... What am i doing wrong ? Or what am i doing not right ? :P
Thanks!
I'd say that getLastKnownLocation is giving you that erroneous position for some reason. Your default of 32.08, 35.84 won't ever get reached because location will never be null. I'd suggest using the debugger to see which of your calls to getLastKnownLocation is getting hit, and what the value returned is.
I took my code and compared it to a working code from an example in the internet.
Not sure what solved the problem, but i definetly know that you should requestLocationUpdates after you finish to configure everything else.
Other people who encounter this problem - try taking a working code from the internet and comparing it step by step until it works on your app.
I'm trying to give a direction to the user using google map from one location to another.
I'm using the code bellow but I have no idea why it's not working. I can't figure out the problem everything seems right.
final double latitude = 37.894404;
final double longitude = -122.0660386;
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(false);
Location lastKnownLocation = locationManager.getLastKnownLocation(locationManager.getBestProvider(criteria, true));
if(lastKnownLocation != null){
double lat = lastKnownLocation.getLatitude();
double longi = lastKnownLocation.getLongitude();
Intent intent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse("http://maps.google.com/maps?saddr="+lat+","+longi+"&daddr="+latitude+","+longitude));
startActivity(intent);
}else{
Toast.makeText(contactus.this,"Coudn't get provider", Toast.LENGTH_SHORT).show();
}
}
First off you need to wrap your call to LocationManager with a try/catch block and grab whatever exception you're getting off the call. Have a look below. This will make the call and catch the exception.. Go from there once you know why it's coming back NULL. You will always have trouble getting location geopoints using the emulator for whatever reason. Also, Google does not always return with geopoints so in the emulator I have looped until it has come back.. Not a good idea
try{
Location lastKnownLocation = locationManager.getLastKnownLocation(locationManager.getBestProvider(criteria, true));
}
catch(IOException e) {
Log.e("IOException", e.getMessage());
//Toaster on high-----------------//
Context context = getApplicationContext();
CharSequence text = "IOException: " + e.getMessage();
int dur = Toast.LENGTH_LONG;
Toast.makeText(context, text, dur).show();
I actually got it working and here is the code I used,
final double latitude = 45.894404;
final double longitude = -112.0660386;
LocationManager lManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
Criteria crit = new Criteria();
String towers = lManager.getBestProvider(crit, false);
Location userCurrentLocation = lManager.getLastKnownLocation(towers);
if(userCurrentLocation != null){
double lat = userCurrentLocation.getLatitude();
double longi = userCurrentLocation.getLongitude();
Intent intent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse("http://maps.google.com/maps?saddr="+lat+","+longi+"&daddr="+latitude+","+longitude));
startActivity(intent);
}else{
Toast.makeText(contactus.this, "Couldn't locate a provider to find your location", Toast.LENGTH_LONG).show();
}
Don't forget to add the premission to find the user location to you manifest, include it above ,
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>