first of all, I'm a beginner to android world so please apologize me if it is stupid question..
I'm trying to do following:
Enable Mobile Data
Wait for 10 seconds
a. check if Mobile got IP address (data connected sucessfully)
b. if Not connected,Disable Data
c. Go to step 1
And these steps 1 to 3 are getting executed in For loop for User Given number of retries.
Now my problem is: I'm stuck at step No. 2. I'm unable to make waitfor(int seconds) function. I tried using Runnable PostDelayed method but it is not giving me required output.
for(retry = UserChoice; retry > 0 && !isDataAvailable ; retry -- ){
enableInternet()
delay(10)
isDataAvailable = GetInternetAvailibility()
if(!isDataAvailable){
disableInternet()
}
}
I tried to put isDataAvailable = GetInternetAvailibility() statement in postDelayed of handler but it is causing enableInternet() disableInternet() to execute at the same time while isDataAvailable = GetInternetAvailibility() gets executed after delay.
I can see from logs, that enableInternet() executes for UserChoice number of times without any delay.
Thread.sleep(10000) just freezes the UI for 10 seconds... How do I achieve this?
EDIT : Let me clear :
public void onClick(View v) {
// Perform action on click
for(i=0; i<3; i++ ){
System.out.println("Before..");
delay(5);
System.out.println("after..");
}
}
public void delay(int seconds){
milliseconds = seconds * 1000;
runOnUiThread(new Runnable() {
#Override
public void run() {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
System.out.println("XXX"); //add your code here
}
}, milliseconds);
}
});
}
Now whenever I click button I can see in logs that System.out prints message as:
Before
afterBefore
afterBefore
after
XXXXXXXXX
But I want:
Before
XXX
After.Before
XXX
After.Before
XXX
After.
try this:
public void check() {
isDataAvailable = GetInternetAvailibility()
if (!isDataAvailable) {
disableInternet();
enableInternet();
if (retry > 0) {
retry--;
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
check();
}
}, 10000);
}
}
}
This way may help you.
http://developer.android.com/reference/android/os/CountDownTimer.html
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
mTextField.setText("done!");
}
}.start();
Try Below code.Hope that it will help
int i = 0;
int j = 3;
method() {
if (i < j) {
System.out.println("Before..");
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
System.out.println("XXXXXX");
i++;
System.out.println("after");
method();
}
}, 1000);
}
}
I tried to put isDataAvailable = GetInternetAvailibility() statement
in postDelayed of handler but it is causing enableInternet()
disableInternet() to execute at the same time while isDataAvailable =
GetInternetAvailibility() gets executed after delay.
Put the if statement and disableInternet() in the postDelayed. enableInternet will get called, 10 seconds later it will check to see if the internet is available, if not it will disableInternet.
Related
I have a tune in my android app. I have added a feature that if user selects a time then the tune will repeat until the time ends. I have also added the feature of infinite time but when I run my app goes in ANR (not responding) mode.
if(tinydb.getString("timer").equals("infinity"))
{
boolean valid = true; //Here i want to play the tune for infinite time
while(valid)
{
water_player = MediaPlayer.create(MainActivity.this, R.raw.water);
water_player.start();
}
}
else
{
while(!timerText.equals("0h: 0m: 1s")) //Here i want to play the tune until the timer gets zero
{
water_player = MediaPlayer.create(MainActivity.this, R.raw.water);
water_player.start();
}
you can use setLooping for the first case
and for the second case
final Runnable r = new Runnable() {
public void run() {
water_player.stop();
}
};
handler.postDelayed(r, 1000); //your time in millisecond
with your code :
if(tinydb.getString("timer").equals("infinity"))
{
water_player = MediaPlayer.create(MainActivity.this, R.raw.water);
water_player.setLooping(true);
water_player.start();
}
else
{
water_player = MediaPlayer.create(MainActivity.this, R.raw.water);
water_player.start();
final Runnable r = new Runnable() {
public void run() {
water_player.stop();
}
};
handler.postDelayed(r, 1000); //your time in millisecond
}
Use countdownTimer to complete your goal in which you can set countdown timer till x seconds manually. when countdown finish process it will go to finish method and execute finish method code
CountDownTimer cntr_aCounter = new CountDownTimer(3000, 1000) {
public void onTick(long millisUntilFinished) {
mp_xmPlayer2.start();
}
public void onFinish() {
//code fire after finish
mp_xmPlayer2.stop();
}
};cntr_aCounter.start();
If you have only 2 cases, use a boolean.
boolean infinitely;
if(infinitely == true){
water_player = MediaPlayer.create(MainActivity.this, R.raw.water);
water_player.start();
}
else {
water_player = new MediaPlayer.create(MainActivity.this, R.raw.water);
water_player.start();
Handler handler = new Handler();
handler.postDelayed(new Runnable(){
water_player.stop();
}
}
, 2000);
The handler method will be executed when 2sec passed. (put your own desired time).
I have an android app which sends likes to the server.
What i want to do is not to send a like to server immediately but send after 2 secs if user still likes the post.
My like void;
public void rotationAnimation(ImageView button, int source1, int source2){
if(isLikeClicked){
button.setImageResource(source1);
button.startAnimation(rotate_backward);
isLikeClicked = false;
}else{
button.setImageResource(source2);
button.startAnimation(rotate_forward);
isLikeClicked = true;
}
ChangeLikeCount();
if(isReadyToPost)
if(!isLikeClicked){
Like like = new Like();
like.execute(ServerCons.HOST + "unlike");
}else{
Like like = new Like();
like.execute(ServerCons.HOST + "like");
}
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// I thought the solution could be there
}
}, 2000);
}
Do it using isReadyToPost flag:
if(isReadyToPost){
isReadyToPost=false;
}else{
// try after 2 secs for next like
}
and in Handler. postDelayed change isReadyToPost to true after 2 secs:
#Override
public void run() {
isReadyToPost=true;
}
isReadyToPost default value is true.
Try this approach:
boolean isReadyToPost= false;
boolean liked = false;//control like click (witch)
public void onLikePressed() {
if (liked && isReadyToPost) {
sendLikeToServer();//send to server after 2 secs
return;
}
this.isReadyToPost= false;
Toast.makeText(this, "waiting for any dislike... in 2 secs", Toast.LENGTH_SHORT).show();
if (liked){
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
isReadyToPost=true;
onLikePressed();
}
}, 2000);
}//end if
} //end onlikepress
You can try to create a thread that sleeps for 2 sec and after that it checks if user still likes the post then update your database
I need a delay for around 5 seconds. I have tried using Timer using below code :
Timer myTimer = new Timer();
myTimer.schedule(new TimerTask() {
#Override
public void run() {
Log.d(TAG,"Timer");
}
}, 4000, 5000);
When i check logs, the Timer is getting printed thrice. If I change time, sometimes it gets printed in log 4 times as well.
I have tried using Handler as well like below :
final Handler mHandler = new Handler();
new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
while (true) {
try {
Thread.sleep(10000);
mHandler.post(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
Log.d(Utility.TAG,"Sleep::");
}
});
} catch (Exception e) {
// TODO: handle exception
}
}
}
}).start();
But again the log is printing multiple times. I just want to call my method once not multiple times. How can I achieve it ?
EDIT
used handler without thread as well like below :
final Handler h = new Handler();
final int delay = 3000; //milliseconds
h.postDelayed(new Runnable(){
public void run(){
//do something
h.postDelayed(this, delay);
Log.d(Utility.TAG,"Sleep ::");
}
}, delay);
But again, Log is getting printed thrice
Your third approach (no Timer, no Thread) is the closest to being correct. It's printing multiple times because the Runnable is re-posting itself every time it runs. If you only want it to run once, remove this line from the run() method:
h.postDelayed(this, delay);
Can I use a thread for increment a counter and shows it in a frame of Android activity.
Public class MainActivity extendsActivity {
TextView counter;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
counter = (TextView) findViewById(R.id.TV_counter);
Thread t = new Thread() {
public void run() {
runOnUiThread(new Runnable() {
public void run() {
for (int i = 0; i < 5; i++) {
try {
counter.setText("" + i);
System.out.println("Value of i= " + i);
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
}
};
t.start();
}
}
I wrote this code, but it run properly in console, but the text view displays i=4 in the terminal, I modified the time to sleep(3000) and the problem persists.
First you don't ever want to put sleep in UI Thread that can lead to unresponsive user interface and that is never good. You should use it just to update your graphics. Try replacing your code with this
Thread t = new Thread() {
public void run() {
for (int i = 0; i < 5; i++) {
try {
final int a = i;
runOnUiThread(new Runnable() {
public void run() {
counter.setText("" + a);
}
});
System.out.println("Value of i= " + i);
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
t.start();
You are going to notice that sleep and for loop is outside UIThread and in your first thread, so basically all of your math is done outside and you just display the results.
This is just a correction of your code and suggestion for further thinking
EDIT: And for you to better understand why your code is not working, you set some value on your TextView, and immediately after you set UIThread to sleep, UIThread blocks instead of giving it time to finish updating graphics, after he finish sleep you set new value, and he never got to update previous one so in the end you see just the last one.
Hope this helps and enjoy your work.
you can use a CountDownTimer, and update your UI in the onTick() method ( this method is executed on the UI Thread):
int i=0;
CountDownTimer timer = new CountDownTimer(5000,1000) {
#Override
public void onTick(long millisUntilFinished) {
// this method will be executed every second ( 1000 ms : the second parameter in the CountDownTimer constructor)
i++;
txt.setText(i);
}
#Override
public void onFinish() {
// TODO Auto-generated method stub
}
};
timer.start();
I am scheduling a simple task that should update a text field in 4 seconds.
However everytime this is called the activity pauses and does not show the value in the text field until I restart the activity.
private void showDelayedValue() {
Runnable longRunningTask = new Runnable() {
public void run() {
int randomVal = randomNumberGenerator.nextInt(30 - -10) - 10; //random number between -10 and 30
String randomValStr = Integer.toString(randomVal);
Log.i(this.getClass().getSimpleName(),
"FIRED startScheduler: " + randomValStr);
theFieldOnScreenTV.setText(randomTempStr);
}
};
//show the value in 2 seconds
scheduledTaskExecutor.schedule(longRunningTask, 4, TimeUnit.SECONDS);
}
The log shows:
FIRED startScheduler: 4
but does not update the TextView theFieldOnScreenTV
Instead onPause is called right after Fired startScheduler: is displayed in LogCat.
Many thanks!
EDIT:
This worked for me following Alex' approach:
private void showDelayedValue() {
int randomX = randomNumberGenerator.nextInt(30 - -10) - 10;
final String randomXStr = Integer.toString(randomX);
final Runnable updateFieldR = new Runnable() {
public void run() {
theFieldOnScreenTV.setText(randomXStr);
}
};
Runnable longRunningTask = new Runnable() {
public void run() {
theFieldOnScreenTV.post(updateFieldR);
}
};
scheduledTaskExecutor.schedule(longRunningTask, 4, TimeUnit.SECONDS);
}
instead of
theFieldOnScreenTV.setText(randomTempStr);
try
theFieldOnScreenTV.post(new Runnable() { theFieldOnScreenTV.setText(randomTempStr); } );
Have a try using Handlers.
Handler handler = new Handler();
handler.post(new Runnable() {
#Override
public void run() {
theFieldOnScreenTV.setText(randomTempStr);
}
});