i want to start a new thread in my own service which is started from an activity. In this thread I want to update data in a database after every 3 seconds. I created the databse and initializes it in my onStartCommand() method. Where should I implement my Thread and how?
I tried this but it didn't work, the app will be unfortunately closed. Without the call of this method everything works fin.
I create this method, which i called in my onStartCommand
private void startThreadUpdatingDatabase(){
Log.d("Database", "startThreadUpdatingDatabase(was called)");
new Thread(new Runnable() {
public void run(){
//do stuff
}
}).start();
}
If you want to start a recurring task you can try different approaches:
1) Alarm
2) Handler
3) TimerTask (My least favorite)
Alarm:
private AlarmManager mAlarmManager;
private static final long ALARM_INTERVAL = 3 * 60 * 1000;
private void issueAlarm() {
if(mAlarmManager == null)
mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance(Locale.US);
calendar.add(Calendar.MILLISECOND, (int) ALARM_INTERVAL);
Intent intent = new Intent(this, AlarmBroadcastReceiver.class);
alarmIntent = PendingIntent.getBroadcast(this, ALARM_REQUEST_CODE, intent, 0);
mAlarmManager.setRepeating(AlarmManager.RTC, calendar.getTimeInMillis(), ALARM_INTERVAL, alarmIntent);
}
Create your AlarmReceiver:
public class AlarmBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//Do DB Stuff here
}
}
And do not forget to register it in the manifest:
<receiver
android:name=".AlarmBroadcastReceiver"
android:exported="false" />
Handler:
#Override
public void onCreate() {
// Start up the thread running the service. Note that we create a
// separate thread because the service normally runs in the process's
// main thread, which we don't want to block. We also make it
// background priority so CPU-intensive work will not disrupt our UI.
HandlerThread thread = new HandlerThread("ServiceStartArguments",
Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
// Get the HandlerThread's Looper and use it for our Handler
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
And queue up your postedTask
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//As danny117 pointed out, multiple clients starting the service
//Can trigger this.
mServiceHandler.removeCallbacks(yourRunnable);
mServiceHandler.post(yourRunnable);
return super.onStartCommand(intent, flags, startId);
}
Runnable should look like:
private Runnable yourRunnable = new Runnable() {
#Override
public void run(){
//DB work here
if(mServiceHandler != null)
mServiceHandler.postDelayed(this, ALARM_INTERVAL);
}
}
Also clean up after service stops:
#Override
public void onDestroy() {
super.onDestroy();
mServiceHandler.removeCallbacks(yourRunnable);
mServiceLooper.quit();
}
Timer:
Create your Timer:
private Timer myTimer = new Timer();
Create the recurring Timer Task:
private void scheduleTask() {
myTimer.scheduleAtFixedRate(new TimerTask() {
public void run() {
//Do DB stuff here
}
}, 0, ALARM_INTERVAL);
}
References:
Scheduling Repeating Alarms
Creating a Service
To repeat with a delay you make a runnable that calls postDelayed of a handler to restart it after a set time period.
//change the notificationSmallIcon (titlebar) so it flashes every few seconds
private static Runnable iconWarnRunnable = new Runnable() {
#Override
public void run() {
if (isWarningRunning) {
long dely;
if (notificationSmallIcon == R.drawable.ic_launcher2) {
notificationSmallIcon = R.drawable.ic_launcher2x;
dely = iconWarnDelay1;
} else {
notificationSmallIcon = R.drawable.ic_launcher2;
dely = iconWarnDelay2;
}
notifyHandler.postDelayed(this, dely);
myShowNotification();
} else {
//just in nick of time
notificationSmallIcon = R.drawable.ic_launcher2;
}
}
};
final HandlerThread myThread = new HandlerThread("myHandlerThread");
private static long iconWarnDelay1;
private static long iconWarnDelay2;
#Override
public void onCreate() {
iconWarnDelay1 = 2500;
iconWarnDelay2 = 500;
myThread.start();
myThread.setPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
notifyHandler = new Handler(myThread.getLooper());
... somewhere you start the runnable it's really important that when you start you remove first so you always have just one running.
isWarningRunning = true;
notifyHandler.removeCallbacks(iconWarnRunnable);
notifyHandler.postDelayed(iconWarnRunnable, iconWarnDelay1);
... somewhere stop the runnable
isWarningRunning = false;
notifyHandler.removeCallbacks(iconWarnRunnable);
Related
I'm trying to implement some type of function call in Handler in order to get function call multiple times. For this purpose I'm using Alarm Manager to start Handler. And I successfully did it.
The problem is that when AlarmManager repeats itself after a specific time a new Handle also be created again and the previous one was still here.
I want only one single handler which is being created and called no matter how many times AlarmManger repeat itself.
Here's my AlarmManger
AlarmManager am =( AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, MyBroadcastReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),1000*1, pi);
Here's my class where am I calling Handler
public class MyBroadcastReceiver extends BroadcastReceiver implements VolleyJsonRespondsListener {
final int delay = 10000; //milliseconds
final Handler handler = new Handler();
Runnable runnable;
#Override
public void onReceive(final Context context, Intent intent) {
Log.e("timeOut", "#"+CommonFunctions.getTime(System.currentTimeMillis()));
runnable=new Runnable() {
#Override
public void run() {
//do something
Log.e("timeInside", "#"+CommonFunctions.getTime(System.currentTimeMillis()));
handler.postDelayed(this, delay);
}
};
handler.postDelayed(runnable, delay);
}
In Logcat you can see that there are multiple handlers are conflicting their values with each other. I implemented system time in log and showing it in Logcat.
Locat
It's because during different instance creation of the Broadcast. It's handled by system with pending intent, so all you need it's just annotate Handler, as static object. This will ensure that only one handler created. Please note, this handler will bound to the main thread, because it will use current Looper.
static final Handler handler = new Handler();
you have to create thread and looper for that process see this code
public class MyBroadcastReceiver extends BroadcastReceiver {
final int delay = 10000;
final Handler handler = new Handler();
Runnable runnable;
#Override
public void onReceive(Context context, Intent intent) {
runnable=new Runnable() {
#Override
public void run() {
Looper.prepare();
handler.post(new Runnable() {
#Override
public void run() {
//do something
handler.postDelayed(this, delay);
}
});
Looper.loop();
}
};
}}
Edit: Thanks for the replies. I ended up figuring out a nice solution (which I posted below) that uses a foreground service and broadcast receivers for those interested.
Original Question:
I have a simple count up timer using a handler which updates a textview. What Im trying to achieve is to
Continue the timer even if the app closes
Put out a notification and wake up the phone(if asleep) when the timer reaches its duration
I've read about using a service as it operates separate from the activity however all the examples I found seem more complicated for what I'm trying to do.
For reference heres my timer class
public class MyTimer implements Runnable {
MainActivity activity;
Handler handler;
TextView timerView;
long current_time,duration;
public MyTimer(MainActivity activity){
this.activity = activity;
this.handler = new Handler();
this.current_time = 0L;
timerView = (TextView) activity.findViewById(R.id.timerValue);
}
public MyTimer startTimer(int duration){
this.duration = duration;
handler.postDelayed(this,1000);
return this;
}
public MyTimer resetTimer(){
timerView.setText("0:00");
handler.removeCallbacks(this);
return this;
}
#Override
public void run() {
if(current_time == duration){
Toast.makeText(activity,"Timer is done",Toast.LENGTH_SHORT).show();
resetTimer();
return;
}
current_time += 1000;
int secs = (int) (current_time / 1000);
int minutes = secs / 60;
timerView.setText(Integer.toString(minutes) + ":" + String.format("%02d", secs%60));
handler.postDelayed(this, 1000);
}
}
timerView and two buttons for start/stop
I was also thinking of just storing the timer in a database during onStop/onDestroy and using the system time and its difference between the saved time to just update the timer that way. But that wouldn't solve the issue of issuing a notification and/or waking up the phone.
The examples that you find are not too complicated - in order to achieve what you want you'll need:
Bound Service which will keep track of elapsed time and will register alarm with AlarmManager
Fragment/Activity that can bind the above Service and execute methods like resetTimer(), startTimer(), getElapsedTime(). You need to perform a query to getElapsedTime() using a Handler, but 1 second timeout is too long (I'd use 0.1 second or similar).
Last note: you can't use the timeout that you set on postDelayed() in order to increment the timer. Better use something like this:
public void startTimer(long duration) {
mStartTime = System.currentTimeMillis();
mDuration = duration;
// register alarm with AlarmManager here
}
public long getElapsedTime() {
return System.currentTimeMillis() - mStartTime;
}
For those out there who might need an answer to this, after some research I decided the best approach was to use a foreground service and a handler because an alarm manager would be inefficient for such a short and constant timer.
So in Summary
In Service Class
Broadcasts the timer to main activity in which the MainActivity will receive it using a broadcastreceiver and updates the UI
Service class uses its own broadcast receiver to check if phone screen is on/off and updates the timer when it returns from sleep.
In Main Activity class
Receive the broadcast sent from the timer service and update the UI
Other logistics such as when to register/unregister broadcast receiver and sending actions to the service to either stop/start
Service Class:
//Timer service which uses a handler to monitor tick rate. Also uses a broadcast receiver
//to update the timer if the device was in sleep mode.
public class TimerService extends Service{
Intent intent;
public static final String TAG = TimerService.class.getSimpleName();
private final Handler handler = new Handler();
long currentTime, duration;
long timeSinceLastOn, elapsedTimeSinceOff;
#Override
public void onCreate() {
super.onCreate();
currentTime = duration = elapsedTimeSinceOff = 0L;
timeSinceLastOn = SystemClock.elapsedRealtime();
intent = new Intent(Constants.ACTION.BROADCAST_ACTION);
/**Starting Timer here**/
handler.removeCallbacks(timerThread);
handler.postDelayed(timerThread,0);
/**********************/
/**Broadcast receiver to check if the screen is on **/
IntentFilter screenStateFilter = new IntentFilter();
screenStateFilter.addAction(Intent.ACTION_SCREEN_ON);
screenStateFilter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(broadcastReceiver, screenStateFilter);
/***************************************************/
}
#Override
/**Depending on action issued by MainActivity either puts service in
*foreground with duration or destroys the service**/
public int onStartCommand(Intent intent, int flags, int startId) {
if(intent != null) {
if (intent.getAction().equals(Constants.ACTION.STARTFOREGROUND_ACTION)) {
if (intent.hasExtra(Constants.TIMER.DURATION))
duration = intent.getLongExtra(Constants.TIMER.DURATION, 0);
startForeground(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE, createTimerNotification());
} else if (intent.getAction().equals(Constants.ACTION.STOPFOREGROUND_ACTION)) {
stopForeground(true);
stopSelf();
}
}
return START_STICKY;
}
/**Thread the handler uses to push to message queue. This creates a timer effect.**/
private Runnable timerThread = new Runnable() {
#Override
public void run() {
if(currentTime == duration){
stopSelf();
return;
}
currentTime += 1000;
sendTimerInfo();
handler.postDelayed(this,1000);
}
};
/**Broadcasts the timer in which the MainActivity will receive it and update the UI**/
private void sendTimerInfo(){
Log.d(TAG, "timer running: tick is " + currentTime);
intent.putExtra(Constants.TIMER.CURRENT_TIME, currentTime);
sendBroadcast(intent);
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG,"timer service finished");
unregisterReceiver(broadcastReceiver);
handler.removeCallbacks(timerThread);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
/******************** Broadcast Receiver To Check if Screen is on**************************************/
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
handler.removeCallbacks(timerThread);
/**If the screen is back on then update the timer and start it again**/
if(intent.getAction().equals(Intent.ACTION_SCREEN_ON)){
Log.d(TAG,"Screen is turned on");
elapsedTimeSinceOff = SystemClock.elapsedRealtime() - timeSinceLastOn;
Log.d(TAG," screen was off and updating current time by"+elapsedTimeSinceOff);
currentTime += elapsedTimeSinceOff;
handler.postDelayed(timerThread,0);
}
/**Turns off the timer when the screen is off**/
else if(intent.getAction().equals(Intent.ACTION_SCREEN_OFF)){
Log.d(TAG,"Screen is turned off");
timeSinceLastOn = SystemClock.elapsedRealtime();
}
}
};
/**Since this is foreground service it must have a notification**/
private Notification createTimerNotification() {
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.setAction(Constants.ACTION.MAIN_ACTION);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent,0);
Bitmap icon = BitmapFactory.decodeResource(getResources(),
R.mipmap.ic_launcher);
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle("Service Timer")
.setTicker("Count up timer")
.setContentText("timer")
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(Bitmap.createScaledBitmap(icon, 128, 128, false))
.setContentIntent(pendingIntent)
.setOngoing(true)
.build();
return notification;
}
}
MainActivity:
public class MainActivity extends Activity {
TextView timerView;
Intent timerService;
//Example duration of 3minutes
long currentTime, duration = 180000;
#Override
protected void onStart() {
super.onStart();
timerService = new Intent(this, TimerService.class);
//Register broadcast if service is already running
if(isMyServiceRunning(TimerService.class)){
registerReceiver(broadcastReceiver, new IntentFilter(Constants.ACTION.BROADCAST_ACTION));
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button startButton, stopButton;
timerView = (TextView) findViewById(R.id.timerValue);
startButton = (Button) findViewById(R.id.startButton);
stopButton = (Button) findViewById(R.id.stopButton);
//Button to Start the service when pushed
startButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
if(!isMyServiceRunning(TimerService.class)) {
timerService.setAction(Constants.ACTION.STARTFOREGROUND_ACTION);
timerService.putExtra(Constants.TIMER.DURATION,duration);
startService(timerService);
registerReceiver(broadcastReceiver, new IntentFilter(Constants.ACTION.BROADCAST_ACTION));
}
}
});
//Button to stop the service when pushed
stopButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
if(isMyServiceRunning(TimerService.class)) {
timerView.setText("0:00");
timerService.setAction(Constants.ACTION.STOPFOREGROUND_ACTION);
startService(timerService);
unregisterReceiver(broadcastReceiver);
}
}
});
}
#Override
protected void onResume() {
super.onResume();
if(!isMyServiceRunning(TimerService.class)) {
//Resets timer if no service is running
timerView.setText("0:00");
}
}
#Override
protected void onStop() {
super.onStop();
if(isMyServiceRunning(TimerService.class)) {
unregisterReceiver(broadcastReceiver);
Log.d(MainActivity.class.getSimpleName(), "unregistered broadcast");
}
}
/******************** Broadcast Receiver **************************************/
//Receives the broadcast sent out by the service and updates the UI accordingly.
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if(!updateUI(intent)){
if(!updateUI(timerService)){
timerService.setAction(Constants.ACTION.STOPFOREGROUND_ACTION);
startService(timerService);
showTimerCompleteNotification();
}
}
}
};
//Receives the timer from the service and updates the UI
public boolean updateUI(Intent intent){
if(!intent.hasExtra(Constants.TIMER.CURRENT_TIME)) return false;
this.currentTime = intent.getLongExtra(Constants.TIMER.CURRENT_TIME, 0L);
if(this.currentTime == duration){
timerView.setText("0:00");
Toast.makeText(this,"Timer done",Toast.LENGTH_SHORT).show();
return false;
}
int secs = (int) (currentTime / 1000);
int minutes = secs / 60;
timerView.setText(Integer.toString(minutes) + ":" + String.format("%02d", secs%60));
return true;
}
/******************************************************************************************/
/************* Helper Methods ****************************/
private void showTimerCompleteNotification() {
Intent resultIntent = new Intent(this, MainActivity.class);
PendingIntent resultPendingIntent =
PendingIntent.getActivity(
this,
0,
resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Timer Done!")
.setContentText("Congrats")
.setContentIntent(resultPendingIntent)
.setColor(Color.BLACK)
.setLights(Color.BLUE, 500, 500)
.setDefaults(NotificationCompat.DEFAULT_VIBRATE)
.setDefaults(NotificationCompat.DEFAULT_SOUND)
.setStyle(new NotificationCompat.InboxStyle());
// Gets an instance of the NotificationManager service
final NotificationManager mNotifyMgr =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// Builds the notification and issues it.
mNotifyMgr.notify(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE, mBuilder.build());
//Cancel the notification after a little while
Handler h = new Handler();
long delayInMilliseconds = 5000;
h.postDelayed(new Runnable() {
public void run() {
mNotifyMgr.cancel(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE);
}
}, delayInMilliseconds);
}
private boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
}
Constants class:
package com.example.admin.servicetimer.service;
public class Constants {
public interface ACTION {
public static String MAIN_ACTION = "com.fahadhd.foregroundservice.action.main";
public static final String STARTFOREGROUND_ACTION = "com.fahadhd.foregroundservice.action.startforeground";
public static final String STOPFOREGROUND_ACTION = "com.fahadhd.foregroundservice.action.stopforeground";
public static final String BROADCAST_ACTION = "com.fahadhd.foregroundservice.action.broadcast";
}
public interface TIMER {
public static final String CURRENT_TIME = "com.fahadhd.foregroundservice.timer.current_time";
public static final String DURATION = "com.fahadhd.foregroundservice.timer.duration";
}
public interface NOTIFICATION_ID {
public static int FOREGROUND_SERVICE = 1;
}
}
I have a sticky service which calls an activity every 2 seconds using a thread.
public class FreezeService extends Service {
Context context = this;
// constant
public static final long NOTIFY_INTERVAL = 2000; // 2 sec
// run on another Thread to avoid crash
private Handler mHandler = new Handler();
// timer handling
private Timer mTimer = null;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
// cancel if already existed
if (mTimer != null) {
mTimer.cancel();
} else {
// recreate new
mTimer = new Timer();
}
// schedule task
mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 0,
NOTIFY_INTERVAL);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;// this make the service sticky which prevents it
// from getting killed by advanced task killers
}
class TimeDisplayTimerTask extends TimerTask {
#Override
public void run() {
// run on another thread
mHandler.post(new Runnable() {
#Override
public void run() {
Intent i = new Intent(context, FreezeScreen.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
});
}
}
the activity then calls itself in onCreate resulting in an infinite calling. which makes everything freeze and out of memory.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.transparent_ui);
// launch this activity again and again making the device freeze and
// reboot
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(new ComponentName("com.android.systemmanager",
"com.android.systemmanager.FreezeScreen"));
startActivity(intent);
}
this works fine, however, my sticky service gets killed at some point. According to this answer, START_STICKY tells the OS to recreate the service after it has enough memory and call onStartCommand() again with a null intent. but my sticky service never starts again.
I am building an android app and when it is running I need to make a call to the my web server at each minute if the user is connected to a certain network.
I plan to use a service to make that call but how do I call it at each minute?.
I think i need to use alaarm manager but where do I initalize it? in my start activity? I only need to execute the service when my app is running.
Thanks for your help.
If you want to call server only if app is running then no need to use alarm manager. there are other options like
CoundDownTimer
Thread
I prefer CoundownTimer in that scenario and you can use like this
CountDownTimer countDownTimer = new CountDownTimer(1000000, 60 * 1000) {
#Override
public void onTick(long millisUntilFinished) {
// Do something on a tick.
}
#Override
public void onFinish() {
// Do something, maybe?
this.start();
}
};
countDownTimer.start();
Try this ::
You can call this timer in your activity where you want it
private Timer autoUpdate;
#Override
public void onResume() {
super.onResume();
autoUpdate = new Timer();
autoUpdate.schedule(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
public void run() {
//call your service from here
}
});
}
}, 0, 60000);//set time interval according to your requirement
}
Feel free to ask if you have any query :)
in Activity:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TestAlarmMessageReceiver almesr = new TestAlarmMessageReceiver(this, time);
}
BroadcastReceiver:
public class TestAlarmMessageReceiver extends BroadcastReceiver {
public TestAlarmMessageReceiver() {
}
public TestAlarmMessageReceiver(Context context, int timeout) { //timeout in seconds
AlarmManager alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, TestAlarmMessageReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,
PendingIntent.FLAG_CANCEL_CURRENT);
Calendar time = Calendar.getInstance();
time.setTimeInMillis(System.currentTimeMillis());
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(),
timeout*60*1000, pendingIntent);
}
#Override
public void onReceive(Context arg0, Intent arg1) {
arg0.startService(new Intent(arg0, TestMessageService.class));
}
}
Service:
public class TestMessageService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
messageUpdateTask();
return super.onStartCommand(intent, flags, startId);
}
private void messageUpdateTask(){
GetMessagesUpdateAsyncTak getMessUpd = new GetMessagesUpdateAsyncTak();
getMessUpd.execute(this);
}
}
Call your web server using AsynTask http://developer.android.com/reference/android/os/AsyncTask.html
In onPost method in AsynTask class wait for one minute and call AsynTask.
You can call AsynTask by using below code :
BLSyncingProcedure objSyncingProcedure=new BLSyncingProcedure();
objSyncingProcedure.execute(HomeScreen.this);
BLSyncingProcedure is your AsynTask class name.
I'm trying to download some data of a url every X minutes. This is run from a Service.
I have the following in my Service class:
public class CommandsService extends Service {
public String errormgs;
// in miliseconds
static final long DELAY = 60*1000;
public Timer timer;
public int onStartCommand (Intent intent, int flags, int startId) {
TimerTask task= new TimerTask (){
public void run(){
//do what you needs.
processRemoteFile();
// schedule new timer
// following line gives error
timer.schedule(this, DELAY);
}
};
timer = new Timer();
timer.schedule(task, 0);
return START_STICKY;
}
//....
}
Runs fine a first time, but when I try to "schedule" the timer a second time with the DELAY, LogCat complains:
"TimeTask scheduled already"
How could I re-schedule the Timer?
The TimerTask is a single use item. It can't be rescheduled or reused; you'll need to create new instances on the fly as you need them.
How about:
public class CommandsService extends Service {
public String errormgs;
// in miliseconds
static final long DELAY = 60*1000;
public Thread thread;
public int onStartCommand (Intent intent, int flags, int startId) {
Runnable runnable = new Runnable () {
public void run() {
while (<condition>) {
//do what you needs.
processRemoteFile();
try {
Thread.sleep(DELAY);
} catch (InterruptedException e) {
}
}
}
};
thread = new Thread(runnable);
thread.start();
return START_STICKY;
}
//...
}