I've created a button to trigger a pulse LED action on my app, but I cant make it pulse forever. It always Pulses by value ( on the example above you will see it pulses 10 times and then stops )
//Button Pulse
Button bpulse = (Button) findViewById(R.id.bpulse);
bpulse.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
Intent led = new Intent(IlluminationIntent.ACTION_START_LED_PULSE);
led.putExtra(IlluminationIntent.EXTRA_PACKAGE_NAME, "com.devsgonemad.xslc");
led.putExtra(IlluminationIntent.EXTRA_LED_ID,
IlluminationIntent.VALUE_BUTTON_2);
led.putExtra(IlluminationIntent.EXTRA_LED_NO_OF_PULSES, 10);
led.putExtra(IlluminationIntent.EXTRA_LED_PULSE_ON_TIME, 1000);
led.putExtra(IlluminationIntent.EXTRA_LED_PULSE_OFF_TIME, 1000);
led.putExtra(IlluminationIntent.EXTRA_LED_COLOR, m_ledColor);
startService(led);
m_isEnabled = true;
}
How can I make this pulse forever when the button is pressed until the user goes back to the app and stops it from pulsing?
Best regards
How about using a while loop? You could put the number of pulses as 1, and let this run continuously in a while loop, until some condition (in your case some button is pressed) is satisfied.
while(buttonNotPressed){
led.putExtra(IlluminationIntent.EXTRA_LED_NO_OF_PULSES, 1);
startService(led);
}
Ofcourse this has an obvious pitfall that you may start many parallel services all trying to flash the LED once. But I guess you can control your while loop to wait for the service to end before you start the next iteration.
EDIT: For the while loop to wait for your service, you will need to add some sort of flag inside your service on which the while loop can wait. Once the service finishes, the flag can be set and the while loop can move onto the next iteration, thus giving you infinite rounds of flashes until the button is pressed.
Related
I am making a board game were I have 3 AI players and a user playing. When the user presses a Button to give its turn up to the AI's I want to add a delay so the user can see every move each AI makes.
I have tried a thread sleep and handler but it seems they are unable to update the board and add a delay with each iteration of the while loop. The code without any attempt to add a delay can be found below. I would need to add a delay after the inner while loop terminates.
public void onClickNextTurn(View view){
boolean turnFinished;
findViewById(R.id.btnChangeTurn).setVisibility(View.INVISIBLE);
while (this.playerTurn<4) {
this.playerTurn++;
turnFinished=false;
while (!turnFinished) {
diceRoll();
MoveTriplet result = ai[playerTurn-2].aiTurn(this.boardPieceLocations, this.homeLocations, this.finishLocations, this.roll, playerTurn);
if (result != null) {
if (result.getMoveType() == 'b') { //The Artificial Opponent is moving from one home location to the board AND gets to roll again
this.homeLocations[playerTurn - 1][result.getPreviousIndex()] = 0;
if (this.boardPieceLocations[result.getNextIndex()] != 0)
returnPieceHome(this.boardPieceLocations[result.getNextIndex()]);
this.boardPieceLocations[result.getNextIndex()] = this.playerTurn;
this.homeButtons[playerTurn - 1][result.getPreviousIndex()].setBackgroundColor(getResources().getColor(R.color.colorHoles));
this.buttons[result.getNextIndex()].setBackgroundColor(colors[playerTurn - 1]);
}
So if anyone could point me in the right direction on how I could add an delay between iterations of the outer while loop and at the same time updating the my board. Thanks in advance!
Try looking at the standard Android animation APIs. Those should handle the timing for you and be smoother anyways -- plus, they'll use the GPU more efficiently for you.
I have a function goClicked which is a onClick method of "Go" button, but when clicking the button, the function is not executed (I am able to say this because the toast is not showing).
But if I comment the while loop then click on the "Go" button, the function is executed (the toast is appearing).
public void goClicked(View view) {
afterGoPressed();
Toast.makeText(MainActivity.this,"pressed",Toast.LENGTH_SHORT).show();
countDown();
correctCount = 0;
totalCount = 0;
TextView time = (TextView) findViewById(R.id.time);
String timetext = time.getText().toString();
while (!timetext.equals("0")) {
int sum = generateQuestion();
pickOption = generateOptions(sum);
}
}
By putting a tight loop like that into your code the Event Dispatch Thread (EDT) is "starved" and so the GUI never gets a chance to do anything.
A simple workaround would be add a bit of a sleep in the loop to let the EDT have a turn. But you really need to do a bit more research into how to do GUI programming.
As it stands the code looks like an infinite loop because the timetext variable used in the loop condition does not change inside the loop. timetext is presumably supposed to change in reaction to GUI events. If the GUI is starved and so doesn't get to run then timetext never changes.
I think you're dealing with an infinite loop.
If when you create the variable timetext the text contained in time is not 0, the variable timetext will never be 0, hence the condition to exit the loop is never met.
public void goClicked(View view) {
afterGoPressed();
Toast.makeText(MainActivity.this,"pressed",Toast.LENGTH_SHORT).show();
countDown();
correctCount = 0;
totalCount = 0;
TextView time = (TextView) findViewById(R.id.time);
String timetext = time.getText().toString(); // <--- this will never change
while (!timetext.equals("0")) {
int sum = generateQuestion();
pickOption = generateOptions(sum);
}
}
Sorry, I know this doesn't offer much of a practical solution to your issue. Maybe if you let us know what you're trying to achieve with that loop we can help a little better.
But for all I know, if you block a thread inside of the public void onClick(View view) method of a View.OnClickListener instance (either by making it sleep with Thread.sleep() or by running an infinite loop), it will also freeze the rest of your app until the onClick(View view) method finishes. That's why you can't even see the Toast appear, although it's before the while loop. Because the main Thread was notified that there has been a click event, but the response from that event is never arriving.
First app ever for me, and first time experiencing with java coding.
I'm building an app for assisting my Rubiks cube speed training, and i'm stuck on my timer.
My general plan is:
I have my main activity screen, where with 1 touch (anywhere on the screen except my 2 buttons) can start a timer. When the timer starts the buttons will fade, and only the timer is visible.
At this moment I have my MainActivity, and a Timer activity. When pressing the screen the timer activity "launches". I then have to press once more to start the timer, this is ok for now, I will fix it somewhat later.
My main goal for now is:
On the timer activity, I want to press and HOLD for at least 2 seconds, and THEN upon release, the timer must start. Hereafter, with a new click, the timer must stop.
I have searched, but it is difficult with minimum knowledge. I have tried a few different things. And what I have is basically something like this.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_timer);
TimerView = (TextView) findViewById(R.id.TextTimerView);
View StopTimeView = (View) findViewById(R.id.StopTimeView);
StopTimeView.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
starttime = SystemClock.uptimeMillis();
timerhandler.postDelayed(timerrunnable,2000);
timestarted = true;
}
if (event.getAction() == MotionEvent.ACTION_UP) {
if(timestarted = true){
timestarted = false;
timerhandler.removeCallbacks(timerrunnable);
}
}
return true;
}
});
}
This code stops when the touch is released. If I remove the last IF sentence, the timer automatically starts after the given 2 seconds, no matter if I hold or not. Furthermore, I need to add an additional button to stop the timer, which I do not want (the ability to be able to stop by touching everywhere is important).
I hope the question is understandable and not to vague. If more of the code is needed, please let me know.
Thanks for your time!
Simply check in your timerrunnable if the button is still pressed. Also, start the onTouch method with a check whether your timer is running. If it is, you know you want to stop it - if it isn't, you can continue with the code you already have.
i made an android game once i minimize it,
it resets data and refresh the timer like you started the game from the scratch
how can i make it Don't do this
i think the problem is on the OnStart function
protected void onStart() {
super.onStart();
// Reset score
Configs.score = 0;
scoreTxt.setText(String.valueOf(Configs.score));
// Set progressBar and start the gameTimer
pb = (ProgressBar)findViewById(R.id.gbProgressBar);
progress = 0;
pb.setProgress((int) progress);
startGameTimer();
// Get a random circle for letters
Random r = new Random();
randomCircle = r.nextInt(Configs.circlesArray.length);
// Reset taps count
tapsCount = -1;
// Get a random word from words string-array
getRandomWord();
}
onStart is called every time the app starts. onCreate on the other hand, is only called when the app starts or after the activity process has been killed and restarted. Usually the last scenario means after onStop is called and the activity process is killed, but it isn't destroyed yet.
Move that code to onCreate, otherwise it calls that every time the app is reopened which resets it
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.