How is it possible to make an app that changes between color automatically after specific time. My code doesn't work for some reason
Random r = new Random();
Timer t = new Timer();
LinearLayout ll = (LinearLayout) findViewById(R.id.ll);
long m = System.nanoTime();
int seconds = (int) (m/1000);
if(seconds <= 5){
ll.setBackgroundColor(Color.BLACK);
}else{
ll.setBackgroundColor(Color.WHITE);
}
For ex. the screen is black and after specific time white. And that the time decreases itslef, the changing goes faster.
Please try the following code for the color change.
Use the countdown timer for changing the color with condition.
new CountDownTimer(5000,1000)
{
onFinish()
{
if(flag==1)
{
//color set black
flag=0;
//start the countdown timer again.
}
else
{
//color set white
flag=1;
//start the countdown timer again.
}
}
}
Try following the code
Calendar c = Calendar.getInstance();
int seconds = c.get(Calendar.SECOND);
//Adding Log Statement to check
Log.i(Tag, String.valueOf(seconds);
if(seconds % 10 < 5){
ll.setBackgroundColor(Color.BLACK);
}else{
ll.setBackgroundColor(Color.WHITE);
}
You are trying to convert nanoseconds to seconds, but actually you are doing is not the same!!
try
int seconds = (int) (m/1000000000);
to convert to nan0-seconds to seconds
EDIT:
if you just want to keep changing color use this code:
public static int color = 1;
android.os.Handler customHandler = new android.os.Handler();
customHandler.postDelayed(updateTimerThread, 0);
and its definition:
private Runnable updateTimerThread = new Runnable()
{
public void run()
{
//write here whaterver you want to repeat
if(color == 1){
ll.setBackgroundColor(Color.BLACK);
color = 2;
}else{
ll.setBackgroundColor(Color.WHITE);
color = 1;
}
customHandler.postDelayed(this, 5000);// will repeat after 5 seconds
}
};
You can use tread to manage this, try this . thread will be the best way to achieve this, since you want to continuously change the color at regular interval.
Handler handler ;
LinearLayout ll ;
int i = 0;
int colors[] = {Color.BLACK, Color.WHITE, Color.BLUE, Color.GREEN, Color.GRAY};
Runnable runnable = new Runnable() {
#Override
public void run() {
ll.setBackgroundColor(colors[i]);
i++;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
......
.......
handler = new Handler();
ll = (LinearLayout) findViewById(R.id.ll);
Thread myTread = new Thread(){
public void run() {
try {
while(true){
sleep(3000);
handler.post(runnable);
}
}
catch (InterruptedException e) {}
}
};
myTread.start();
}
the code will change the background color every 3secssleep(3000) as written in the code. also each time it changes it select from a set of pre-define color array.
you can also use random generation of colors. either you randomly generate the rgb values or you can store the colors in an array as i have done and randomly iterate over it
Related
I searched other posts and I didn't find a case matching my problem, so please do not refer me to other posts.
I have a list of hundreds of different times starting like the below list:
timeList = {5, 13, 21, 40, ...}.
Suppose that they are saved in an arraylist. That means some task must be executed at 5 secs, 13 secs,... from a starting point . How can I use a Timer or any other way to achieve this?
Also I may have the timeList in a format like this if it helps:
timeList = {8:05, 8:13, 8:21, 8:40, ...}.
My current timer is like this:
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
synchronized public void run() {
//do some task
}
}, startPoint, Period);
But this is obviously working at fixed rate!
By using Timer.schedule(TimerTask task, long delay), set all your timers and wait for them to execute
Assuming you are getting in MM:SS format (ex: 8:58):
ArrayList<String> your_arraylist = new ArrayList<String>();
//your list above, fill it with MM:SS
final ArrayList<Long> seconds = new ArrayList<Long>();
final ArrayList<Long> minutes = new ArrayList<Long>();
long first_minute;
for (String time : your_arraylist) {
minutes.add(Long.parseLong(time.split(":")[0]));
seconds.add(Long.parseLong(time.split(":")[1]));
}
first_minute = minutes.get(0);
for (int i = 0; i < seconds.size(); i++) {
long waiting_duration;
if (seconds.get(i) < Calendar.SECOND) {
waiting_duration = (60 - Calendar.SECOND + seconds.get(i)) * 1000;
}
else {
waiting_duration = (seconds.get(i) - Calendar.SECOND) * 1000;
}
waiting_duration += (minutes.get(i) - first_minute) * 60 * 1000;
Timer timer = new Timer();
TimerTask timer_task = new TimerTask() {
#Override
public void run() {
// do jobs
}
};
timer.schedule(timer_task, waiting_duration);
}
Don't use Timer use a Handler instead.
private int[] mTimeList = {5000, 2000, 7000, 4000};
private int mCount;
private int mDelay;
private Handler mHandler = new Handler();
private void initRepeatedTimer() {
mHandler.postDelayed(new Runnable() {
public void run() {
Log.e(TAG, "run: " + mCount);
mDelay = mTimeList[mCount];
if (mCount < mTimeList.length - 1)
mCount++;
else
mCount = 0;
mHandler.postDelayed(this, mDelay);
}
}, mDelay);
}
You wil notice that the log is printed as per delay in the list.
Iam calculating the cellular data rate per second by using Handler, the code is being executed every second and the overall traffic been calculated then it suppose to subtract the old traffic since boot from the current traffic since boot to get the current data rate per second.
The problem I'm facing that the current data rate value is not correct, it is always giving me the total overall traffic since boot. May be I did something wrong, I'm still beginner with android. The code below.
public class MainActivity extends AppCompatActivity {
private double RXOld;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
////////////////////////Code to be executed every second////////////////////////////////////////
Calendar c = Calendar.getInstance();
int seconds = c.get(Calendar.SECOND);
double overallTraffic = TrafficStats.getMobileRxBytes();
double currentDataRate = overallTraffic - RXOld;
TextView view1 = null;
view1 = (TextView) findViewById(R.id.view1);
view1.setText("Current Data Rate per second= " + currentDataRate);
double RXOld = overallTraffic;
handler.postDelayed(this, 1000);
}
}, 1000 );
}
The new Code after rectification which shall give the current data rate per second
public class MainActivity extends AppCompatActivity {
final double [] RXOld = new double [1];
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
////////////////////////Code to be executed every second////////////////////////////////////////
Calendar c = Calendar.getInstance();
int seconds = c.get(Calendar.SECOND);
double overallTraffic = TrafficStats.getMobileRxBytes();
double currentDataRate = overallTraffic - RXOld [0];
TextView view1 = null;
view1 = (TextView) findViewById(R.id.view1);
view1.setText("Current Data Rate per second= " + currentDataRate);
RXOld [0] = overallTraffic;
handler.postDelayed(this, 1000);
}
}, 1000 );
First of all, consider using a Timer, and declare the TextView at the beginning. I think this code should work, but I didn't test it:
final TextView view1 = null;
view1 = (TextView) findViewById(R.id.view1);
final double[] oldT = new double[1];
Timer timer1 = new Timer();
TimerTask tt1 = new TimerTask() {
#Override
public void run() {
double overallTraffic = TrafficStats.getMobileRxBytes();
double trafficRate = overallTraffic - oldT[0];
oldT[0] = overallTraffic;
view1.setText("Current Data Rate per second= " + trafficRate);
}
};
timer1.scheduleAtFixedRate(tt1,1000,1000);
Note: if you use a new variable into the run() of the TimerTask, the variable MUST be declared final. You can easyly change its value by makeing the variable an array of 1 element ('int[] varName = new int[1]' instead of 'int varName'), and using varName[0] instead of varName
I'm trying to append letters from a specific string onto a TextField. This is what I've tried so far. But no luck.
What happens here is it just waits for 100 milliseconds and then displays the string directly.
outConsole = (TextView) findViewById(R.id.outconsole);
int i, j;
String fin = "";
final String in = "HELLO!";
i = in.length;
try{
for(j = 0; j < i; j++){
Thread.sleep(100);
fin = fin + in.charAt(j);
outConsole.setText(fin);
}
}catch(Exception e){}
}
How do I achieve this?
I would like something like this but slower:
https://www.youtube.com/watch?v=Ff-eDOGLuYw
Try using Handlers. Something like this should work:
Handler handler = new Handler();
Runnable runnable = new Runnable() {
#Override
public void run() {
//update your ui
handler.postDelayed(this, 100);//this restarts the handler better to have some terminating condition
}
};
handler.postDelayed(runnable, 100);//starts the handler first time
public void run() {
runOnUiThread(new Runnable() {
public void run() {
tvTimer.setText("timer=" + String.valueOf(TimeCounter));
TimeCounter++;
A.setBackgroundColor(123455+TimeCounter*100000);
}
});
}
}, 0, 1000);
I have created a timer that his role to count the running time of the application, and i want to change the background color as long as the timer goes up. what is wrong with my script?
I think the problem comes from the value that you are passing to the setBackgroundColor method.
From the doc of the class Color we can see that:
The components are stored as follows (alpha << 24) | (red << 16) |
(green << 8) | blue.
In your code, the first value that you are passing (supposing the TimeCounter starts from 0) is 123455 which corresponds to 0x0001E23F in hexadecimal.
By decomposing it, we have:
alpha=0x00
red=0x01
green=0xE2
blue=0x3F
It gives you 0% for the alpha value which means that the color is transparent.
You are adding 100000 to this value every second. So it will take you about 166 seconds (almost 3 minutes) to have a color with an alpha value greater than 0 (but it will still be invisble as the percentage of alpha will be lower than 1%).
To fix it, you can use an offset to each color to set the alpha value to 100%. For that you just have to add 0xff000000 (4 278 190 080) to the color value.
Finally, just be sure that the color value is always lower than the maximum value 0xffffffff (4 294 967 295) and it should work.
Here is a sample code:
private int offsetColor = 0xFF000000; //offset to have 100% in alpha value
public void run() {
runOnUiThread(new Runnable() {
public void run() {
tvTimer.setText("timer=" + String.valueOf(TimeCounter));
TimeCounter++;
if (TimeCounter < 167) {
A.setBackgroundColor(offsetColor+TimeCounter*100000);
} else {
/* You just reach the limit: 0xFFFFFFFF which is White */
}
}
});
}
}, 0, 1000);
With this example you can do 166 iterations (166 seconds). You can change the value that you are adding each second to adjust the duration of your animation.
Problem is the color code set in the A.setBackgroundColor();
I have simple and logical solution of this:
1.make color array like this
int[] colors=new int[]{Color.BLACK,Color.BLUE,Color.GREEN,Color.RED,Color.YELLOW};
int i=0;
set color of array by its index as i increments in Runnable:
public void run() {
runOnUiThread(new Runnable() {
public void run() {
tvTimer.setText("timer=" + String.valueOf(TimeCounter));
TimeCounter++;
A.setBackgroundColor(colors[i]);
i++;
if(i==5){
i=0;
}
}
});
}
}, 0, 1000);
See I have create new application for your color change as you required.:
public class MainActivity extends Activity {
ImageView iv;
int red = 255, green = 0, blue = 0;
int i = 0;
int a = 30;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv = (ImageView) findViewById(R.id.imageView1);
// m.postScale(2f, 2f);
Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
public void run() {
runOnUiThread(new Runnable() {
public void run() {
iv.setBackgroundColor(Color.argb(a, red, green, blue));
Log.d("main", "i: " + i + " a:+ " + a + " red: " + red
+ " green: " + green + " Blue: " + blue);
a = a + 30;
// set 30 to 60 for more difference
if (a > 250) {
a = 30;
i++;
if (i == 1) {
red = 0;
green = 255;
blue = 0;
} else if (i == 2) {
red = 0;
green = 0;
blue = 255;
} else if (i == 3) {
red = 255;
green = 0;
blue = 0;
}
if (i == 3) {
i = 1;
}
}
}
});
}
}, 0, 1000);
}
}
Now Enjoy Good Luck ..
Below I am posting my code for the thread I am running to animate text in a RelativeLayout on top of the Page Curl activity by harism.
public void startProgress(final int index)
{
runnable = new Runnable()
{
#Override
public void run()
{
mArrWords.removeAll(mArrWords);
mStart.removeAll(mStart);
mEnd.removeAll(mEnd);
words = sentence.split(" ");
for(int i = 0; i < words.length; i++)
{
mArrWords.add(words[i]);
if(i == 0)
{
mStart.add(0);
mEnd.add(words[0].length());
}
else
{
mStart.add(mEnd.get(i-1)+1);
mEnd.add(mStart.get(i)+words[i].length());
}
/*Log.e("words", "" + "" + words[i]);
Log.e("mArrWords", "" + mArrWords);
Log.e("mStart", "" + mStart);
Log.e("mEnd", "" + mEnd);*/
}
for (int i = 0; i < mArrWords.size(); i++)
{
final int value = i;
try
{
Thread.sleep(500);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
mHandler.post(new Runnable()
{
#Override
public void run()
{
currIndex = index;
try
{
if(CurlView.ANIMATE)
tv1.setVisibility(View.VISIBLE);
else
tv1.setVisibility(View.GONE);
final Pattern p = Pattern.compile(mArrWords.get(value));
final Matcher matcher = p.matcher(sentence);
SpannableString spannableTxt = new SpannableString(sentence);
ForegroundColorSpan span = new ForegroundColorSpan(Color.RED);
while(matcher.find())
spannableTxt.setSpan(span, mStart.get(value), mEnd.get(value), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
tv1.setText(spannableTxt);
mHandler.sendEmptyMessage(0);
}
catch (Exception e)
{
e.printStackTrace();
mHandler.sendEmptyMessage(0);
}
}
});
}
}
};
final ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor();
worker.schedule(runnable, CurlView.ANIMTIME+50, TimeUnit.MILLISECONDS);
}
Here, I am animating the text over images. I need to change the text for each page I am changing. I am able to change the text, however, when I turn the page, the index values I store in ArrayLists are not getting cleared. I am storing a sentence in an ArrayList named mArrWords and the indexes to refer to each word of sentence are stored in mStart and mEnd.
The problem I am facing is when the text changes, the animation starts with the previous indexes stored in mStart and mEnd ArrayLists I use to store index of a particular word. What I need to know is how do I stop my thread when the page is turned or the index of the page changes. I am calling this function inside the updatePage(final CurlPage page, final int width, final int height, final int index) method of Curl activity. I hope I was able to explain my problem. Thanks!
EDIT: I would like to specify my question more clearly. How do I check if the thread is already running before starting another thread and stop the execution of the previous thread?
removeCallbacks(..) only stops pending messages (Runnables).If runnable is started then u can not stop it in this way. See the following :
removecallbacks-not-stopping-runnable