如何在Android的服务中运行倒计时?

如何在Android的服务中运行倒计时?,android,android-service,Android,Android Service,我想要一个运行倒计时的服务,在每一个滴答声中,我想显示活动中的倒计时,并在某个间隔后播放声音 在单个活动中,所有过程都进行得很顺利,但在传入呼叫期间,倒计时不起作用,这就是我希望使用服务来完成此操作的原因 有人能帮我吗 提前谢谢 更新 最简单的方法可能是在活动中创建广播接收器,并让服务向接收器发送广播。下面是一个带有简化倒计时的服务类的完整列表 package com.example.cdt; import android.app.Service; import android.content

我想要一个运行倒计时的服务,在每一个滴答声中,我想显示活动中的倒计时,并在某个间隔后播放声音

在单个活动中,所有过程都进行得很顺利,但在传入呼叫期间,倒计时不起作用,这就是我希望使用服务来完成此操作的原因

有人能帮我吗

提前谢谢

更新


最简单的方法可能是在活动中创建广播接收器,并让服务向接收器发送广播。下面是一个带有简化倒计时的服务类的完整列表

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;
        }
}
以下是一项主要活动的相关内容:

@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);            
    }
}
您还需要在清单文件中的开始/结束应用程序标记之间定义服务

<service android:name=".BroadcastService" />
下载源代码

activity_main.xml

MainActivity.java


try是否会在来电期间运行?在应用程序切换期间计时器会停止。try可能会对您有所帮助。我已经这样做了,但我希望在服务中运行计时器,并且倒计时将显示在活动中。如果我在onPause中停止服务,则在来电期间计时器会停止。您没有停止服务;您正在停止活动中的广播接收器。换句话说,你只是告诉Android你的活动不需要在它睡觉的时候收听广播。在这段时间内,服务将继续发送它们,但它们将被忽略。我应该使用哪种类型的服务?你能发布一些代码吗?我已经修改了我的答案来展示一个更完整的例子。为了更普遍地提供帮助,它不包括特定的计时器操作。=只传递回一个长值。您需要调整代码以满足您的需要。它工作正常,但如何从onCreate中的调用方活动获取意向发送。我可以从onStartCommand获得它,但在onStartCommand之前调用onCreate。代码正常,但当我从最近打开的应用程序中清除应用程序并再次启动时,计时器正在运行。当用户从中删除时,如何取消它来自于背景
<service android:name=".BroadcastService" />
<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>
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);
}
}
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);
}
}