I'm working as a football (soccer) referee in Israel and I was asked to write an application that simulates our fitness test for the upcoming season.
The test is an interval test, and the user can enter how much time does he run, walk and for how many sets.
There is a beep sound for each time you should start/stop running (beep variable is of type MediaPlayer). The chronometer should reset each time you finish running / walking.
The following code almost works - The beep sounds are heard in the right time and stop after the right number of sets, but the screen gets stuck right after the chronometer starts...
I would really appreciate your kind help!
Thanks, Yaad
private void testLoop() {
int i = 0;
boolean flag = true; //true = running, false = walking
chronometer.setBase(SystemClock.elapsedRealtime());
chronometer.start();
//run, walk, rep = integers that are set by user input
beep.start();
tvRunWalk.setText("Running");
tvRepNum.setText(String.format("Repetition Number: %d", i + 1));
while (i < rep) //rep = number of repetitions
{
if (SystemClock.elapsedRealtime() - chronometer.getBase() == run * 1000 && flag) //if running time is over and you are now running
{
chronometer.setBase(SystemClock.elapsedRealtime());
flag = false;
tvRunWalk.setText("Walking");
beep.start();
}
else if (SystemClock.elapsedRealtime() - chronometer.getBase() == walk * 1000 && !flag) //if walking time is over and you are now walking
{
chronometer.setBase(SystemClock.elapsedRealtime());
flag = true;
i++;
tvRunWalk.setText("Running");
tvRepNum.setText(String.format("Repetition Number: %d", i + 1));
beep.start();
}
}
}
Your while loop is blocking the UI. You better use AsyncTask and put your loop in its doInBackground() method in order to properly update the UI.
More info here: http://developer.android.com/reference/android/os/AsyncTask.html
Related
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()
I am working on a game (my first) for Android. I want a function like a lot of games do where a "consumable" regenerates over time. I want to display the countdown timer for a +1 on the consumable. When it reaches 0, i want the timer to reset and start over, while the consumable increases by 1. If the consumable is at it's pre-defined max, I want the timer to stop until the consumable is used, then systematically start again.
public class MainActivity extends Activity {
int currentConsumable = 2;
int maxConsumable = 5;
boolean isConsumableMaxed = false;
long timeToAddConsumable; //unknown calculation for 10 minutes
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView countDown = (TextView) findViewById(R.id.countDownDisplay);
if (currentConsumable==maxConsumable) {
isConsumableMaxed = true;
//some function to stop the timer
} else { isConsumableMaxed = false; }
//function to begin countdown and setText to countDown's TextView
....
}
}
What I am looking for assistance with is how to calculate the time I need (10 minutes - but i'd prefer the equation so I can change it without asking for the specific time again).
I would also like to know how to get a countdown to begin and display it on countDown, as well as how to cancel it when isConsumableMaxed == true.
Note - the countdown should continue when the game is closed.
Thanks in advance for your assistance.
I have actor Rectangle and powerUp Rectangle and I want that when It collides with actor will have power for 10 seconds. This was achieved as follows :
if (powerBoxRect.overlaps(actorRectObj)) {
powerUpTime = System.currentTimeMillis() + 10000;
}
if (powerUpTime > System.currentTimeMillis()) {
powerActor = IMMUNEACTOR;
}
But as I have taken any power and press pause button my game is go to paused state and after 10 seconds when I resume my game,power is lost because meanwhile system time is running.
I want to know that how can I stop system time or libgdx provides any other feature to handle this situation?
float time = 0;
int maxTime = 3;
public void update() {
time += Gdx.graphics.getDeltaTime();
if(time > maxTime) {
// DO YOUR THING
}
}
Hi everyone This is my first post so please be gentle. Even though my android final is complete and all i still find it hard to not continue to adjust my program and add to it just for the fun of it. what it is is a simple program that when you touch the screen the character on the screen laughs one of two ways with matching vibration. It works nicely but when my teacher (who was in a foul mood at the time) went to test it he pretty much button mashed the thing which made it que up every button press and we had to sit through like 15 laughter fits before we could do anything more with the phone. What i want to do is just have one touch event count until the first event is complete. what it is is a simple on touch event with a couple nested if statements.
public boolean onTouch(final View v, MotionEvent m)
{
v.setBackgroundResource(R.drawable.laughing);//changes the image to the laughing monkey
if (m.getAction() == MotionEvent.ACTION_DOWN)
{
if (timesTouched != I) //checks to see if the touch amount is not equal to the random number
{
if(laughter != 0)
{
sp.play(laughter, 1, 1, 1, 0, 1);//plays the loaded sound when the screen is pressed
//vib.vibrate(900);
}
Time = 900;
timesTouched++;
intDelay = 1;
if(vibon == 1)
{
vib.vibrate(Time);
}
}
else if (timesTouched == I)//checks to see if the touch amount is the same as the random number
{
if(laughter != 0)
{
sp.play(laughFit, 1, 1, 1, 0, 1);//plays the loaded sound when the screen is pressed
}
Time = 6000;
timesTouched = 0;
intDelay = 1;
if(vibon == 1)
{
vib.vibrate(laugh, -1);
}
}
}
else if((m.getAction() == MotionEvent.ACTION_UP) && (intDelay == 1))
{
try {
Thread.sleep(Time);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
v.setBackgroundResource(R.drawable.normal) ;//returns the image to the normal looking monkey
intDelay = 0;
}
return true;
}
}
the sleep timer is there to prevent the background image from going back to the default before the laughter is over. I did attempt to get my teacher to help but he is just a speedy replacement and had never even touched an android device before starting to teach at the beginning of this year. please any help you can provide is greatly appreciated because so far i have had to pretty much teach myself this stuff with the help of Google searches.
Thanks a Bunch!
If this were me I would probably move the sound playing to a separate thread then use messages to notify that thread when to start and stop the sounds. In this way the button can send the message immediately and not be blocked by any subsequent actions. The side-effect should be that every button press stops the previous laughter and starts a new one (or just queues up another sound byte over the previous one effectively combining sounds). You could contrarily disable the button until the sound is finished but I do not believe that would be a good user experience - they would expect to be able to mash and mash to their hearts content!
Check out http://developer.android.com/resources/articles/painless-threading.html for more guidance on how to approach such a thing.
Basically i am developing a rss feed for android, and i want to have a updater service that, for each source, get the feeds in specific time.
Imagine:
Source1 - 5minutes
Source2 - 10minutes
Source3 - 10minutes
I build a differential list to use only one thread that make the requests for update.
The datastructure stays like this:
Source1 (next sleep - 5), Source2 (next sleep - 0, Source 3 (next sleep 5).. and so on..
What i do is, i add always to a list of providers (that contains the id and URL) and when sleep is != 0, i order the update (that uses async task, i pass the list of providers to update, and asynctask do the job for me, that is... go to internet, parse content, and update database)
but exists one worker thread that is sleeping just for the sake of group a bundle of providers and sent to AsyncTask to update.
What's the problem..
First the thread don't sleep for the specific time, the thread must sleep 10 minutes, i made a method for convert minutes to milis, that is:
private static int MinutesToMilis(int minutes) { return minutes * 1000 * 60; }
i am using alogcat, an widget on my phone and the thread sleeps about 25 minutes (WTF) :|
Other thing that i verified is that, when phone is charging, the service works OK...
Here is the code:
worker = new Thread(new Runnable()
{
#Override
public void run()
{
Provider[] enabledProviders = feedService.getAllProvidersEnabledData();
// Build a differential list from enabledProviders
DifList<Provider> list = getListForProviders(enabledProviders);
//
// Code starts here
int sleep;
DifNode<Provider> header = list.getFirst();
sleep = header.getInitial();
LinkedList<Provider> data = new LinkedList<Provider>();
Log.d(TAG, String.format("Worker thread started # %s", now()));
try
{
for(int idx = 0 ; true ; list.reorderFirst(), header = list.getFirst(), idx++)
{
Log.d(TAG, String.format("Iteration %s with sleep %s", idx, sleep));
if(sleep > 0) {
Log.d(TAG, String.format("Next download in %s minutes", sleep));
// Suspend worker thread for sleep time
Thread.sleep(MinutesToMilis(sleep));
Log.d(TAG, "Worker thread waked up from sleep");
}
// Add to data
data.add(header.getKey());
// Set next sleep time
sleep = header.getDifference();
if(sleep != 0)
{
Log.d(TAG, "Worker preparing for update..");
//
// If difference to next is not 0 we dump data to async task
for(Provider p : data){
Log.d(TAG, String.format("Starting update %s # %s", p.Name, now()));
}
Provider[] arrayData = new Provider[data.size()];
data.toArray(arrayData);
data.clear();
new UpdateBundleOfFeedsTask().execute(arrayData);
}
}
}
catch(InterruptedException ex)
{
Log.d(TAG, String.format("Worker thread was interrupted # %s", now()));
isRunning = false;
}
Log.d(TAG, String.format("Worker thread exit # %s", now()));
}
});
You should really not be doing it that way, ie having a thread that never dies. I strongly suggest you have a look at alarms : http://developer.android.com/reference/android/app/AlarmManager.html
A good way to go would be :
set a repeating alarm, maybe one with a different pendingIntent for each client, although in your case its seems to be a little too frequent to do that each 5-10 minutes only to read some RSS.
implement a broadcast receiver that listens to the pending intents set by your alarm.
from the broadcast receiver, start a service that starts a worker thread to read from the network and save to DB.