How to know the time that a user has been somewhere? - android

I am using Android LocationManager to check if a user is around a Location that I have defined.
I am using addProximityAlert method so that I receive an intent when the user is where I expect.
However, what I would like to do is to know if a user is in the given place for a period of time because if a user is crossing through the location I am checking, I may also receive the intent.
My first approach is that after some time (some minutes) I can check it again. Is there a better approach? Is there any way to receive the intent only after some time has passed?
Thank you.

To solve this problem, you could use an if statements to store the elapsed time of the user being in a certain distance. You could use System.currentTimeMillis() to get the current time and then subtract the original start time from it, to give you the elapsed time. Here is something you could do:
long startTime = 0;
long elapsedTime;
// Set up LocationManager here
Location targetPlace;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Location location = locationManager.getLastKnownLocation(provider);
// Checks to see if the user was already there when they opened the activity
if(location.distanceTo(targetPlace) == 5) {
startTime = System.currentTimeMillis();
}
targetPlace = new Location(provider);
}
#Override
public void onLocationChanged(Location location) {
if(startTime != 0) {
// Check to see if the user is in a given place
if (location.distanceTo(targetPlace) == 5) {
elapsedTime = (System.currentTimeMillis() - startTime) / 1000; // Time in seconds
} else {
// User is not near that location
}
} else {
startTime = System.currentTimeMillis();
}
}
Change '5' in the if statement to whatever you want the radius to be. Hope this helps!

Related

What is SystemClock.elapsedRealtime - millisecond?

I have some doubts I had in mind regarding a section of code that I retrieved from some answers given which were used to prevent the user from clicking the same button multiple times. Can someone explain to me what this section code does and give examples?
The Codes are
private long mLastClickTime = 0;
//Avoid the user clicking more than one
if (SystemClock.elapsedRealtime() - mLastClickTime < 1000){
return;
}
mLastClickTime = SystemClock.elapsedRealtime();
the if condition is placed below every button.setonclicklistener
I just want to understand what this section of code does only :)
I'll explain it using more detailed variable names.
private long mLastClickTime = 0;
private long theUserCannotClickTime = 1000; // milliseconds. the time that must pass before the user's click become valid
long currentTime = SystemClock.elapsedRealtime(); // not necessarily the current realworld time, and it doesn't matter. You can even use System.currentTimeMillis()
long elapsedTime = currentTime - mLastClickTime; // the time that passed after the last time the user clicked the button
if (elapsedTime < theUserCannotClickTime)
return; // 1000 milliseconds hasn't passed yet. ignore the click
}
// over 1000 milliseconds has passed. do something with the click
// record the time the user last clicked the button validly
mLastClickTime = currentTime;
elapsedRealtime() and elapsedRealtimeNanos() return the time since the system was booted, and include deep sleep. This clock is guaranteed to be monotonic, and continues to tick even when the CPU is in power saving modes, so is the recommend basis for general purpose interval timing.
For futher check this method
https://developer.android.com/reference/android/os/SystemClock.html#elapsedRealtime()

Code set to run during a timer is being triggered intermittently

I have a countdown timer that runs when a user presses a button, at the conclusion of the timer, the location of the device is sent to another device for which the user enters a phone number for. Here is my timer code::
private void initTimer() {
if(timer==null)
{
long totalTime= (PersistData.getIntData(con, AppConstant.selectedMinute)*60*1000)+(PersistData.getIntData(con, AppConstant.selectedseconds)*1000);
timer=new CountDownTimer(totalTime, 1000) {
public void onTick(long millisUntilFinished) {
timerView.setText(getFormatterTimerText(millisUntilFinished));
if(millisUntilFinished<60*1000)
{
continueFlashAndAudio();
/*
refresh GPS Location again
*/
updateGPSLocation (millisUntilFinished);
}
}
public void onFinish() {
showFinishView();
}
};
}
}
When the timer runs, it is supposed to run the "updategpslocation" function:
private void updateGPSLocation(long millisUntilFinished) {
Log.e("current time remaining", " time: "+millisUntilFinished/1000);
if(millisUntilFinished/1000==30)
{
Log.e("30 seconds remaining", "get locaiton");
getLocation();
}
if(millisUntilFinished/1000==10)
{
Log.e("10 seconds remaining", "get locaiton");
getLocation();
}
}
The issue I am having is that about half the time, the location will not be updated and it will send a location that was previously fetched to the other phone.
Here is my code to get the location:
private void getLocation()
{
GPSTracker tracker=new GPSTracker(con);
if(tracker.canGetLocation())
{
Location lastLocation=tracker.getLocation();
PersistObject.apply(con,AppConstant.LOCATION,lastLocation);
Log.e("Location is refreshed", "5 seconds remaining");
}
}
I am extremely confused as to why this is happening, I have spent hours on this and have hired a couple freelancers to help and nothing they have done has been able to remedy the issue. Half the time the code will work fine and it will send the new location of the device, and half the time it will send the location that the device returned previously. I move the phone around to test new spots and I am running this on three different phones and it happens on all of them intermittently. Any ideas would be GREATLY appreciated.

Best way to implement a delayed SMS sending after a countdown (Alarm, Chronometer, CountDownTimer)

I need to send a SMS in a future time, i.e. in 5 minutes, and to show in the UI the remaining time in the format 00:00.
My first choice was using android-alarm, but I dont know how to show in the layout the countdown.
Next, I tried to use a chronometer, and use the view of the object, but the time is always up, so i'd need to make a lot of math operations to refresh the view.
Finally I've used a CountDownTimer, and i show in a TextView the elapsed time.
That is the best choice?
Here is a short of code:
public void startCountDown(View v) {
if (!activedCountDown) {
activedCountDown = true;
final TextView mTextField = (TextView) findViewById(R.id.mTextField);
EditText text = (EditText) findViewById(R.id.etMinutos);
String mins = text.getEditableText().toString();
futureTime = Integer.parseInt(mins) * 60000;
isTheFinalCountDown = new CountDownTimer(futureTime, interval) {
#Override
public void onTick(long millisUntilFinished) {
if (millisUntilFinished < 60000) {
mTextField.setText("00:" + millisUntilFinished / 1000);
} else {
//TODO parse the textfield to show minutes and seconds
}
}
#Override
public void onFinish() {
//TODO: launch SMS
mTextField.setText("Send SMS now");
activedCountDown = false;
}
}.start();
}
}
To show user time remaining you may use the countdown timer
BUT FOR SENDING SMS
I will strongly discourage you to use it, you must use the the Alarm/Broadcast reciever because your activity variables might get freed from memory as Android OS needs memory if other apps are running.
See this for detail, it happened to me.

Track an user with location based App

I'm working on a Location based App. Here my requirement is I want to track a user location from my device like uber or Ly ft App.
Example: If a pizza guy(User B) wants to deliver pizza to me(User A) then he can share his user id, so using that id, I can enter in my device and see his exact precise location. But I want to track him until I required so how to achieve this in code. Help me with the architecture if you have come across such scenario.
I can also achieve the above scenario, but my doubt is how can I show in map without refreshing each time when the user moves say for example two minutes once I want to check the Latitude and Longitude and update it in my map for the same user
Create a Thread, that asks a Handler to get the position a few times. You need to use a Handler, because the getMyLocation method can only be called from GUI Thread:
private class MyLocationThread extends Thread{
#Override
public void run() {
int loops = 0;
// we give the location search a minute
while(loops < 60){
// we have to try it over a handler, because getMyLocation() has to be called from GUI Thread -_-
_getMyLocationHandler.sendEmptyMessage(0);
if(isInterrupted()){
return;
}
// take a short nap before next try
try {Thread.sleep(1000);} catch(Exception e){}
loops++;
}
}
}
Here's what the Handler does:
private Handler _getMyLocationHandler = new Handler(){
public void handleMessage(android.os.Message msg) {
if(getMap().isMyLocationEnabled() && getMap().getMyLocation() != null){
_locationWatcher.interrupt();
drawCurrentImagePositions();
}
}
};

slowing down a user's ability to button mash in Android

I have an activity that runs some ASCII control over a network port to a remote device.
Every single button push on the interface will trigger an AsyncTask to handle the communication, and (finally) works great.
However, if a user starts button mashing like a chimp on crack, the system will crash with way too many calls on the same socket, so I've come up with a little timer function to slow down the reaction to their excitement.
I'm wondering if somebody has come up with a better way to do this?
First off, inside the onCreate:
btn_pwrtoggle = (Button)findViewById(R.id.pwr_btn);
btn_pwrtoggle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(!buttonMasher){
if(powerstat.equals("OFF")){
String[] commandToSend = {"POWER","ON"}
}else{
String[] commandToSend = {"POWER","OFF"};
}
deviceControl(commandToSend);
}
startButtonMashTimer();
}else{
Log.w("button masher","slow down there, monkey.");
}
}
});
Then, in the actual Activity:
Timer buttonTimer;
TimerTask buttonMonitorThread;
int chimpCrackCounter;
protected void startButtonMashTimer() {
chimpCrackCounter = 0;
buttonTimer = new Timer();
buttonMonitorThread = new TimerTask(){
#Override
public void run(){
buttonMasher = true;
if(chimpCrackCounter == 1){
buttonMasher = false;
buttonTimer.cancel();
}
chimpCrackCounter++;
}
};
buttonTimer.schedule(buttonMonitorThread, 0, 500);
}
It seems to be working just fine, (and may help somebody having the same difficulty) but I'm open to suggestions.
An easy way to prevent a user from pushing a button too often is to save the time when a button was pushed, and then next time compare the last time with the current time and if the difference is too small, ignore the action.
final static long minTimeBetweenClicks = 1000;
long lastTime;
onClick(View v){
if( System.currentTimeMillis() < lastTime + minTimeBetweenClicks ) return;
//Handle the click
lastTime = System.currentTimeMillis();
}
The beauty of this is that it doesn't require any new threads or timers, and your AsyncTasks won't have to know about the buttons.
Disable the Button after a click (setEnabled(false), perhaps in onPreExecute, and enable after the task is done, in onPostExecute.
Also, be sure to pay attention to lifecycle changes. Your AsyncTask may be killed if the Activity is paused, so be sure to check the state in onResume.

Categories

Resources