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
Related
I'm working on a school project in Android Studio and so far I've written a code which generates a random equation and then display this equation in a textview. Here is the code:
String[] operationSet = new String[]{"+", "-", "/", "*"};
Random random = new Random();
int numOfOperations = random.nextInt(2) + 1;
List<String> operations = new ArrayList<>();
for (int i = 0; i < numOfOperations; i++) {
String operation = operationSet[random.nextInt(4)];
operations.add(operation);
}
int numOfNumbers = numOfOperations + 1;
List<Integer> numbers = new ArrayList<>();
for (int i = 0; i < numOfNumbers; i++) {
int number = random.nextInt(10)+1;
numbers.add(number);
}
String equation = "";
for (int i = 0; i < numOfOperations; i++) {
equation += numbers.get(i);
equation += operations.get(i);
}
equation += numbers.get(numbers.size() -1);
TextView TextEquation = (TextView)findViewById(R.id.textView3);
TextEquation.setText(equation);
String stringResultOfEquation = String.valueOf(equation);
// Resultat der Rechung berechnen
double doubleAnswer = eval(stringResultOfEquation);
String stringAnswer = Double.toString(doubleAnswer);
TextView textAnswer = (TextView)findViewById(R.id.textView4);
textAnswer.setText(stringAnswer);
So far I've tried to use the TimerTask command:
TimerTask timerTaskWaiting = new TimerTask() {
#Override
public void run() {
}
};
Timer timerwaiting = new Timer();
timerwaiting.schedule(timerTaskWaiting, 5000);
I've put the "equation generater code" and put it into "public void run(){...}" but the app crashed when I tried it out.
My question now is, if there is a simple way which will generate the equation after a certain amount of time (for example 5 seconds) I mean, I want that the equation will be generated 5 seconds after the app is launched.
If there is anything unclear in my question, feel free to ask and I will try to clarify the problem :)
Thank you already in advance for your help!
This bit of code should suffice for you to understand what you need to do. obviously there are other ways you can achieve this.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_layout);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
generateAndDisplayEquation();
}
}, 5000);
}
Use RxJava library, it is very easy tool to organize periodic tasks.
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.
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
I want to create an application in which the user has 90 seconds in order to complete a certain number of sums.
I am unsure how to stop the activity and move to another after the timeframe is up?
Activity code:
/**
* Class holding the activity that has the 10 random sums for the user to answer
* #author Ross
*
*/
public class RandomTest extends Activity implements View.OnClickListener {
// declare vars
TextView text;
EditText answer;
Button submit;
int random1;
int random2;
String[] question = new String[10];
int correctAnswer[] = new int[10];
int[] results = new int[10];
int score = 0;
int questionNumber = 1;
MediaPlayer correctNoise;
MediaPlayer incorrectNoise;
ImageView imageRandom;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
// initialising variables
initialiseVars();
// set up random
setUpRandom();
// Set text view equal to question in array
text.setText(question[questionNumber - 1]);
// set on click listener for the submit button
submit.setOnClickListener(this);
// updateQuestion
updateQuestion();
}
/**
* Method that initialises variables
*/
public void initialiseVars() {
correctNoise = MediaPlayer.create(RandomTest.this, R.raw.correctnoise);
incorrectNoise = MediaPlayer.create(RandomTest.this, R.raw.incorrectnoise);
text = (TextView) findViewById(R.id.tvTopRandomTest);
answer = (EditText) findViewById(R.id.etEnterAnswerRandomTest);
submit = (Button) findViewById(R.id.btnSubmitRandomTest);
imageRandom= (ImageView) findViewById(R.id.imageViewRandomTest);
}
/**
* Method that creates the random sum for user to answer
*/
public void setUpRandom() {
// setting up new random
Random random = new Random();
// Generating random number between 1 and 12
random1 = random.nextInt(12) + 1;
// Generating another random number between 1 and 12
random2 = random.nextInt(12) + 1;
// Creating random question String
question[questionNumber - 1] = random1 + " x " + random2 + " = ";
// Creating correct answer to question
correctAnswer[questionNumber - 1] = random1 * random2;
}
/**
* Method that updates question after each click
*/
public void updateQuestion() {
// updating question after each click
setUpRandom();
text.setText(question[questionNumber - 1]);
answer.setText("");
}
public void onClick(View v) {
// sets text view equal to what is entered in editText
final String entry = answer.getText().toString();
// convert from string value to int
int a = Integer.parseInt(entry); //
// setting the user answer equal to the correct part of results array
results[questionNumber - 1] = a;
// If user answer is equal to correct answer then increase score
if (a == correctAnswer[questionNumber - 1]) {
score++;
correctNoise.start();
imageRandom.setImageResource(R.drawable.thumbsup);
}else{
incorrectNoise.start();
imageRandom.setImageResource(R.drawable.thumbsdown);
}
// if question number is under 10
if (questionNumber < 10) {
// updates question number
questionNumber++;
// called after an answer is given
updateQuestion();
} else {
// Passing values to the results activity
Intent intent = new Intent(this, RandomTestResults.class);
intent.putExtra("results", results);
intent.putExtra("Questions", question);
intent.putExtra("CorrectAnswer", correctAnswer);
intent.putExtra("score", score);
// Start Activity
this.startActivity(intent);
}
}
}
Use the AlarmManager and when it calls use finish();
I have developed a stopwatch in Android . The stopwatch has the feature of Lap calculation too.
I have started the stopwatch . I tested the stopwatch developed by me with multiple standard stopwatches . The problem is that after 1 minutes , the stopwatch developed keeps lagging behind the other stopwatches & the difference keeps on increasing. I got around 8-10 seconds lagging after the 3 minutes.
The following code I am using:
Two classes I am using , one for the Stopwatch implementation & the other for Stopwatch display
StopwatchImplementation.java
/** The timer used to implement the Stopwatch logic. */
private Timer mSWatch = null;
/**
* Starts the Stopwatch.
*/
public void watchStart() {
if (mSWatch != null)
mSWatch .cancel();
mSWatch = new Timer();
mSWatch .schedule(new TimerTask() {
#Override
public void run() {
mListener.updateUIThread();
}
}, 0, 100);
}
/** Runnable The Timer_ tick where the time is updated */
Runnable Timer_Tick = new Runnable() {
public void run() {
updateTime(); // Updates the time , calculates the lap duration
}
};
private int mHours = 0;
/** The mins. */
private int mMins = 0;
/** The secs. */
private int mSecs = 0;
/** The fraction of a sec. */
private int mFSec = 0;
/** The lap hours. */
private int mLapHours = 0;
/** The lap mins. */
private int mLapMins = 0;
/** The lap secs. */
private int mLapSecs = 0;
/** The lap fraction of sec.... 1/10th of a sec*/
private int mLapFSec = 0;
public void updateTime() {
try {
mLapFSec++;
if (mLapFSec >= 10) {
mLapFSec = 0;
mLapSecs++;
if (mLapSecs >= 60) {
mLapSecs = 0;
mLapMins++;
if (mLapMins >= 60) {
mLapMins = 0;
mLapHours++;
}
}
}
mFSec++;
if (mFSec >= 10) {
mFSec = 0;
mSecs++;
if (mSecs >= 60) {
mSecs = 0;
mMins++;
if (mMins >= 60) {
mMins = 0;
mHours++;
}
}
}
}
StopwatchScreen.java
StopwatchImplementation mStopWatch = new StopwatchImplementation(this);
/**
* Update ui thread.
*/
public void updateUIThread() {
StopWatchScreen.this.runOnUiThread(mStopWatch.Timer_Tick);
}
public void startPressed() {
mStopWatch.watchStart();
}
Kindly provide any inputs regarding where the calculation is going wrong.
Thanks in advance.
Warm Regards,
CB
You cannot rely on the scheduling of a TimerTask for precision timing. You have asked for the updateTime method to be called every 100 milliseconds, but the Android system will only adhere to this roughly - it might take 99 or 101 milliseconds before the next time updateTime is called. Because of this you should avoid timing mechanisms which rely on simply increasing a counter.
For this reason you should record the start time, then compare the current time to the start time to get the amount of time elapsed. For instance:
private long startTime;
public void watchStart() {
startTime = SystemClock.elapsedRealtime();
...
}
public void updateTime() {
final long currentTime = SystemClock.elapsedRealtime();
final long elapsedTime = currentTime - startTime;
// convert elapsedTime in seconds, minutes etc
final int seconds = (elapsedTime/1000)%60;
final int minutes = (elapsedTime/(1000*60))%60;
final int hours = (elapsedTime/(100*60*60))%24;
...
}