当屏幕关闭时,倒计时器无法正常工作。

3
我实现了一个扩展 CountDownTimer 的类,它能正常工作,但当屏幕关闭时,定时器就会失去同步。因此,当我离开活动或屏幕关闭时,CountDownTimer 应该继续正确地工作。我拥有 <uses-permission android:name="android.permission.WAKE_LOCK"/> 权限,并尝试使用 PowerManager,但我认为问题不在那里。请帮我解决这个问题。
PowerManager pm = (PowerManager) getSystemService((MenuApp.this).POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag");
       wl.acquire();
       myTimer =  new CustomTimer(min, 1000); 
       myTimer.start();                    
       wl.release();

.

@TargetApi(Build.VERSION_CODES.GINGERBREAD) @SuppressLint("NewApi")
public class CustomTimer extends CountDownTimer
{
    public CustomTimer(long millisInFuture, long countDownInterval) 
    {

        super( millisInFuture, countDownInterval );
        byteTimer = 1;
    }
    @TargetApi(Build.VERSION_CODES.GINGERBREAD) 
    @SuppressLint("NewApi")
    @Override
    public synchronized void onTick(long millisUntilDone) 
    {
   String hms = String.format("%02d:%02d", 
           TimeUnit.MILLISECONDS.toMinutes(millisUntilDone)- TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millisUntilDone)),
           TimeUnit.MILLISECONDS.toSeconds(millisUntilDone)-TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millisUntilDone)));

                 tim.setText(hms);
                 edit.putLong("Minute",  millisUntilDone-1669);
                 edit.commit();

    }
    @TargetApi(Build.VERSION_CODES.GINGERBREAD) 
    @SuppressLint("NewApi")
    @Override
    public synchronized void onFinish() 
    {   
        tim.setText("00:00");
                seconds = 0L;
                if(btnToggle.isChecked()){   
                        btnToggle.setChecked(false);
                        btnToggleTimer.setChecked(false);                   
                    }else{
                        btnToggle.setChecked(true);
                        btnToggleTimer.setChecked(false);
            }         
        }
    }

“我也尝试过使用PowerManager,但我认为问题不在那里” - 是的,你是对的。你已经安排让设备保持足够长时间的唤醒状态来创建CustomTimer实例并调用start()方法。然后设备可以回到睡眠状态。 - CommonsWare
嗨,CommonsWare,你建议我该怎么做?我的意思是计时器正在工作,但如果我离开活动,它不会停止5分钟,而是会停止5分钟20秒。 - Soyer
@Soyer 你好,我也遇到了类似的问题,请问你最后是怎么解决的?谢谢! - tj56
1个回答

2
你建议我做什么?
笨拙的方法是做你试图做的事情:始终保持CPU开启。在启动计时器之前,你需要acquire() WakeLock,并且只有在停止计时器时才release()它。然而,如果你在倒计时期间一直保持CPU开启,那会耗尽电池,用户可能会用尖锐的物品攻击你。忘记在某些情况下release() WakeLock可能会导致CPU保持开启状态,只要你的进程继续运行就会发生泄漏,这足以让用户使用更重的武器对付你。
因此,不要使用CountDownTimer。相反,使用AlarmManager(即使设备处于睡眠状态也可以控制倒计时结束时间),以及轻量级的东西(例如postDelayed()循环)来在前台更新UI。这样可以最大限度地减少电池消耗,同时在合适的时间给你控制权。

在alarmManager中使用setInexactRepeating()函数,它是否也能在Doze模式下工作? - kavie
@kavie:它将受到标准Doze限制的影响。因此,它可以工作,但当设备处于Doze模式时,闹钟会变得不那么频繁。 - CommonsWare
我需要在Android Wear应用程序中每10秒触发一次警报,持续2分钟。问题在于默认情况下警报自动增加到60秒。 - kavie
@kavie:那么你需要使用我回答中第一段的方法。 - CommonsWare

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接