This question already has answers here:
Show Download progress inside activity using DownloadManager
(5 answers)
Closed 4 years ago.
I am using Download Manager in android to download images and Videos from a particular Url.
So, When Downloading is in Progress, I am displaying a simple Progressbar.
Instead, I wanna to display custom Progressbar, which display the progress of content downloaded. That means It should display a view so that User can know that How much data is downloaded.
Just like WhatsApp is doing with downloading images and videos.
Thanks.
used below code to show percentages download is complete like below ...
<ProgressBar
android:id="#+id/xml_reg_progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/common_left_right_margin"
android:layout_marginRight="#dimen/common_left_right_margin"
android:layout_marginTop="#dimen/reg_ph_linear_top_margin"
/>
and used below code to show it...
protected static final int TIMER_RUNTIME = 180000; // in ms --> 10s
private ProgressBar progressTimer;
public void startTimer() {
final Thread timerThread = new Thread() {
#Override
public void run() {
mbActive = true;
try {
int waited = 0;
while (mbActive && (waited < TIMER_RUNTIME)) {
sleep(1000);
if (mbActive) {
waited += 1000;
updateProgress(waited);
}
}
} catch (InterruptedException e) {
// do nothing
} finally {
onContinue();
}
}
};
timerThread.start();
}
Handler handler = new Handler();
private void onContinue() {
handler.post(new Runnable() {
#Override
public void run() {
txtCallContactUsNumber
.setText(CommonVariable.CallForSupporMessage
+ contactInfo.MobileNo);
}
});
}
public void updateProgress(final int timePassed) {
if (null != progressTimer) {
// Ignore rounding error here
final int progress = progressTimer.getMax() * timePassed
/ TIMER_RUNTIME;
handler.post(new Runnable() {
#Override
public void run() {
Log.i("timePassed", "timePassed=" + timePassed);
DateFormat formatter = new SimpleDateFormat("mm:ss");
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(timePassed);
String timer = formatter.format(calendar.getTime());
formatter.setTimeZone(java.util.TimeZone.getTimeZone("GMT"));
txtTimerCount.setText(formatter.format(timePassed));
}
});
progressTimer.setProgress(progress);
}
}
in my above code this will call 1 second and get progress increment every 1 second.
I download gocoder android example and run the BitmapOverlayActivity, everything is ok but when I try to update the WZBitmap using WZBitmap.setBitmap() like:
private Runnable runnable = new Runnable() {
#Override
public void run() {
if (mWZBitmap != null) {
if (System.currentTimeMillis() % 2 == 0) {
mWZBitmap.setBitmap(overlayBitmap1);
} else {
mWZBitmap.setBitmap(overlayBitmap2);
}
}
handler.postDelayed(runnable, 5000);
}
};
private Handler handler = new Handler();
and the camera only shows black view:
In my application, I have a button that starts an AsyncTask that downloads data with coordinates for google maps, then draws a marker on the map at the following coordinates. I want to run this every 10 seconds until the user presses the button again.
Here's my code for the handler:
class handleMap{
Handler mHandler = new Handler();
Runnable mTask = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
while(btnRefreshPressed == false){
try{
new getGoogleMap().execute();
mHandler.postDelayed(mTask, INTERVAL);
Thread.sleep(INTERVAL);
} catch(Exception e){
System.out.println(e.toString());
}
}
}
};
public void starReapetingClass (){
hMap.starReapetingClass();
}
public void stopDoing(){
mHandler.stopDoing();
}
}
And in the menubutton where it is called:
case R.id.id_Refresh:
handleMap hMap = new handleMap();
if(btnRefreshPressed == true){
menuItem = item;
menuItem.setActionView(R.layout.progressbar);
menuItem.expandActionView();
fRun += 1;
btnRefreshPressed = false;
hMap.run();
}else if(btnRefreshPressed == false){
if(fRun > 0){
menuItem.collapseActionView();
menuItem.setActionView(null);
}
btnRefreshPressed = true;
hMap.stopHandler();
}
This currently causes the application to freeze, and the system outputs a dialog saying that the app isn't responding, and asking if I want to close or wait.
I suspect it has to with the while statement, but I don't get any errors in logcat.
Thanks in advance.
Just use:
private int mSampleDurationTime = 10000;
private boolean continueToRun = true;
mHandler.postDelayed(mRunnable, mSampleDurationTime);
where mRunnable is your task:
private final Runnable mRunnable = new Runnable() {
//...
public void run() {
...
if(continueToRun == true){
mHandler.postDelayed(mRunnable, mSampleDurationTime);
}
}
...
};
First time you call postDelayed and invoke new Runnable(). After, if you want to continue,
call the same method into run()
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);
}
});
I'm developing an Android 2.3.3 application and I need to run a method every X seconds.
In iOS, I have NSTimer, but in Android I don't know what to use.
Someone have recommend me Handler; another recommend me AlarmManager but I don't know which method fits better with NSTimer.
This is the code I want to implement in Android:
timer2 = [
NSTimer scheduledTimerWithTimeInterval:(1.0f/20.0f)
target:self
selector:#selector(loopTask)
userInfo:nil
repeats:YES
];
timer1 = [
NSTimer scheduledTimerWithTimeInterval:(1.0f/4.0f)
target:self
selector:#selector(isFree)
userInfo:nil
repeats:YES
];
I need something what works like NSTimer.
What do you recommend me?
The solution you will use really depends on how long you need to wait between each execution of your function.
If you are waiting for longer than 10 minutes, I would suggest using AlarmManager.
// Some time when you want to run
Date when = new Date(System.currentTimeMillis());
try {
Intent someIntent = new Intent(someContext, MyReceiver.class); // intent to be launched
// Note: this could be getActivity if you want to launch an activity
PendingIntent pendingIntent = PendingIntent.getBroadcast(
context,
0, // id (optional)
someIntent, // intent to launch
PendingIntent.FLAG_CANCEL_CURRENT // PendingIntent flag
);
AlarmManager alarms = (AlarmManager) context.getSystemService(
Context.ALARM_SERVICE
);
alarms.setRepeating(
AlarmManager.RTC_WAKEUP,
when.getTime(),
AlarmManager.INTERVAL_FIFTEEN_MINUTES,
pendingIntent
);
} catch(Exception e) {
e.printStackTrace();
}
Once you have broadcasted the above Intent, you can receive your Intent by implementing a BroadcastReceiver. Note that this will need to be registered either in your application manifest or via the context.registerReceiver(receiver, intentFilter); method. For more information on BroadcastReceiver's please refer to the official documentation..
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent)
{
System.out.println("MyReceiver: here!") // Do your work here
}
}
If you are waiting for shorter than 10 minutes then I would suggest using a Handler.
final Handler handler = new Handler();
final int delay = 1000; // 1000 milliseconds == 1 second
handler.postDelayed(new Runnable() {
public void run() {
System.out.println("myHandler: here!"); // Do your work here
handler.postDelayed(this, delay);
}
}, delay);
Use Timer for every second...
new Timer().scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
//your method
}
}, 0, 1000);//put here time 1000 milliseconds=1 second
You can please try this code to call the handler every 15 seconds via onResume() and stop it when the activity is not visible, via onPause().
Handler handler = new Handler();
Runnable runnable;
int delay = 15*1000; //Delay for 15 seconds. One second = 1000 milliseconds.
#Override
protected void onResume() {
//start handler as activity become visible
handler.postDelayed( runnable = new Runnable() {
public void run() {
//do something
handler.postDelayed(runnable, delay);
}
}, delay);
super.onResume();
}
// If onPause() is not included the threads will double up when you
// reload the activity
#Override
protected void onPause() {
handler.removeCallbacks(runnable); //stop handler when activity not visible
super.onPause();
}
If you are familiar with RxJava, you can use Observable.interval(), which is pretty neat.
Observable.interval(60, TimeUnits.SECONDS)
.flatMap(new Function<Long, ObservableSource<String>>() {
#Override
public ObservableSource<String> apply(#NonNull Long aLong) throws Exception {
return getDataObservable(); //Where you pull your data
}
});
The downside of this is that you have to architect polling your data in a different way. However, there are a lot of benefits to the Reactive Programming way:
Instead of controlling your data via a callback, you create a stream of data that you subscribe to. This separates the concern of "polling data" logic and "populating UI with your data" logic so that you do not mix your "data source" code and your UI code.
With RxAndroid, you can handle threads in just 2 lines of code.
Observable.interval(60, TimeUnits.SECONDS)
.flatMap(...) // polling data code
.subscribeOn(Schedulers.newThread()) // poll data on a background thread
.observeOn(AndroidSchedulers.mainThread()) // populate UI on main thread
.subscribe(...); // your UI code
Please check out RxJava. It has a high learning curve but it will make handling asynchronous calls in Android so much easier and cleaner.
With Kotlin, we can now make a generic function for this!
object RepeatHelper {
fun repeatDelayed(delay: Long, todo: () -> Unit) {
val handler = Handler()
handler.postDelayed(object : Runnable {
override fun run() {
todo()
handler.postDelayed(this, delay)
}
}, delay)
}
}
And to use, just do:
val delay = 1000L
RepeatHelper.repeatDelayed(delay) {
myRepeatedFunction()
}
new CountDownTimer(120000, 1000) {
public void onTick(long millisUntilFinished) {
txtcounter.setText(" " + millisUntilFinished / 1000);
}
public void onFinish() {
txtcounter.setText(" TimeOut ");
Main2Activity.ShowPayment = false;
EventBus.getDefault().post("go-main");
}
}.start();
Here I used a thread in onCreate() an Activity repeatly, timer does not allow everything in some cases Thread is the solution
Thread t = new Thread() {
#Override
public void run() {
while (!isInterrupted()) {
try {
Thread.sleep(10000); //1000ms = 1 sec
runOnUiThread(new Runnable() {
#Override
public void run() {
SharedPreferences mPrefs = getSharedPreferences("sam", MODE_PRIVATE);
Gson gson = new Gson();
String json = mPrefs.getString("chat_list", "");
GelenMesajlar model = gson.fromJson(json, GelenMesajlar.class);
String sam = "";
ChatAdapter adapter = new ChatAdapter(Chat.this, model.getData());
listview.setAdapter(adapter);
// listview.setStackFromBottom(true);
// Util.showMessage(Chat.this,"Merhabalar");
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
t.start();
In case it needed it can be stoped by
#Override
protected void onDestroy() {
super.onDestroy();
Thread.interrupted();
//t.interrupted();
}
I do it this way and it works fine (the code is written in Kotlin):
private lateinit var runnable: Runnable
private var handler = Handler(Looper.getMainLooper())
private val repeatPeriod: Long = 10000
Then reinit the runnable from inside your function
runnable = Runnable {
// Your code goes here
handler.postDelayed(runnable, repeatPeriod)
}
handler.postDelayed(runnable, repeatPeriod)
Note that if you don't postDelay twice the handler, the loop is not going to be intinity!
In Kotlin, you can do it this way with a Runnable:
private lateinit var runnable: Runnable
private var handler = Handler(Looper.getMainLooper())
private val interval: Long = 1000
private var isRunning = false
val runnable = object : Runnable {
override fun run() {
// Do something every second
function()
// Call your runnable again after interval
handler?.postDelayed(runnable(this, interval))
}
}
// Call your function once
if (!isRunning) {
handler?.postDelayed(runnable, interval)
isRunning = true
}
// Remove your repeatedly called function
if (isRunning) {
handler?.removeCallbacks(runnable)
isRunning = false
}