Android: re-starting Timer fails - android

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;
}
//...
}

Related

Service stops when App stop

When I close App service stops running,
I have tried START_STICKY but still not working.
I need to show notification whenever server respond
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Timer timer = new Timer();
timer.schedule(new Receive(), 0, 5000);
return START_STICKY;
}
Here is my enitre Class
http://justpaste.it/14gqd
you need to bind it with notification. then system allows to run service.
#Override
public int onStartCommand(Intent intent, int flags, int startId){
startForeground(999, bindService()/*function to return notification*/);
return START_REDELIVER_INTENT;
}
and this function to return notification.
protected Notification bindService(){
Notification.Builder mBuilder = new Notification.Builder(this);
/*customize notification builder here*/
return mBuilder.build();
}
Service is Killed As Activity is Destroyed , You might Wanna Look into JobScheduler or use TimerTask(Easy to Implements)
Timer Task Example
#Override
public void onStart(Intent intent, int startId) {
// Perform your long running operations here.
//Creating new thread for service
//Always write your long running tasks in a separate thread, to avoid ANR
final Handler handler = new Handler();
timer = new Timer();
TimerTask task = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
public void run() {
Log.i(TAG, "Service running");
}
});
}
};
timer.scheduleAtFixedRate(task, 0, 10000); // Executes thetask every 5 seconds.

How do I stop my thread and will my service stop too if I do?

I'm currently working on my first android app and I've run into a problem.
My app is supposed to be counting in the background using a Service and I'm creating a new thread to handle that. If I don't stop the thread in my Service's onDestroy() method, my phone gives me the message "Unfortunately, (my app) has stopped." every time I close the app. I need to stop it somehow, and I tried to do it using :
while(!Thread.currentThread().isInterrupted()){
**my code**
}:
And then interrupting it in the onDestroy() method.
It works, but it makes my app count extremely fast, so I would like to know if it can be done any other way that does not change the functionaliy of my code.
Also, since my thread gets stopped in the onDestroy method, I guess my service stops as well. Is there any way to keep my service running even when my app has been closed?
Here's my code:
public class CounterService extends Service {
private Handler handler;
private int time = -1;
private boolean isActive;
private Intent timeBroadcaster;
private Runnable counter;
private Thread serviceCounter;
#Override
public void onCreate(){
super.onCreate();
handler = new Handler();
timeBroadcaster = new Intent();
timeBroadcaster.setAction("EXAMPLE_BROADCAST");
counter = new Runnable() {
#Override
public void run() {
isActive = ((PowerManager) getSystemService(Context.POWER_SERVICE)).isInteractive();
if (isActive) {
handler.postDelayed(this, 1000);
time += 1;
} else {
if (time > 5) {
//log
}
time = 0;
handler.postDelayed(this, 1000);
}
timeBroadcaster.putExtra("counter", time);
sendBroadcast(timeBroadcaster);
}
};
serviceCounter = new Thread(counter);
serviceCounter.start();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy(){
//serviceCounter.interrupt();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
Is there any way to keep my service running even when my app has been closed?
you can use sync adapter which runs in background even app is stoped.
https://developer.android.com/training/sync-adapters/creating-sync-adapter.html

Android: Start a thread in a service

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);

Android create handler inside thread into Service

i'm writing simple android service and i want to use such as Toast or Notification but i get this error:
FATAL EXCEPTION: Thread-17116
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
i can not use runOnUiThread . my service does not know that. for example i try to use that with : this, getBaseContect(), getApplication, mContext for .runOnUiThread(new Runnable() {}
i get problem and i can not resolve problem.
this is my code:
public class TsmsService extends Service {
private Timer smsThread;
private DatabaseHandler db;
private SQLiteDatabase dbHelper;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
smsThread = new Timer();
GetSMSThread getSMSThread = new GetSMSThread(getBaseContext());
smsThread.scheduleAtFixedRate(getSMSThread, 0, 1000); //(timertask,delay,period)
return super.onStartCommand(intent, flags, startId);
}
public class GetSMSThread extends TimerTask {
private Context mContext;
public GetSMSThread(Context context) {
mContext = context;
}
#Override
public void run() {
this.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getApplication() , "Service is Running ... " , Toast.LENGTH_SHORT).show();
}
});
}
}
}
Try creating a Handler in onStartCommand (so, from the UI thread). Then use that Handler to trigger the Toast. For example:
private Handler mToastHandler = null;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
...
mToastHandler = new Handler();
...
}
...
// from inside your child thread
mToastHandler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(...);
}
});
Here you can use ResultReceiver that is used for the purpose of receiving a callback result from someone. In your case its Service
You can check the complete example of Service with TimerTask using ResultReceiver for updating the UI inside Activity

Service doesnot stop after activity destroy

I have written a service with timer to do something periodically but when I stop service service from mainActivity if my service is in middle of their task it's continue to finish and after that stop it and the same issue when i want to close application that call OnDestroy on Main Activity service work and after finish their task don't start again.
My Question is how can Force stop service when i want to exit from my app?
this is my service code
public class MyTimerService extends Service{
private static int counter = 0;
private Timer timer = new Timer();
private int INTERVAL;
#Override
public IBinder onBind(Intent i) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
INTERVAL = intent.getIntExtra("time", 500);
repaet();
return START_NOT_STICKY;
}
private void repaet() {
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
Log.i("Saeed", String.valueOf(++counter));
}
}, 0, INTERVAL);
}
#Override
public void onDestroy() {
Toast.makeText(this, "Stop Service", Toast.LENGTH_LONG).show();
if(timer!=null){
timer.cancel();
}
stopSelf();
super.onDestroy();
}
}
Have you tried to manually stop your service inside onDestroy() by using this stopService()?

Categories

Resources