我正在制作 Countdown Timer Android应用,其中我正在启动一个名为TimerService的服务,以便即使将应用发送到后台也能保持计时器正常运行。我想在启动计时器时在服务中设置计时器持续时间。当触发警报时,我想通过通知通知用户。我正在使用处理程序运行计时器。 目前我已经尝试在我将counDownDuration传递给setAlarm(long)的服务中设置警报。当触发警报时,接收器类会显示一个toast。但问题是,警报在随机时间时触发。(主要在3-5秒内)
这是我的代码:
TimerService.java
private long countDownDuration = 25000;//25 sec timer
public void startTimer(){
mIsTimerRunning = true;
startTime = SystemClock.elapsedRealtime();
setAlarm(countdownTimer);
Log.i(TAG,"Timer Started");
}
private void setAlarm(long countDownDuration){
mAlarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, TimerExpiredReceiver.class);
PendingIntent sender = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mAlarmManager.setExact(ELAPSED_REALTIME_WAKEUP, countDownDuration, sender);
} else {
mAlarmManager.set(ELAPSED_REALTIME_WAKEUP, countDownDuration, sender);
}
Log.i(TAG,"Alarm Set of " + countDownDuration/1000 );
}
private void cancelAlarm(){
Intent intent = new Intent(this, TimerExpiredReceiver.class);
PendingIntent sender = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
mAlarmManager.cancel(sender);
Log.i(TAG,"Alarm Cancelled");
}
TimerExpiredReceiver.java
public class TimerExpiredReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// context.mIsTImerRunning = false;
Toast.makeText(context,"Time's Up!!",Toast.LENGTH_LONG).show();
}}
更新1: 找出随机触发的原因。在TimerService的startTimer()和setAlarm(long)中进行了更改。 这是更新的TimerSerive代码:
public class TimerService extends Service {
protected static final String TAG = "TimerService";
private long startTime, endTime;
private boolean mIsTimerRunning;
private final IBinder mBinder = new TimerBinder();
private static int count = 0;
private long countDownDuration = 25000;//25 sec timer
private long wakeUpTime;
private AlarmManager mAlarmManager;
private BroadcastReceiver mAlarmReceiver;
public TimerService() {
count++;
Log.i(TAG,"TimerService Object No. " + count);
}
@Override
public void onCreate() {
Log.i(TAG, "Service Created");
startTime = 0;
endTime = 0;
mIsTimerRunning = false;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG,"Service Started");
return Service.START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG,"Service Bound");
return mBinder;
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG,"Service Destroyed");
}
public void startTimer(){
mIsTimerRunning = true;
startTime = SystemClock.elapsedRealtime();
wakeUpTime = startTime + countDownDuration;
setAlarm(wakeUpTime);
Log.i(TAG,"Timer Started");
}
public void stopTimer(){
mIsTimerRunning = false;
endTime = SystemClock.elapsedRealtime() - startTime;
cancelAlarm();
Log.i(TAG,"Timer Stopped : endtime = " + endTime);
}
public int getElapsedTime(){
return (int)TimeUnit.MILLISECONDS.toSeconds(SystemClock.elapsedRealtime() - startTime);
}
public boolean isTimerRunning() {
return mIsTimerRunning;
}
private void setAlarm(long wakeUpTime){
mAlarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, TimerExpiredReceiver.class);
PendingIntent sender = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mAlarmManager.setExact(ELAPSED_REALTIME_WAKEUP, wakeUpTime, sender);
} else {
mAlarmManager.set(ELAPSED_REALTIME_WAKEUP, wakeUpTime, sender);
}
Log.i(TAG,"Alarm Set of " + wakeUpTime/1000 );
}
private void cancelAlarm(){
Intent intent = new Intent(this, TimerExpiredReceiver.class);
PendingIntent sender = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
mAlarmManager.cancel(sender);
Log.i(TAG,"Alarm Cancelled");
}
public class TimerBinder extends Binder {
TimerService getService() {
return TimerService.this;
}
}}
问题: 现在正在寻找一种方法将 TimerExpiredReceiver 代码置于 Timerservice中,以便它可以注册和取消注册服务。除了接收器可以访问 TimerService类的成员,并且可以显示通知而不是 toast 。 任何帮助,将不胜感激。 谢谢!
答案 0 :(得分:0)
在你的计数器到期后启动闹钟服务,并将时间设置为0,以便它开始响铃
Intent intent = new Intent(DashboardScreen.this, ServiceClass.class);
PendingIntent pintent = PendingIntent.getService(DashboardScreen.this, 0, intent, 0);
AlarmManager alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 0*1000, pintent);
希望这可以帮到你!