resetting SystemClock.currentThreadTimeMillis() - java

I have a button that appears at the end of my app when the game is complete that is meant to reset the app. I have tested it and it works besides the timer. I have does not reset to the "startTime". I have a button that is used to reset the game such as:
if(resetButton.getText().equals("Restart"))
{
reset_flag = true;
Intent i = getBaseContext().getPackageManager()
.getLaunchIntentForPackage(getBaseContext().getPackageName());
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
I have a runnable for the timer as:
long gamerestart = SystemClock.currentThreadTimeMillis();
if(reset_flag)
{
gamerestart = 0;
startTime = 60000;
flag = false;
}
timeInMilliseconds = startTime - gamerestart;
The reset_flag did help as I noticed the time at the top of the game reset to the original time but at the next time-tick it updated to whatever the currentThreadTimeMillis is.
I did try doing SystemClock.currentThreadTimeMillis() = 0; but that did not work ( I was not surprised it didn't either..)
I did not see a function within SystemClock that would doing any resetting. I thought this would be a simple task but maybe it is not, could anyone give me some help? Thanks.

That time is how long the thread has been alive, consider using a separate variable for timing. You can always initialize it to SystemClock.currentThreadTimeMillis() and deduct SystemClock.currentThreadTimeMillis() whenever you want to display the value

Related

How to make a delay in processing project?

I'm using Java within a Processing project. I'm trying to make a delay that doesn't stop the program, but stops only a given block of code. That "processing" block of code could for example add 1 to a variable, then wait one second and then add 1 again. The problem is that delay() (see reference) stops the whole program and Thread.sleep() doesn't work in a Processing project.
You should not use delay() or Thread.sleep() in Processing unless you're already using your own threads. Don't use it on the default Processing thread (so don't use it in any of the Processing functions).
Instead, use the frameCount variable or the millis() function to get the time that your event starts, and then check that against the current time to determine when to stop the event.
Here's an example that shows a circle for 5 seconds whenever the user clicks:
int clickTime = 0;
boolean showCircle = false;
void draw(){
background(64);
if(showCircle){
ellipse(width/2, height/2, width, height);
if(clickTime + 5*1000 < millis()){
showCircle = false;
}
}
}
void mousePressed(){
clickTime = millis();
showCircle = true;
}
Side note: please try to use proper punctuation when you type. Right now your question is just one long run-on sentence, which makes it very hard to read.

android: taking pictures in task or thread at regular interval?

I'm writing an android app which should take pictures in a user-defined interval (20 sec - 1 min). It should take the pictures even while it is running in background or while the device is sleeping. The app will run for a very long time period. If it is necessary to wake up the device, it should put back to sleep as soon as possible to save batterie life. After taking a picture the app will process some additional work (comparison of two pictures).
I read some stuff about sheduling alarms (http://developer.android.com/training/scheduling/alarms.htm), creating Services (also # android training) and Android AsyncTasks, Java threads (http://www.mergeconflict.net/2012/05/java-threads-vs-android-asynctask-which.html)
... but I'm still not sure what is the best way to achieve this.
My questions are:
Should I use thread or a task to take the pictures in background?
(the comparison of the two pictures might take longer than a few
milliseconds but i don't know anything about the cpu load of this
operation)
Should I use an alarm to wake the device up or are there any alternative solutions?
How can both (alarms and thread/task) work together? (Include the Alarm in the Task/Thread?)
Many thanks for your help in advance.
As to our question I know I can help get started with the aspect of repeating the picture taking task at a user defined time interval. For such a task you can user a Timer to achieve this. The code would look something like this:
mTmr = new Timer();
mTsk = new TimerTask() {
#Override
public void run() {
//Take picture or do whatever you want
}
};
mTmr.schedule(mTsk, 0, USER_DEFINED_EXECUTION_INTERVAL);
schedule begins the timer. The first parameter of schedule used here is the task to run which is mTsk. The second parameter is the delay until the first execution (in milliseconds), in this case no delay. The third parameter is what you'll want to manipulate which is the interval of executions. The parameter is the time between executions so if it were 20 seconds you'd pass in 20,000. If it were a minute it would be 60,000. You can get this value from the user using any method you'd like.
To keep the timer running make sure you don't call mTmr.cancel in onPause because for your case you want to keep the timer running while the user isn't on the app. Not calling cancel means the timer will hold it's resources until the app is closed by the user.
OR you can look at this How to schedule a periodic task in Java? If you'd like to use ScheduledExecutorService instead of a Timer.
I have made this app - Lenx. It uses Camera extensively and I am processing image in the background. I have used AsyncTask to process the image and it has never given any problems. The app also has a timer which starts the process after certain interval. The logic that I have used is very simple.
I have not used Camera2 API yet, so the code might be deprecated. I created CameraPreview class which implements Camera.PreivewCallback.
#Override
public void onPreviewFrame(byte[] data, Camera camera) {
if (data == null) {
return;
}
int expectedBytes = previewWidth * previewHeight *
ImageFormat.getBitsPerPixel(ImageFormat.NV21) / 8;
if (expectedBytes != data.length) {
Log.e(TAG, "Mismatched size of buffer! Expected ");
mState = STATE_NO_CALLBACKS;
mCamera.setPreviewCallbackWithBuffer(null);
return;
}
if (mProcessInProgress || mState == STATE_PROCESS_IN_PROGRESS) {
mCamera.addCallbackBuffer(data);
return;
}
if (mState == STATE_PROCESS) {
mProcessInProgress = true;
processDataTask = new ProcessDataTask();
processDataTask.execute(data);
}
}
public void startProcessing() {
mState = STATE_PROCESS;
}
And my AsyncTask is something like this
private class ProcessDataTask
extends
AsyncTask<byte[], Void, Boolean> {
#Override
protected Boolean doInBackground(byte[]... datas) {
mState = STATE_PROCESS_IN_PROGRESS;
Log.i(TAG, "background process started");
byte[] data = datas[0];
long t1 = java.lang.System.currentTimeMillis();
// process your data
long t2 = java.lang.System.currentTimeMillis();
Log.i(TAG, "processing time = " + String.valueOf(t2 - t1));
mCamera.addCallbackBuffer(data);
mProcessInProgress = false;
return true;
}
#Override
protected void onPostExecute(Boolean result) {
mState = STATE_PROCESS_WAIT;
}
}
onPreviewFrame() will always get called as long as the camera preview is running. You need to take the data and process it only when you trigger something. So simply change the state of a variable, in this case, mState, and based on the state, call your AsyncTask.

CountDownTimer continues to tick in background — How do I retrieve that count in onResume?

I have an app with multiple timers; when I start one, I can see it counting down in Logcat in Eclipse.
When I hit the Back button, onStop() is called in the app but the timer continues to countdown in logcat (the onTick() is continuing to tick away).
What I would like is when onResume() is called, I want to get that timer which is still counting down and continue it. Is this possible?
Here are my buttons that start the countdown:
//Button1 Timer
final CountDown button1 = new CountDown(420000,1000,bButton1);
bButton1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
button1.start();
long currentTime = System.currentTimeMillis();
//Set start time for calculating time elapsed if needed
saveTime("START_TIME_BUTTON1", currentTime);
}
});
//Button2 Timer
final CountDown button2 = new CountDown(360000,1000,bButton2);
bButton2.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
button2.start();
long currentTime = System.currentTimeMillis();
//Set start time for calculating time elapsed if needed
saveTime("START_TIME", currentTime);
}
});
My onResume() looks like this:
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
//Reset the timers on appropriate buttons if there was something running
//If nothing was running or timer finished - have button in default state
//See if there was a button1 timer running - if not, it will be 0
SharedPreferences start = PreferenceManager.getDefaultSharedPreferences(this);
long startTime = start.getLong("START_TIME_BUTTON1", 0);
long timeElapsed = (System.currentTimeMillis()-startTime);
long timeRemaining = (420000 - timeElapsed);
if (timeRemaining == 0) {
} else if (timeRemaining > 0) {
final CountDown button1Timer = new CountDown(timeRemaining,1000,bButton1);
button1Timer.start();
long currentTime = System.currentTimeMillis();
saveTime("START_TIME", currentTime);
} else {
}
}
This actually works — the onResume() starts another timer right where the first one would be, and the text displays the appropriate number and continues counting down with the onTick() method. But now logcat shows 2 timers counting down instead of just one!
Ultimately I wouldn't want to start another timer, I just want to pick up the first timer I started where it is currently in the countdown at and have the onTick() display appropriately. Is there a way to do that? Would services be what I'm looking for? Is it already a service since it continues to tick down in the background?
I'm a little confused on what would be best practice to get this done.
onTick() will continue being called until either the time remaining reaches 0 or you call cancel() on the CountDownTimer.
So in your onStop() method you will need to call cancel() on the timer you want to stop receiving onTick() notifications.
Android's implementation of CountDownTimer uses a Handler to perform timing by queuing a Message to be sent to the Handler after each tick. Unfortunately there is no way to pause the CountDownTimer, so I believe you will need to create a new Timer with the appropriate values like you're doing currently.
When you're calculating the timeElapsed, you shouldn't use System.currentTimeMillis() because it can be changed at any time, instead you should use SystemClock.elapsedRealtime(). System.currentTimeMillis() is the timer used for the wall clock (time and date) and so can change unpredictably, see the Android documentation.

Counting headset button clicks in BroadcastReceiver

Inside of the onReceive(Content context, Intent intent) method of my public class MediaButtonIntentReceiver extends BroadcastReceiver I need to count the number of headset button clicks (single, double, triple), which is denoted by KeyEvent.ACTION_DOWN of the ACTION_MEDIA_BUTTON.
What I have almost works, but my current algorithm sucks and is unreliable after a few times. Basically every successive ACTION_DOWN (hit within a certain number of milliseconds to the previous ACTION_DOWN) I do numClicks++. But also I need to see when the user is done pressing, so after each event I start a CountDownTimer, and if by the time it runs out there are no new clicks, then I'm done and now know the number of clicks.
The problems I'm running into are as follows: for one, the button itself seems noisy - if I press it too fast I usually miss a click. Two, after a few trials when the app it loaded, it starts getting random and I'm assuming that there are multiple CountDownTimer threads (is that the right word?) still running which screws my stuff up.
Anyways here's the main code snippet:
//note: thisClickTime uses System.currentTimeMillis()
if (action == KeyEvent.ACTION_UP) {
if (isDown == true) {
if (numClicks == 0 && lastClickTime == 0) {
//we have a new click
numClicks++;
lastClickTime = thisClickTime; //update the click time
isDown = false;
elapsedTime = thisClickTime - lastClickTime;
} else if (thisClickTime - lastClickTime < clickDelay) { //&& thisClickTime - lastClickTime > 10
numClicks++;
lastClickTime = thisClickTime;
isDown = false;
}
final int oldNumClicks = numClicks;
final CountDownTimer checkIfDone = new CountDownTimer(clickDelay, 10) {
public void onTick(long millisUntilFinished) {
if (oldNumClicks != numClicks) {
cancel();
}
}
public void onFinish() { //code that executes when counter is done
if (oldNumClicks == numClicks) {
//if user doesn't click anymore in time clickDelay + X milliseconds, then it's done
Toast.makeText(context, "Number of clicks: " + Integer.toString(numClicks), Toast.LENGTH_SHORT).show();
//reset state variables
numClicks = 0;
lastClickTime = 0;
}
}
}.start();
} else {
//?
}
}
For reference, I've been looking around at stuff like:
http://musicqueueproject.googlecode.com/svn-history/r83/trunk/src/com/yannickstucki/android/musicqueue/old/PlayerService.java
To see if there's a good way to register number of clicks. I don't really understand their code too well though, and from what I can see they only deal with single/double clicks (I may need triple and quadruple).
EDIT - uploaded the current code I'm working with. It works pretty decently most of the time. Here's what I've noticed though: if I do my button testing too close together in time, the results start screwing up and under counting the clicks. I think this is because other CountDownTimers from previous attempts are still open, and when they finish, they reset certain state variables (numClicks = 0, for one). So am I misusing the timer? I can't think of another solution though as I need some concept of elapsed time after the last click to determine when the clicking is done.
Thanks for any help.
If your BroadcastReceiver is registered in the manifest, the BroadcastReceiver will only exist for a single call to onReceive() -- subsequent broadcasts may result in another BroadcastReceiver instance. And a manifest-registered BroadcastReceiver cannot fork threads, as the whole process may get shut down once onReceive() is over.
I am skeptical that there a clean way to get your code to be reliable, as the media button simply was not designed for your intended use pattern.

Blackberry stopwatch implementation

I'm trying to write a blackberry app that is basically a stopwatch, and displays lap times. First, I'm not sure I'm implementing the stopwatch functionality in the most optimal way. I have a LabelField (_myLabel) that displays the 'clock' - starting at 00:00. Then you hit the start button and every second the _myLabel field gets updated with how many seconds have past since the last update (should only ever increment by 1, but sometimes there is a delay and it will skip a number). I just can't think of a different way to do it - and I am new to GUI development and threads so I guess that's why.
EDIT: Here is what calls the stopwatch:
_timer = new Timer();
_timer.schedule(new MyTimerTask(), 250, 250);
And here is the TimerTask:
class MyTimerTask extends TimerTask {
long currentTime;
long startTime = System.currentTimeMillis();
public void run() {
synchronized (Application.getEventLock()) {
currentTime = System.currentTimeMillis();
long diff = currentTime - startTime;
long min = diff / 60000;
long sec = (diff % 60000) / 1000;
String minStr = new Long(min).toString();
String secStr = new Long(sec).toString();
if (min < 10)
minStr = "0" + minStr;
if (sec < 10)
secStr = "0" + secStr;
_myLabel.setText(minStr + ":" + secStr);
timerDisplay.deleteAll();
timerDisplay.add(_timerLabel);
}
}
}
Anyway when you stop the stopwatch it updates a historical table of lap time data. When this list gets long, the timer starts to degrade. If you try to scroll, then it gets really bad.
Is there a better way to implement my stopwatch?
Here are a few tips:
keep track of the last "sec" value used to update the label, and exit from the run loop immediately if the newly-calculated "sec" value is the same - otherwise you're needlessly refreshing the UI with the same values which slows everything down
remove the synchronization in your run loop and just put the code that modifies the UI (setText call) in a UiApplication.getUiApplication.invokeLater() call (using an anonymous Runnable)
don't delete the re-add the label from the screen or maanger, you just need to call setText() and it should update - if it doesn't update then call invalidate() on the field and it will be redrawn
now that you've optimized your code and minimized the amount of actual UI drawing, it's safe to set the timertask interval to a lower value, such as 50ms, so that you have a smoother timer update
The most important thing to remember in making a fast UI is to only update the UI when you need to, and only update the fields that need to change. If you're calling methods like deleteAll() you're going to end up having the entire screen or manager refresh which is really really slow.

Categories

Resources