All,
I am newbie in android, just developing app to display the current Download/Upload Speed. I have got some tips from this Example. It uses TrafficStats.getTotalRxBytes() function that returns the total Bytes received after boot and increases monotonically.
So i used the below code, to display only the Current Available Speed. But i am not getting the result. it displays the Total Tx/Rx values only.
Is there any Alternative to achieve this? Any Code snippets would be much appreciated as i am a complete beginner.
Also, i cant understand below code. Can some one explain this?
private final Runnable mRunnable = new Runnable()
i need to refresh the data displayed in textView for every one second. I Guess
mHandler.postDelayed(mRunnable, 1000) ( );
is used to do that. is there any alternative? if not, how does would be the control flow when using PostDelayed function? (I am bit confused)
public class MainActivity extends Activity {
private Handler mHandler = new Handler();
private long mStartRX =0;
private long mStartTX = 0;
private static final int RESULT_SETTINGS = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mHandler.postDelayed(mRunnable, 1000);
}
private final Runnable mRunnable = new Runnable()
{
public void run()
{
long TxResult=0;
long RxResult=0;
long or1=0,or2=0;
long rxBytes = TrafficStats.getTotalRxBytes()- mStartRX-or1;
if (rxBytes<1024)
{
RxResult=0;
}
else if (rxBytes>1024)
{
// RxResult=0;
RxResult=RxResult+(rxBytes/1024);
}
TextView RX = (TextView)findViewById(R.id.rxOut);
//mStartRX=rxBytes;
TextView TX = (TextView)findViewById(R.id.txOut);
RX.setText(Long.toString(RxResult));
long txBytes = TrafficStats.getTotalTxBytes()- mStartTX-or2;
if (txBytes<1024)
{
TxResult=0;
}
else if (txBytes>1024)
{
TxResult=0;
TxResult=TxResult+(txBytes/1024);
}
TX.setText(Long.toString(TxResult));
or2=or2+txBytes;
or1=or1+rxBytes;
mHandler.postDelayed(mRunnable, 100);
}
};
Related
Android. I am trying to set background colour at time to make some sort of trainer. But this loop set background colour for all 4 LivearLayouts at ONE TIME - after the last iteration. And i need to do it one by one with pauses. How can i do it?
private LinearLayout[] lls;
lls = new LinearLayout[4];
lls[0] = findViewById(R.id.ll01);
lls[1] = findViewById(R.id.ll02);
lls[2] = findViewById(R.id.ll03);
lls[3] = findViewById(R.id.ll04);
public void onClick(View view) throws InterruptedException {
for (int i = 0; i < 4; i++) {
Thread.sleep(3000);
lls[i].setBackgroundColor(Color.parseColor("red"));
}
}
Such a code changes colour for all 4 objects at once - after the end of the 4th iteration. Prior to this, the colour of none has changed.
I think you should use a handler instead of for loop. Handlers are more convenient for delaying and doing some stuff. I am putting some edited code for you.
private LinearLayout[] lls;
private Long timeInMillis = 3000L;
private Handler handler;
private Runnable runnable;
private int index = 0;
private void setColors(){
lls = new LinearLayout[4];
lls[0] = findViewById(R.id.ll01);
lls[1] = findViewById(R.id.ll02);
lls[2] = findViewById(R.id.ll03);
lls[3] = findViewById(R.id.ll04);
handler = new Handler();
runnable = new Runnable() {
#Override
public void run() {
if(index!=lls.length){
lls[index++].setBackgroundColor(Color.parseColor("red"));
handler.postDelayed(runnable,timeInMillis);
}
}
};
handler.postDelayed(runnable,timeInMillis);
}
It was wrong code. You cant change smth in activity in one thread. It was solved by adding thread with loop that sends Broadcast messages for BroadcastReciever in MainActivity.
In my android application I need to update different parts of the UI (actually a Fragment inside a ViewPager on a different time intervals. To do this I've created an Handler and 3 Runnables. With the postDelayed(Runnable, delay) method the Runnables should repeat themselves at scheduled time intervals.
Currently I have 1 runnable that must update a TextView every 100 ms, another that update a ProgressBar every 1000 ms and another one that checks some stuff every 2000 ms.
I saw the counter and the progress bar incrementing too fast and so I've put some code checking the delay between every call to the Run() method and I've discovered that the first runnable is executed every 58 ms and the progressbar's one running every 508 ms.
I've then tried to left only the first Runnable on the Handler (the counter one) and the Run() method get called every ~101 ms. So I've hypothized that other Runnables maybe interfer with the Message Queue schedule. I've then created one Handler for every Runnable but in that way the problem persist with 56~58 ms in the first Runnable and 508~510 ms on the second one.
Any suggestion on why this behaviour happen?
Here's part of my code:
private static final int TIME_STEP_COUNTER = 100;
private static final int TIME_STEP_PROGRESS = 1000;
private static final int TIME_STEP_DIRECTOR = 2000;
private Handler counterHandler, progressHandler, directorHandler;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
// some code here
directorThread = new DirectorThread(wwp,TIME_STEP_DIRECTOR);
if(directorHandler == null){
directorHandler = new Handler();
directorHandler.post(directorThread);
}
startCounting();
}
StartCounting() method
public void startCounting(){
stdCounterUpdater = new CounterUpdaterThread(textViewCounter,TIME_STEP_COUNTER, increment100ms);
progressUpdaterThread = new ProgressUpdaterThread(progressBar,TIME_STEP_PROGRESS,textViewPercentage);
fixerThread = new FixerThread(wwp,TIME_STEP_FIXER);
if(counterHandler == null){
counterHandler = new Handler();
}
counterHandler.post(stdCounterUpdater);
if(progressHandler == null){
progressHandler = new Handler();
}
progressHandler.postDelayed(progressBarInitThread, DELAY_INIT_PROGRESS);
progressHandler.postDelayed(progressUpdaterThread, DELAY_INIT_PROGRESS + INIT_PROGRESS_DURATION);
counterLayout.setVisibility(View.VISIBLE);
}
Threads
CounterUpdater
class CounterUpdaterThread implements Runnable{
public CounterUpdaterThread(TextView counterView, long deltaTime, float increment){
//Constructor with fields initialization
}
#Override
public void run(){
counter += increment;
changeCounterText();
if(counterHandler != null){
counterHandler.postDelayed(stdCounterUpdater,deltaTime);
}
}
}
ProgressUpdater
class ProgressUpdaterThread implements Runnable{
public ProgressUpdaterThread(ProgressBar pBar, long deltaTime, TextView percTW){
//Fields init
}
#Override
public void run(){
anim = new ProgressBarAnimation(progressBar, progress, progress + smoothScale);
progress += smoothScale;
anim.setDuration(PROGRESS_UPDATE_DURATION);
progressBar.startAnimation(anim);
percTW.setText(String.format(Locale.US,"%.1f", progressBar.getProgress()*100f/progressBar.getMax()) + "%");
if(progressHandler != null){
progressHandler.postDelayed(progressUpdaterThread,deltaTime);
}
}
}
DirectorThread
class DirectorThread implements Runnable{
public DirectorThread(WeeklyWorkPeriod wwp, long deltaTime){
//init
}
#Override
public void run(){
if(isStarted){
//....code.....
stopCounting();
isStarted = false;
//....code.....
}
}
else{
// ...code...
raiseMethod.requestProgressData(ProgressBarFragment.this,fragmentID);
startCounting();
isStarted = true;
}
}
if(directorHandler != null){
directorHandler.postDelayed(directorThread,deltaTime);
}
}
}
I've checked also these articles and some other question but with no results
Repeating Tasks
Handler Vs Timer
Handlers and Loopers
I just found the problem: wasn't about a single handler but about starting new callbacks in the DirectorThread. Just setting in the onCreateView() method isStarted to true solved the problem.
Among the other things I've replaced postDelayed() with postAtTime() as suggested by pskink cause it happens to be more accurate.
I'm running a handler inside of a while loop, against a lat/lng span so if i'm outside of a certain span, that map will automatically zoomIn. I'm using this exact same setup, comparing zoom levels instead of spans and it works just fine. Here's what I'm doing...
public static void smoothZoomToSpan(final MapController controller,
MapView v, GeoPoint center, int latitudeSpan, int longitudeSpan) {
final Handler handler = new Handler();
final MapView mapView = v;
final int currentLatitudeSpan = v.getLatitudeSpan();
final int currentLongitudeSpan = v.getLongitudeSpan();
final int targetLatitudeSpan = latitudeSpan;
final int targetLongitudeSpan = longitudeSpan;
controller.animateTo(center, new Runnable() {
public void run() {
int curLatSpan = currentLatitudeSpan;
int curLngSpan = currentLongitudeSpan;
int tarLatSpn = targetLatitudeSpan;
int tarLngSpan = targetLongitudeSpan;
long delay = 0;
while ((curLatSpan - 6000 > tarLatSpn)
|| (curLngSpan - 6000 > tarLngSpan)) {
Log.e("ZoomIn", "Thinks we should!");
handler.postDelayed(new Runnable() {
#Override
public void run() {
controller.zoomIn();
Log.e("ZoomIn", "Zoomed");
}
}, delay);
delay += 150; // Change this to whatever is good on the
// device
}
Log.e("ZoomIn", "completed");
}
});
}
After I execute this code, Logcat outputs "Thinks we should!" (basically flooding the logs) endlessly. But it never does anything with my handler... the actual zoomIn call never fires, and it just loops forever until I force-close my application. What am I doing wrong?
Your handler and the while loop are both executing their Runnables on the UI thread. So you've posted a bajillion runnables to the UI thread handler, but it doesn't matter, because the UI thread is busy executing your while loop and never gets to the point where it can execute the runnables you've posted to the handler. You'll have to modify your flow of control somewhat to get this to work - perhaps something like this:
public static void smoothZoomToSpan(final MapController controller,
MapView v, GeoPoint center, int latitudeSpan, int longitudeSpan) {
controller.animateTo(center, new Runnable());
}
private class ExecuteZoom implements Runnable {
static long delay;
#Override
public void run() {
if ((curLatSpan - 6000 > tarLatSpn)
|| (curLngSpan - 6000 > tarLngSpan)) {
handler.postDelayed(new ExecuteZoom(), delay);
delay += 150;
}
}
}
Clearly not a complete implementation, you might have to pass the constructor of the runnables some variables, etc; but hopefully this works out a bit better for you.
I want to display 5 images on a Map View as map overlay with an interval of 1 minute each. I use sleep to make a delay. But it is not working. After all delay, the images are displaying altogether. How to do this? Please help
Look at this link. I think, it is, what you need
http://developer.android.com/resources/articles/timed-ui-updates.html
UPD:
Define in your activity:
private Handler mHandler = new Handler();
private int cnt = 0;
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
if (cnt < 5)
{
// Display new Image
mHandler.postDelayed(mUpdateTimeTask, 60000);
cnt++;
}
else
{
mHandler.removeCallbacks(this);
}
}
};
and call then somwhere in onCreate or onResume
mHandler.postDelayed(mUpdateTimeTask, 60000);
I've made a simple Android music player. I want to have a TextView that shows the current time in the song in minutes:seconds format. So the first thing I tried was to make the activity Runnable and put this in run():
int position = 0;
while (MPService.getMP() != null && position<MPService.duration) {
try {
Thread.sleep(1000);
position = MPService.getSongPosition();
} catch (InterruptedException e) {
return;
}
// ... convert position to formatted minutes:seconds string ...
currentTime.setText(time); // currentTime = (TextView) findViewById(R.id.current_time);
But that fails because I can only touch a TextView in the thread where it was created. So then I tried using runOnUiThread(), but that doesn't work because then Thread.sleep(1000) is called repeatedly on the main thread, so the activity just hangs at a blank screen. So any ideas how I can solve this?
new code:
private int startTime = 0;
private Handler timeHandler = new Handler();
private Runnable updateTime = new Runnable() {
public void run() {
final int start = startTime;
int millis = appService.getSongPosition() - start;
int seconds = (int) ((millis / 1000) % 60);
int minutes = (int) ((millis / 1000) / 60);
Log.d("seconds",Integer.toString(seconds)); // no problem here
if (seconds < 10) {
// this is hit, yet the text never changes from the original value of 0:00
currentTime.setText(String.format("%d:0%d",minutes,seconds));
} else {
currentTime.setText(String.format("%d:%d",minutes,seconds));
}
timeHandler.postAtTime(this,(((minutes*60)+seconds+1)*1000));
}
};
private ServiceConnection onService = new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder rawBinder) {
appService = ((MPService.LocalBinder)rawBinder).getService();
// start playing the song, etc.
if (startTime == 0) {
startTime = appService.getSongPosition();
timeHandler.removeCallbacks(updateTime);
timeHandler.postDelayed(updateTime,1000);
}
}
what about this:
int delay = 5000; // delay for 5 sec.
int period = 1000; // repeat every sec.
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask()
{
public void run()
{
//your code
}
}, delay, period);
Use a Timer for this (instead of a while loop with a Thread.Sleep in it). See this article for an example of how to use a timer to update a UI element periodically:
Updating the UI from a timer
Edit: updated way-back link, thanks to Arialdo: http://web.archive.org/web/20100126090836/http://developer.android.com/intl/zh-TW/resources/articles/timed-ui-updates.html
Edit 2: non way-back link, thanks to gatoatigrado: http://android-developers.blogspot.com/2007/11/stitch-in-time.html
You have to use a handler to handle the interaction with the GUI. Specifically a thread cannot touch ANYTHING on the main thread. You do something in a thread and if you NEED something to be changed in your main thread, then you call a handler and do it there.
Specifically it would look something like this:
Thread t = new Thread(new Runnable(){
... do stuff here
Handler.postMessage();
}
Then somewhere else in your code, you do
Handler h = new Handler(){
something something...
modify ui element here
}
Idea its like this, thread does something, notifies the handler, the handler then takes this message and does something like update a textview on the UI thread.
This is one more Timer example and I'm using this code in my project.
https://stackoverflow.com/a/18028882/1265456
I think the below blog article clearly gives a very nice solution. Especially, if you are a background service and want to regularly update your UI from this service using a timer-like functionality.
It really helped me, much more than the 2007 blog link posted by MusiGenesis above.
https://www.websmithing.com/2011/02/01/how-to-update-the-ui-in-an-android-activity-using-data-from-a-background-service/