How to run CountDownTimer in a Service in Android?

前端 未结 2 1851
南旧
南旧 2020-11-28 08:07

I want a service which runs a CountDownTimer and in every tick I want to show the countdown in a Activity and after some interval play a sound.

All the process are g

相关标签:
2条回答
  • 2020-11-28 08:55

    Download source code Android Countdown Timer Run In Background

    activity_main.xml

    <RelativeLayout android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android">
    
    
        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/et_hours"
            android:hint="Hours"
            android:inputType="time"
            android:layout_marginRight="5dp"
            />
    
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/btn_timer"
        android:layout_above="@+id/btn_cancel"
        android:text="Start Timer"/>
    
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:id="@+id/btn_cancel"
        android:text="cancel timer"/>
    
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/tv_timer"
        android:layout_centerInParent="true"
        android:textSize="25dp"
        android:textColor="#000000"
        android:text="00:00:00"/>
    
    </RelativeLayout>
    

    Timer_Service.java

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

    MainActivity.java

    package com.countdowntimerservice;
    
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.content.IntentFilter;
    import android.content.SharedPreferences;
    import android.preference.PreferenceManager;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.TextView;
    import android.widget.Toast;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    
    
    public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    
    private Button btn_start, btn_cancel;
    private TextView tv_timer;
    String date_time;
    Calendar calendar;
    SimpleDateFormat simpleDateFormat;
    EditText et_hours;
    
    SharedPreferences mpref;
    SharedPreferences.Editor mEditor;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
        listener();
    
    
    }
    
    private void init() {
        btn_start = (Button) findViewById(R.id.btn_timer);
        tv_timer = (TextView) findViewById(R.id.tv_timer);
        et_hours = (EditText) findViewById(R.id.et_hours);
        btn_cancel = (Button) findViewById(R.id.btn_cancel);
    
    
    
        mpref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        mEditor = mpref.edit();
    
        try {
            String str_value = mpref.getString("data", "");
            if (str_value.matches("")) {
                et_hours.setEnabled(true);
                btn_start.setEnabled(true);
                tv_timer.setText("");
    
            } else {
    
                if (mpref.getBoolean("finish", false)) {
                    et_hours.setEnabled(true);
                    btn_start.setEnabled(true);
                    tv_timer.setText("");
                } else {
    
                    et_hours.setEnabled(false);
                    btn_start.setEnabled(false);
                    tv_timer.setText(str_value);
                }
            }
        } catch (Exception e) {
    
        }
    
    
    
    }
    
    private void listener() {
        btn_start.setOnClickListener(this);
        btn_cancel.setOnClickListener(this);
    
    }
    
    @Override
    public void onClick(View v) {
    
        switch (v.getId()) {
            case R.id.btn_timer:
    
    
                if (et_hours.getText().toString().length() > 0) {
    
                    int int_hours = Integer.valueOf(et_hours.getText().toString());
    
                    if (int_hours<=24) {
    
    
                        et_hours.setEnabled(false);
                        btn_start.setEnabled(false);
    
    
                        calendar = Calendar.getInstance();
                        simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
                        date_time = simpleDateFormat.format(calendar.getTime());
    
                        mEditor.putString("data", date_time).commit();
                        mEditor.putString("hours", et_hours.getText().toString()).commit();
    
    
                        Intent intent_service = new Intent(getApplicationContext(), Timer_Service.class);
                        startService(intent_service);
                    }else {
                        Toast.makeText(getApplicationContext(),"Please select the value below 24 hours",Toast.LENGTH_SHORT).show();
                    }
    /*
                    mTimer = new Timer();
                    mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 5, NOTIFY_INTERVAL);*/
                } else {
                    Toast.makeText(getApplicationContext(), "Please select value", Toast.LENGTH_SHORT).show();
                }
                break;
    
    
            case R.id.btn_cancel:
    
    
             Intent intent = new Intent(getApplicationContext(),Timer_Service.class);
             stopService(intent);
    
                mEditor.clear().commit();
    
                et_hours.setEnabled(true);
                btn_start.setEnabled(true);
                tv_timer.setText("");
    
    
                break;
    
        }
    
    }
    
    private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String str_time = intent.getStringExtra("time");
            tv_timer.setText(str_time);
    
        }
    };
    
    @Override
    protected void onResume() {
        super.onResume();
        registerReceiver(broadcastReceiver,new IntentFilter(Timer_Service.str_receiver));
    
    }
    
    @Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(broadcastReceiver);
    }
    }
    
    0 讨论(0)
  • 2020-11-28 09:01

    The easiest way is probably to create a broadcast receiver in your activity and have the service send broadcasts to the receiver. Here's a full listing for a service class with a simplified CountDownTimer.

    package com.example.cdt;
    
    import android.app.Service;
    import android.content.Intent;
    import android.os.CountDownTimer;
    import android.os.IBinder;
    import android.util.Log;
    
    public class BroadcastService extends Service {
    
        private final static String TAG = "BroadcastService";
    
        public static final String COUNTDOWN_BR = "your_package_name.countdown_br";
        Intent bi = new Intent(COUNTDOWN_BR);
    
        CountDownTimer cdt = null;
    
        @Override
            public void onCreate() {       
                super.onCreate();
    
                Log.i(TAG, "Starting timer...");
    
                cdt = new CountDownTimer(30000, 1000) {
                    @Override
                    public void onTick(long millisUntilFinished) {
    
                        Log.i(TAG, "Countdown seconds remaining: " + millisUntilFinished / 1000);
                        bi.putExtra("countdown", millisUntilFinished);
                        sendBroadcast(bi);
                    }
    
                    @Override
                    public void onFinish() {
                        Log.i(TAG, "Timer finished");
                    }
                };
    
                cdt.start();
            }
    
            @Override
            public void onDestroy() {
    
                cdt.cancel();
                Log.i(TAG, "Timer cancelled");
                super.onDestroy();
            }
    
            @Override
            public int onStartCommand(Intent intent, int flags, int startId) {       
                return super.onStartCommand(intent, flags, startId);
            }
    
            @Override
            public IBinder onBind(Intent arg0) {       
                return null;
            }
    }
    

    And here are the relevant lines from a main activity:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    
        startService(new Intent(this, BroadcastService.class));
        Log.i(TAG, "Started service");
    }
    
    private BroadcastReceiver br = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {            
            updateGUI(intent); // or whatever method used to update your GUI fields
        }
    };
    
    @Override  
    public void onResume() {
        super.onResume();        
        registerReceiver(br, new IntentFilter(BroadcastService.COUNTDOWN_BR));
        Log.i(TAG, "Registered broacast receiver");
        }
    
    @Override
    public void onPause() {
        super.onPause();
        unregisterReceiver(br);
        Log.i(TAG, "Unregistered broacast receiver");
    }
    
    @Override
    public void onStop() {
        try {
            unregisterReceiver(br);
        } catch (Exception e) {
            // Receiver was probably already stopped in onPause()
        }
        super.onStop();
    }
    @Override
    public void onDestroy() {        
        stopService(new Intent(this, BroadcastService.class));
        Log.i(TAG, "Stopped service");
        super.onDestroy();
    }
    
    private void updateGUI(Intent intent) {
        if (intent.getExtras() != null) {
            long millisUntilFinished = intent.getLongExtra("countdown", 0);
            Log.i(TAG, "Countdown seconds remaining: " +  millisUntilFinished / 1000);            
        }
    }
    

    You'll also need to define the service between the start/end application tags in your manifest file.

    <service android:name=".BroadcastService" />
    
    0 讨论(0)
提交回复
热议问题