Can anyone help?
=====================================================
I tried like this:
Animation zoom, zoom_out;
zoomAnimation();
private void zoomAnimation() {
zoom= AnimationUtils.loadAnimation(this,R.anim.fast_zoomin);
avatar.startAnimation(zoom);
//question
if (zoom.hasEnded()){
zoomoutAnimation();
}
//question
}
private void zoomoutAnimation() {
zoom_out= AnimationUtils.loadAnimation(this,R.anim.fast_zoomout);
avatar.startAnimation(zoom_out);
}
I'm not sure I understand the question correctly.
But I think that you need just to add a module. When the animation ends, the object still exist, so you can connect an action with an intent-filter.
Hope to be of help
I made it so that when the animation started, exactly as many seconds elapsed as the animation lasted, after that another action will begin (C help of the Handler method).
private void zoomAnimation() {
zoom = AnimationUtils.loadAnimation(this,R.anim.fast_zoomin);
zoom_out = AnimationUtils.loadAnimation(this,R.anim.fast_zoomout);
avatar.startAnimation(zoom);
if (!zoom.hasStarted()){
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
avatar.startAnimation(zoom_out);
}
}, 1500); //seconds after which another action will start when
//condition that the first one started
}
}
Related
One part of my activity needs two timers running at once, one of them using Handler and the other using CountDownTimer. The handler portion updates the display every second, while the CountDownTimer counts down to when this part of the code ends. For some reason, I cannot run these both at the same time, and even when I commented out the CountDownTimer portion, the handler portion only ran once, instead of repeating every second. I am at a loss for what to do here. Any ideas? The relevant part of the code is below. For some clarification, the first handler seen here is supposed to run on its own, until a condition is met, at which point it reruns the function and goes to the second if statement. Seen within the second if statement are the details I mentioned at the beginning.
private void statusCheck() {
if (possible = true) {
final Random random = new Random();
final Handler handler1 = new Handler();
final int delay1 = 1000; //milliseconds
handler1.postDelayed(new Runnable() {
public void run() {
runChance = random.nextInt(1000);
if (runChance < 100) {
possible = false;
statusCheck();
}
}
}, delay1);
}
if (possible = false) {
final Handler Handler = new Handler();
final int Delay = 1000; //milliseconds
Handler.postDelayed(new Runnable() {
public void run() {
// code to update every second
}
}, Delay);
new CountDownTimer(ghostDuration, 1000) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
//code to run when finished
}
}.start();
}
}
First of all it's not a good idea to to run timer and tasks under Android that way.
Android will block these timer and tasks because they work against the framework.
If you want to implement it correctly with a WorkManager watch out this video from Google which gives you some fundamentals: Android Jetpack WorkManager
I'm new to Android and I'm working on a tiny project with a set of strict parameters. One of them is to have a multifunction button that increments a timer every time it's clicked, and that starts only after I didn't increment said timer for 3 seconds.
I found three or four ways on how to set an alarm of sorts with Handler, CountDownTimer, Timer, or some other way, but I'm confused on how I can do what I'm looking for with just the onClick() method.
The function to wait for 3s(), I'm calling it after:
public void wait3s()
{
Thread thread = new Thread() {
#Override
public void run()
{
while (!isInterrupted()) {
try {
Thread.sleep(3000);
runOnUiThread(new Runnable() {
#Override
public void run() {
count++;
threeS.setText(String.valueOf(count));
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
thread.start();
}
My onClick() just calls these:
public void onClick(View view)
{
increment();
wait3s();
startStop();
}
As you can see, part of the issue is that I'm calling the wait3s() there at every click, and I need a way to control that Thread/Timer (whatever) without it creating a new one at every click. I'm being a little dumb now, but I have been on this for a while and I'm still coming out empty, since I never worked with this before.
Another option for the wait3s() function that I found would be like in this other StackOverflow thread.
Thank you
PS: Sorry for the title, I couldn't find a better way to describe it, if you have it, and have the power to change it, please do.
Handler.removeCallbacks will effectively cancel a runnable.
boolean timerStarted = false;
clockHandler = new Handler();
OnClick(){
if (!timerStarted){
incrementTimer();
clockHandler.removeCallbacks(null);
clockHandler.postDelayed(new Runnable() {
#Override
public void run() {
// maybe kick off another handler/runnable here to start your timer
timerStarted = true;
}
}
}, 3 * 60 * 1000);
} else {
startStop();
}
}
Here's how I solve it. Although the suggestions were closer, they weren't exactly spot on to what I was looking for, in terms of logic, they weren't exactly helpful, creating more issues. Perhaps it's due to my explanation of the problem, perhaps because I'm new to Android Studio and the explanations shared here with me. Pardon me if it looks like I'm just using my own answer for internet points, I just had to put a lot more to understand this by myself than what I actually got from the answers shared here.
public void wait3s()
{
t.schedule(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
startStop();
}
});
}
}, 3000);
}
The variable t is a Timer(), and I had to import the classes java.util.Timer, and java.util.TimerTask. I called this method inside my increment() method and under onClick() I just have the increment() method. Turned out pretty neat.
I'm playing around with some basic android, and I'm trying to write a metronome app. The basic idea is that I'm using a runnable in order to trigger a sound after a time period (msPeriod). I've tried to use SoundPool, but it will just log 'sample not loaded', and trying to ititialise a MediaPlayer causes the app to crash on opening. Could you explain to me where I'm going wrong please? Below is my code with MediaPlayer.
//I create the media player first thing inside MainActivity
private Handler handler = new Handler();
int msPeriod = 1000;
MediaPlayer mpHigh = MediaPlayer.create(this, R.raw.hightick);
MediaPlayer mpLow = MediaPlayer.create(this, R.raw.lowtick);
//within an onClick Listener
onClick(View v) { handler.postDelayed(startMetron, msPeriod); }
//the runnable that starts the metronome
private Runnable startMetron = new Runnable( ) {
#Override
public void run() {
if(isRunning){
if (count == 4) {
count = 1;
mphigh.start();
} else {
count++;
mplow.start();
}
}
textCount.setText(String.valueOf(count));
//triggering the next run
handler.postDelayed(this, msPeriod);
}
};
Thanks so much for bearing with me!
You are running a separate thread . The UI element must be updated form the main thread... so..
runOnUiThread(new Runnable(){
public void run() {
textCount.setText(String.valueOf(count));
}
});
This makes sure that the textview is update from the UI thread and your app will not crash.
I recently began working with Java and am exploring Android development. I was trying to port over one of the Java programs I made, but I am having some difficulty with getting the java Timer to function the same way in Android. I read through a number of posts and they, for the most part, indicated that it would be better to use the Handler class in android as opposed to Timer.
This was my timer in Java:
playTimer = new Timer(1000/model.getFPS(), new ActionListener() {
public void actionPerformed(ActionEvent evt) {
// do something
...
if( finished everything ) playTimer.stop();
}
});
And once a certain button was clicked, I would simply run "playTimer.start()" to start it.
As you can see, I had it set up so that the user could set the FPS they wanted (by simply setting the first parameter of the Timer class to 1000/model.getFPS()).
Now I've tried to do something similar in Android using handlers, but I am having some difficulty. It appears that the Handler ticks are not firing at the proper intervals. It seems that they are quite slow compared to what I need it to be. This is what I did in android so far:
public void startTimer() {
playHandler = new Handler();
startTime = System.currentTimeMillis();
playHandler.removeCallbacks(updateTimeTask);
playHandler.postDelayed(updateTimeTask, 0);
}
private Runnable updateTimeTask = new Runnable() {
public void run() {
// do something
...
if( finished everything ) playHander.cancel();
else {
playHandler.postDelayed(updateTimeTask, 1000/model.getFPS());
}
}
};
Excuse the semi-pseudocode. Can anyone shed any light? Thanks guys.
You can use a timer as below. The timer runs every second incrementing the counter. Displs the counter value in textview.
Timer runs on a different thread. SO you should set the text on the UI Thread.
The counter runs from 0 to 99. After 99 the timer is cancelled. Also cancel the timer when not required like in onPause().
public class MainActivity extends Activity {
TextView _tv,tv2;
Timer _t;
int _count=0;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
_tv = (TextView) findViewById( R.id.textView1 );
_t = new Timer();
_tv.setText(R.string.app_name);
_t.scheduleAtFixedRate( new TimerTask() {
#Override
public void run() {
_count++;
runOnUiThread(new Runnable() //run on ui thread
{
public void run()
{
_tv.setText(""+_count);
if(_count==99)
{
_t.cancel();
}
}
});
}
}, 1000, 1000 ); //change this value of 1000 to whatever you need.
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
_t.cancel();
}
}
If you decide not to use Timer (for whatever reason) you can just write a separate Thread that sleeps for x milliseconds and then wakes up and calls whatever Runnable you want it to call. That's going to be pretty precise. I have it working at the 10 millisecond level and it works quite nicely.
Just remember that it HAS to call a Runnable because a separate Thread can't have direct effect on anything on the main display thread.
public boolean keepPlayingAnimation = true
Handler h = new Handler()
Runnable updateDisplay = new Runnable(){
public void run(){
//do something in my display;
}
}
new Thread(){
public void run(){
while(keepPlayingAnimation){
try{
sleep(10);
}catch(Exception e){
}
h.post(updateDisplay);
}
}
}.start();
Just don't forget to set keepPlayingAnimation to false when you're done with this cause otherwise it will sit there running in the background for ever (or just about).
Take a look at Android Timer
It already has everything you need i guess. From ticking every 1 second to finish handly and so on.
Here is an example how to setup an TimerTask: setup
Not sure if you need such but i just remembered that i made this.
I've got an activity that keeps reading words to the user, and using onUtteranceCompleted with textTospeech to display something when the code is completed.
Inside onUtteranceCompleted I have this code to delay a function with a second:
Runnable task = new Runnable() {
public void run() {
//runs on ui
runOnUiThread(new Runnable() {
public void run() {
readWord();
}
});
}
};
worker.schedule(task, 1, TimeUnit.SECONDS);
This seems like it works well, but I think it is causing a problem.
When I rotate the screen of my phone (I guess this starts a new activity).
I hear some words being read in the background. I guess this is because of runOnUiThread() which makes the activity continue in the background.
How could I avoid 2 activities running ? I would prefer if I don't have to stop the screen from rotating on doing some weird patch!
Thank you
EDIT:
public void readWord() {
if (this.readingOnPause) {
return;
}
txtCurrentWord.setText(currentItem[1]);
this.hashAudio.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID,"word");
this.tts.setLanguage(Locale.US);
this.tts.speak(this.currentItem[1], TextToSpeech.QUEUE_FLUSH,this.hashAudio);
}
EDIT2:
instantiation of worker:
private static final ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor();
I would use a Handler instead of runOnUiThread().
For one thing, you're using a Thread that starts another Thread - why?
Secondly, if you create a simple Handler, it should kill itself on the rotate config change. IE:
private Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
// do your background or UI stuff
}
};
Then later use a Thread to call the handler, which will kick off whatever process you want to run on the UI thread:
new Thread() {
#Override
public void run() {
long timestamp = System.currentTimeMillis();
// thread blocks for your 1 second delay
while (System.currentTimeMillis() - timestamp <= 1000) {
// loop
}
handler.sendEmptyMessage(0);
}
}.start();
Ok so this is a fix I've come up with, if someone has a better solution, I'm listening.
I've added android:configChanges="keyboardHidden|orientation" inside the activity in the androidmanifest
2.
and then a function that is called when the screen is rotate:
#Override
public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
setContentView(R.layout.streaming);
initializeUI(); //contains all the findViewByID etc...
}