I have the following code in my main activity (Note: GPSTracker in this application works):
double latitude, longitude;
gps = new GPSTracker(MainActivity.this);
if(gps.canGetLocation()){
latitude = gps.getLatitude();
longitude = gps.getLongitude();
Toast.makeText(getApplicationContext(), "Your Location is - \nLat: " + latitude + "\nLong: " + longitude, Toast.LENGTH_LONG).show();
}
else{
gps.showSettingsAlert();
}
I want to create a loop, which would display in some time intervals Toast with my current position. I´ve tried this:
double latitude, longitude;
long currentTime = System.currentTimeMillis();
long myTimestamp = currentTime;
int i = 0;
gps = new GPSTracker(MainActivity.this);
while(i < 5)
{
myTimestamp = System.currentTimeMillis();
if((myTimestamp - currentTime) > 5000)
{
i++;
currentTime = System.currentTimeMillis();
if(gps.canGetLocation()){
latitude = gps.getLatitude();
longitude = gps.getLongitude();
Toast.makeText(getApplicationContext(), "Your Location is - \nLat: " + latitude + "\nLong: " + longitude, Toast.LENGTH_LONG).show();
}else{
gps.showSettingsAlert();
}
}
}
With this code, Toast is shown only one time (the last iteration). Could you help me with this? Thanks in advance.
I want it to be shown every iteration (for example every 5 seconds).
The code above doesn't loop every five seconds, it loops continuously but only increments your counter every five seconds... This is a very inefficient way of creating a time delay because nothing else can happen while the loop runs. (Even if you run this on a separate thread it is still not good tactic.)
Instead use LocationManager's requestLocationUpdates which will use callbacks so your app can do things between updates. A couple quick notes:
Understand that the GPS may not be able to get a fix every five seconds and that this interval is really short so use it sparingly or you'll run the battery down.
Some pre-Jelly Bean devices may not observe the minTime parameter, but you can enforce your time parameter yourself as I describe in Android Location Listener call very often.
All that aside, you use your existing code but I recommend a Handler and Runnable, like this:
handler.postDelayed(new Runnable() {
#Override
public void run() {
// Fetch your location here
// Run the code again in about 5 seconds
handler.postDelayed(this, 5000);
}
}, 5000);
One problem is that this method does a 'busy-wait', which, I suspect, prevents the toast from being displayed. Try doing a sleep() to wait until it's time for the next Toast:
public void sleepForMs(long sleepTimeMs) {
Date now = new Date();
Date wakeAt = new Date(now.getTime() + sleepTimeMs);
while (now.before(wakeAt)) {
try {
long msToSleep = wakeAt.getTime() - now.getTime();
Thread.sleep(msToSleep);
} catch (InterruptedException e) {
}
now = new Date();
}
}
Related
It's me again having another problem with my location app. Let me explain the current situation:
I have a file stored on my SD card which contains various combinations of latitudes and longitudes in order to define different POIs. These are read into an ArrayList and added to the map using markers. Also, proximity alerts are added. Whenever the user gets near a POI, he is notified using a BroadcastReceiver. This is working perfectly fine.
Now, what I want to do is display a message to the user when he is 1 mile, 0.5 miles and 0.1 miles away from the POI.
What I can do is use the distanceTo() method in the onReceive() method of the BroadcastReceiver. But this will only work once, when the user enters the radius. But since I need the distance to be updated regularly depending on the current position, this won't help me out.
My idea is to give back the latitude and longitude of the POI. Whenever the user enters the specified radius, an Intent is fired from the BroadcastReceiver to the Activity (which is my MainActivity that added the proximity alerts). Then, in my Activity, I get the latitude and longitude and continue my distance calculation in the onLocationChanged method.
Unfortunately, my idea isn't working. It just gives me loop and then my mobile phone kind of freezes. Here are some code snippets:
In my MainActivity:
private void addProximityAlert(double latitude, double longitude, int id) {
// +++ Add a proximity alert to the corresponding obstacle +++ \\
// Attach the id of the obstacle (its index in the ArrayList) to an intent
// NOTE: This is needed in order to distinguish between all proximity alerts added
Intent intent = new Intent(Constants.PROX_ALERT_INTENT);
intent.putExtra("key_id", id);
intent.putExtra("key_latitude", latitude);
intent.putExtra("key_longitude", longitude);
intent.putExtra("key_current_location", mCurrentLocation);
PendingIntent proximityIntent = PendingIntent.getBroadcast(getApplicationContext(), id, intent, PendingIntent.FLAG_CANCEL_CURRENT);
// Add the proximity alert
mLocationManager.addProximityAlert(latitude, longitude, Constants.POINT_RADIUS, Constants.PROX_ALERT_EXPIRATION, proximityIntent);
}
...
public void onLocationChanged(Location location) {
Toast.makeText(this, counter + "", Toast.LENGTH_LONG).show();
// +++ Adapt mCurrentLatitude and mCurrentLongitude when position changes +++ \\
mCurrentLocation = location;
mCurrentLatitude = mCurrentLocation.getLatitude();
mCurrentLongitude = mCurrentLocation.getLongitude();
if(counter == 2) {
Intent fromReceiver = getIntent();
if (fromReceiver.getDoubleExtra("key_dest_latitude", 12345) != 12345.0) {
double latitude = fromReceiver.getDoubleExtra("key_dest_latitude", 12345);
double longitude = fromReceiver.getDoubleExtra("key_dest_longitude", 12345);
Toast.makeText(this, "RECEIVER: LAT =" + latitude + " & LONG = " + longitude, Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "NOT AVAILABLE YET", Toast.LENGTH_LONG).show();
}
}
}
In the class of the BroadcastReceiver:
public void onReceive(Context context, Intent intent) {
// +++ Check if a geofence is entered +++ \\
String key = LocationManager.KEY_PROXIMITY_ENTERING;
mEntering = intent.getBooleanExtra(key, false);
if (mEntering == true) {
Toast.makeText(context, "Obstacle " + intent.getIntExtra("key_id", 666) + " in less than " + Constants.POINT_RADIUS + "m!", Toast.LENGTH_LONG).show();
Intent fromReceiver = new Intent(context.getApplicationContext(), MainActivity.class);
fromReceiver.putExtra("key_dest_latitude", intent.getDoubleExtra("key_latitude", 0));
fromReceiver.putExtra("key_dest_longitude", intent.getDoubleExtra("key_longitude", 0));
fromReceiver.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(fromReceiver);
}
else {
Toast.makeText(context, "Leaving", Toast.LENGTH_LONG).show();
}
}
I'm thankful for any suggestions in order to solve my problem. I just can't find a solution for that...
I am trying to make an Android app which takes the location data in certain intervals e.g:- 5 sec, 1 min,etc. Here is my code :-
public void onLocationChanged(Location loc) {
// TODO Auto-generated method stub
if(loc!=null)
{
//Required Interval
tInterval =(minInterval*60*1000) + (secInterval)*1000 - 1000;
//The app also supports interval mode
RadioButton sel = (RadioButton) findViewById(mode.getCheckedRadioButtonId());
//Code for Manual Functionality
if(sel.getText().equals(MANUAL_RADIO))
{
Time t = new Time();
t.setToNow();
db.addLocationAtTime(loc, t);
Toast.makeText(getApplicationContext(), "Location Added to Database",Toast.LENGTH_SHORT).show();
locate.removeUpdates(this);
b.setText(MANUAL_BUTTON);
d.setEnabled(true);
}
//Code for Interval functionality
else if(sel.getText().equals(INTERVAL_RADIO))
{
//count is object of Countdown class which is a Thread object
if(count == null)
{
//t is a Time object
t.setToNow();
//SQLiteDatabase object for logging Location with Time
db.addLocationAtTime(loc, t);
Toast.makeText(getApplicationContext(), "Location Added to Database",Toast.LENGTH_SHORT).show();
count = new CountDown( tInterval);
count.start();
}
else if(count.getState().toString().equals("TERMINATED"))
{
t.setToNow();
db.addLocationAtTime(loc, t);
Toast.makeText(getApplicationContext(), "Location Added to Database",Toast.LENGTH_SHORT).show();
count = new CountDown(tInterval);
count.start();
}
}
}
}
Here is the code for the Countdown class:-
This class is used to add the interval to the app
public class CountDown extends Thread
{
long time;
public CountDown(long duration)
{
time = duration;
}
public void run()
{
long t1 = System.currentTimeMillis();
long t2 = 0;
do
{
t2 = System.currentTimeMillis();
}while(t2 - t1 < time);
}
}
The problem is that using the above code I am not getting accurate intervals. I am always getting 1 sec extra (due to which I subtracted 1000 in the formula) , but this 1 sec is not happening always. So can anyone please tell me what I am doing wrong ?
Look at LocationManager.requestLocationUpdates, just pass your time interval in parameter..
LocationManager mLocationManager = (LocationManager).getSystemService(mActivity.LOCATION_SERVICE);
mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 5000, 0, new GeoUpdateHandler());
i think here you need to use default features , no need to use Timer
NETWORK_PROVIDER
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 3000, 0, networkLocationListener);
GPS_PROVIDER
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 3000, 0, gpsLocationListener);
Here ,
minTime(2nd field) => minimum time interval between location updates, in milliseconds
minDistance(3rd field) => minimum distance between location updates, in meters
Documentation
I don't think the minTime param of the requestLocationUpdates(...) methods does anything at all. It does not seem to prevent distance-based updates from coming at shorter intervals, and it definitely does not cause updates to come at the specified interval, as many people seem to think. I've tried it on devices from Android 2.3.6 to 4.0.4.
I trying to match hardcoded latitude an longitude with dynamic latitude and longitude, but its not showing correct output, can anyone help me to sort out this error
My code is
String Log = "-122.084095";
String Lat = "37.422005";
try {
if ((Lat.equals(latitude)) && (Log.equals(longitude))) {
AudioManager audiM = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
audiM.setRingerMode(AudioManager.RINGER_MODE_SILENT);
Toast.makeText(getApplicationContext(),
"You are at home",
Toast.LENGTH_LONG).show();
} else {
AudioManager auMa = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
auMa.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
Toast.makeText(getApplicationContext(),
"You are at office ", Toast.LENGTH_LONG)
.show();
}
} catch (Exception e) {
e.printStackTrace();
}
it always goes for else part...
You don't want to use a String comparison here as you can't guarantee the level of accuracy with the real-time location.
The best way to handle this would be to determine the distance between the points and then determine if it's close enough for you to consider, approx, the same.
For this, we use distanceBetween or distanceTo
Docs are here and here
Examples can be found here. Here's one of those examples:
Location locationA = new Location("point A");
locationA.setLatitude(pointA.getLatitudeE6() / 1E6);
locationA.setLongitude(pointA.getLongitudeE6() / 1E6);
Location locationB = new Location("point B");
locationB.setLatitude(pointB.getLatitudeE6() / 1E6);
locationB.setLongitude(pointB.getLongitudeE6() / 1E6);
double distance = locationA.distanceTo(locationB);
The latitude and longitude are variables which vary from point to point, matter of fact they keep on changing while standing on the same spot, because it is not precise.
Instead of comparing the Strings, take a rounded value of the lat and long (in long or float ) and check those values within a certain range. That will help you out with the "Home" and "Office " thing.
For e.g :
String Log = "22.084095";
String Lat = "37.422005";
double lng=Double.parseDouble(Log);
double lat=Double.parseDouble(Lat);
double upprLogHome=22.1;
double lwrLogHome=21.9;
double upprLatHome=37.5;
double lwrLatHome=37.3;
// double upprLogOfc=;
// double lwrLogOfc=;
// double upprLatOfc=;
// double lwrLatOfc=;
if(lng<upprLogHome && lng>lwrLogHome && lat<upprLatHome &&lat>lwrLatHome )
{
System.out.println("You are Home");
}
/* else if(lng<upprLogOfc && lng>lwrLogOfc && lat<upprLatOfc &&lat>lwrLatOfc )
{
System.out.println("You are Home");
}*/
else
System.out.println("You are neither Home nor Ofc");
But for the negative lat long you have to reverse the process of checking.
your matching is okay but you probably should not check for a gps location like this.
You should convert the location to something where you can check that you are in 10m radius of the location.
A nicer way would be to leave the long/lat as doubles and compare the numbers.
if(lat > HOME_LAT - 0.1 && lat < HOME_LAT + 0.1 && ...same for lon... ){}
Try this,
Use google map api to pass lat and long value you will get formatted address. And also pass dynamic lat and lng value same google api you will get formatted address. And then match two formatted address you will get result. i suggest this way you can try this
Use this google api. http://maps.googleapis.com/maps/api/geocode/json?latlng=11.029494,76.954422&sensor=true
Reena, its very easy, Check out below code. You need to use "equalsIgnoreCase()" instead of
"equals".
if ((Lat.equalsIgnoreCase(latitude)) && (Log.equalsIgnoreCase(longitude))) {
should work
Example below :
// Demonstrate equals() and equalsIgnoreCase().
class equalsDemo {
public static void main(String args[]) {
String s1 = "Hello";
String s2 = "Hello";
String s3 = "Good-bye";
String s4 = "HELLO";
System.out.println(s1 + " equals " + s2 + " -> " +
s1.equals(s2));
System.out.println(s1 + " equals " + s3 + " -> " +
s1.equals(s3));
System.out.println(s1 + " equals " + s4 + " -> " +
s1.equals(s4));
System.out.println(s1 + " equalsIgnoreCase " + s4 + " -> " +
s1.equalsIgnoreCase(s4));
}
}
You can print dynamice Latitute and Longitute to Logcat and check with hardcoded Latitute and Longitute
I run a class LokasyonBulucu()
LokasyonBulucu lokasyonBulucu= new LokasyonBulucu();
lokasyonBulucu.LokasyonBul(context);
I take two variable from this class lat and lon
lat=lokasyonBulucu.location.getLatitude();
lon= lokasyonBulucu.location.getLongitude();
but I want to waiting class found coordinates... because it take amount time.
if it find lat and lon I want to run this function
new arkaPlanIsleri(kategori_id, lat , lon).execute();
Use a for loop to check every second with a maximum number of seconds to wait. Check every second if the lat and lon are already found. If so execute the method and break out of the waiting loop:
for(int i = 0; i < 10; i++) { //maximum 10 seconds to wait
if(lat != null && lon != null) { //check if the lat and lon are already found
new arkaPlanIsleri(kategori_id, lat , lon).execute();
break; //stop the waiting loop
}
SystemClock.sleep(1000); //wait one second
}
i have a situation where i need to use GPS technique.
i need to find the distance between two points when the person is walking.
When the person starts walking he will click on Start button and when he stops he clicks on stop button
after this it should show him
1.time taken
2.Distance travelled in Kms.
3.from where to where(places name) eg: a to b
Do i need to have google maps for this?
I saw the code here link to get the current location which gives me latitude longitude.
please help how to go with this
**
Edited:
**
This is the code i am using
private EditText editTextShowLocation;
private Button buttonGetLocation;
private ProgressBar progress;
private LocationManager locManager;
private LocationListener locListener = new MyLocationListener();
private boolean gps_enabled = false;
private boolean network_enabled = false;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
editTextShowLocation = (EditText) findViewById(R.id.editTextShowLocation);
progress = (ProgressBar) findViewById(R.id.progressBar1);
progress.setVisibility(View.GONE);
buttonGetLocation = (Button) findViewById(R.id.buttonGetLocation);
buttonGetLocation.setOnClickListener(this);
locManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
}
#Override
public void onClick(View v) {
progress.setVisibility(View.VISIBLE);
// exceptions will be thrown if provider is not permitted.
try {
gps_enabled = locManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
} catch (Exception ex) {
}
try {
network_enabled = locManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
} catch (Exception ex) {
}
// don't start listeners if no provider is enabled
if (!gps_enabled && !network_enabled) {
AlertDialog.Builder builder = new Builder(this);
builder.setTitle("Attention!");
builder.setMessage("Sorry, location is not determined. Please enable location providers");
builder.setPositiveButton("OK", this);
builder.setNeutralButton("Cancel", this);
builder.create().show();
progress.setVisibility(View.GONE);
}
if (gps_enabled) {
locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locListener);
}
if (network_enabled) {
locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locListener);
}
}
class MyLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location location) {
if (location != null) {
// This needs to stop getting the location data and save the battery power.
locManager.removeUpdates(locListener);
String londitude = "Londitude: " + location.getLongitude();
String latitude = "Latitude: " + location.getLatitude();
String altitiude = "Altitiude: " + location.getAltitude();
String accuracy = "Accuracy: " + location.getAccuracy();
String time = "Time: " + location.getTime();
editTextShowLocation.setText(londitude + "\n" + latitude + "\n" + altitiude + "\n" + accuracy + "\n" + time);
progress.setVisibility(View.GONE);
}
}
#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
}
}
#Override
public void onClick(DialogInterface dialog, int which) {
if(which == DialogInterface.BUTTON_NEUTRAL){
editTextShowLocation.setText("Sorry, location is not determined. To fix this please enable location providers");
}else if (which == DialogInterface.BUTTON_POSITIVE) {
startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
}
}
It is showing the Logitude Latitude which i am entering from emulator control.
In this i am manually entering the details of longitude and latitude
by going to window->showview->other->emulator control for testing in the emulator
but what i need is i will have two edittext where i enter the place name(A) and (B)
it should give me the distance
please help
try using Google Distance Matrix Api
https://developers.google.com/maps/documentation/distancematrix/
You can use currentTimeinMillis() to get your start and end time for your journey.
You can then use the formulas explained here to find the distance and lastly you will have to use a reverse geocoding service such as Nominatim to be able to get the address of a place from your GPS coordinates.
That being said, the distance formula will get you the distance between one point and the next, not the actual displacement. If this is not what you need, but rather you want the actual distance travelled you will need to calculate this value at a shorter interval.
You can find out the distance between two locations(in terms of latitude and longitude) by making use of Spherical Trigonometry
Coming to time make use of simple date objects and compare the startTime and endTime.
(OR)
You can get approximate distance using below code
double distance;
Location locationA = new Location("point A");
locationA.setLatitude(latA);
locationA.setLongitude(lngA);
Location locationB = new Location("point B");
locationB.setLatitude(latB);
LocationB.setLongitude(lngB);
distance = locationA.distanceTo(locationB);
For getting the distance between 2points(A to B) there is a function called distanceTo in android.
For e.g.
double distance = startLocation.distanceTo(finishLocation)/1000;
For time taken as npinti said you can use currentTimeinMillis() or you can also use Timer and show it to user when he clicks on start button. Its just like stopwatch.
Edited
Place A - New York
Place B - Paris
In this case you first need to convert the string into Location(i.e you need latitude & longitude). For that you have use the concept of Geocoding.
List<Address> foundGeocode = null;
foundGeocode = new Geocoder(this).getFromLocationName("address here", 1);
foundGeocode.get(0).getLatitude(); //getting latitude
foundGeocode.get(0).getLongitude();//getting longitude
After that you can calculate the distance from the distanceTo method.
Hope this will help....
I suppose the question is one of walking..
Are you walking on the streets, or as the crow flies?
If it's streets, and your connected to the net, use google's api.. It calculates routing based on two points and returns XML.. Should be easy enough to figure out.
If it's crow flies.. well then, just do (a*a) + (b*b) = (c*c) this is by far the easier..
You could have your user tap for major turns.. Or you could keep a runnable running every 10 seconds from when they hit start, and plot the points. Still a*a+b*b=c*c but just a bunch of steps.
Of course you'd have to run it in a service.. And given the choice I'd go with that option. You could adjust the cycle time based on speed traveled. Faster would be smaller pauses.
It requires less on your dataplan.
EDIT
Ah.. I see what you're looking for. Tis not what I thought you were asking for.
Simplify.. convert lat/long to GPS. and then do simple math on the last point stored
void addDistance()
{
newX = ...
newY = ...
deltaX = absolute(m_oldX - newX)
deltaY = absolute(m_oldY = newY)
m_distance += sqrt(deltaX^2 + deltaY^2);
m_oldX = newX;
m_oldY = newY;
}
void startOver()
{
newX = ...
newY = ...
m_distance = 0;
m_oldX = newX;
m_oldY = newY;
}