4

I have an Android app with manage a countdowntimer (class CountDownTimer) that it is shown in app screen, to show how much time left to arrive 00:00.

My problem now is that when I press home button or when I launch another app the app/timer does not run in the background. So I suspect I must do a service, but how? Colleagues have said to me that I must do something special for when the device gets locked in order for the timer to continue. I want to wake up when arrived to 0.

What is the best way to do this?

MysticMagicϡ
  • 28,593
  • 16
  • 73
  • 124
Tibor
  • 589
  • 2
  • 7
  • 20

3 Answers3

1

You must create your CountDownTimer class and extend it from Service class. By doing so your activity becomes a service and it runs in the background even if you close the application or the screen it doesnt matter it just does the task that you assign to it in the background .

Serdar Dogruyol
  • 5,147
  • 3
  • 24
  • 32
  • Currently I have: "public class MyCount extends CountDownTimer{ ...." to use the onTic routine, so I understand I must create a MyCount extends service, and inside it "my class extend CountDownTimer"???? In that case, if I update de textview of time remaining from the tics routine of my class (countdowntimer), does it will update correctly? – Tibor Nov 14 '11 at 17:23
  • I am also looking into asyntask, that it will update UI easily. If I send my app to background (ie launching another app), can this configuration will be killed? – Tibor Nov 16 '11 at 16:02
  • Also another question: if I extend a service as you say, will I need something special to update calling class UI? thx – Tibor Nov 16 '11 at 16:03
  • Yeah it'll update the UI properly if your service is working good and your AsyncTask is written okay.Even if the program is closed and you open another application your service will run in background and do the job.You dont need to do something special if you extend the service it's the same and AsyncTask will update the Ui so you gonna make the call from there. – Serdar Dogruyol Nov 16 '11 at 16:07
  • I was thinking in Asyntask into the UI thread, not in a service, in order to try a service, that looks complex to me. – Tibor Nov 17 '11 at 10:09
  • more quiestion: if I implement a service, how has to update the ui, the service or the app when it comes to front? – Tibor Nov 17 '11 at 10:10
  • A service is also an activity.You can create a class which extends from service and in that class you can use an AsyncTask to do your background job.Actually there's not much difference creating from a normal activity.You can start the service activity from any another service that you want to. – Serdar Dogruyol Nov 17 '11 at 10:13
  • but I have doubts about who has to update the UI activity. Activity itself (asking data to service), or the service calling "paint" members of the ui activity? – Tibor Nov 17 '11 at 11:42
0

The easiest way is use the service with timer async. You can download the source from here (Android Countdown Timer Run In Background)

Service Class:

package com.countdowntimerservice;


import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Handler;
 import android.os.IBinder;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import android.util.Log;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;

public class Timer_Service extends Service {

public static String str_receiver = "com.countdowntimerservice.receiver";

private Handler mHandler = new Handler();
Calendar calendar;
SimpleDateFormat simpleDateFormat;
String strDate;
Date date_current, date_diff;
SharedPreferences mpref;
SharedPreferences.Editor mEditor;

private Timer mTimer = null;
public static final long NOTIFY_INTERVAL = 1000;
Intent intent;

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public void onCreate() {
    super.onCreate();

    mpref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
    mEditor = mpref.edit();
    calendar = Calendar.getInstance();
    simpleDateFormat = new SimpleDateFormat("HH:mm:ss");

    mTimer = new Timer();
    mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 5, NOTIFY_INTERVAL);
    intent = new Intent(str_receiver);
}


class TimeDisplayTimerTask extends TimerTask {

    @Override
    public void run() {
        mHandler.post(new Runnable() {

            @Override
            public void run() {

                calendar = Calendar.getInstance();
                simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
                strDate = simpleDateFormat.format(calendar.getTime());
                Log.e("strDate", strDate);
                twoDatesBetweenTime();

            }

        });
    }

}

public String twoDatesBetweenTime() {


    try {
        date_current = simpleDateFormat.parse(strDate);
    } catch (Exception e) {

    }

    try {
        date_diff = simpleDateFormat.parse(mpref.getString("data", ""));
    } catch (Exception e) {

    }

    try {


        long diff = date_current.getTime() - date_diff.getTime();
        int int_hours = Integer.valueOf(mpref.getString("hours", ""));

        long int_timer = TimeUnit.HOURS.toMillis(int_hours);
        long long_hours = int_timer - diff;
        long diffSeconds2 = long_hours / 1000 % 60;
        long diffMinutes2 = long_hours / (60 * 1000) % 60;
        long diffHours2 = long_hours / (60 * 60 * 1000) % 24;


        if (long_hours > 0) {
            String str_testing = diffHours2 + ":" + diffMinutes2 + ":" + diffSeconds2;

            Log.e("TIME", str_testing);

            fn_update(str_testing);
        } else {
            mEditor.putBoolean("finish", true).commit();
            mTimer.cancel();
        }
    }catch (Exception e){
        mTimer.cancel();
        mTimer.purge();


    }

    return "";

}

@Override
public void onDestroy() {
    super.onDestroy();
    Log.e("Service finish","Finish");
}

private void fn_update(String str_time){

    intent.putExtra("time",str_time);
    sendBroadcast(intent);
}
}
Deepshikha Puri
  • 2,104
  • 22
  • 23
0

First off, You need to use a Handler to operate the timer, but check out this great post to see if it helps:

How to set a timer in android

Android Developer Resources touch on this topic as well:

http://developer.android.com/resources/articles/timed-ui-updates.html

Community
  • 1
  • 1
SQLiteNoob
  • 2,958
  • 3
  • 29
  • 44