简体   繁体   English

取消计时器后,如何重新启动计时器?

[英]How can I restart the timer, after it was cancelled?

I've got this service, which starts a timer, whenever said service also starts. 每当该服务也启动时,我就会启动该计时器。 The idea is that, if the user manually turns on the screen (ie the app. enters in the "counter" BroadcastReceiver), the timer gets cancelled. 这个想法是,如果用户手动打开屏幕(即应用程序输入“计数器” BroadcastReceiver),则计时器将被取消。 Otherwise, if the timer finishes by itself, the service will automatically stop (via onDestroy, of course). 否则,如果计时器本身完成,则服务将自动停止(当然,通过onDestroy)。

My problem comes when I want to restart the service, WITHOUT killing the app. 我的问题是当我想重新启动服务而不杀死应用程序时。 first. 第一。 If I simply input a new number of seconds and start the service, I get the following error: java.lang.IllegalStateException: Timer was canceled 如果仅输入新的秒数并启动服务,则会收到以下错误: java.lang.IllegalStateException: Timer was canceled

How can I get rid of said problem? 我如何摆脱上述问题?

MainService: 主要服务:

public class MainService extends Service {

static String BROADCAST_ACTION = "com.example.vladpintea.friendsbeforecents.displayevent";
Handler handler = new Handler();
Intent intentForStars;

String usedTimer;
long interval;

TimerTask myTask = new TimerTask() { public void run() { stopSelf(); } };
Timer myTimer = new Timer();

@Override
public void onCreate() {
    Toast.makeText(MainService.this, "Service, Created", Toast.LENGTH_SHORT).show();

    intentForStars = new Intent(BROADCAST_ACTION);

    registerReceiver(counter, new IntentFilter(Intent.ACTION_SCREEN_ON));
}

private BroadcastReceiver counter = new BroadcastReceiver() {
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    @Override
    public void onReceive(Context context, Intent intent) {
        myTimer.cancel();

        NotificationManager notify_manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        Intent intent_main_activity = new Intent(context, MainActivity.class);
        PendingIntent pending_intent_main_activity = PendingIntent.getActivity(context, 0,
                intent_main_activity, 0);
        Notification notification_popup = new Notification.Builder(context)
                .setContentTitle("Friends Before Cents")
                .setContentText("Oh, no! You've Lost. Try Again?")
                .setSmallIcon(R.mipmap.ic_sentiment_very_dissatisfied_white_48dp)
                .setContentIntent(pending_intent_main_activity)
                .setAutoCancel(true)
                .build();
        notify_manager.notify(0, notification_popup);

        Settings.System.putInt(getContentResolver(), Settings.System.SCREEN_OFF_TIMEOUT, 30000);
    }
};

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Toast.makeText(MainService.this, "Service, Started", Toast.LENGTH_SHORT).show();

    try { usedTimer = intent.getStringExtra("timer"); } catch (NullPointerException ignored) {}
    try { interval = Long.parseLong(usedTimer); } catch (NumberFormatException ignored) {}
    myTimer.schedule(myTask, interval * 1000);

    handler.removeCallbacks(sendUpdatesToUI);
    handler.postDelayed(sendUpdatesToUI, 1000);

    return super.onStartCommand(intent, flags, startId);
}

private Runnable sendUpdatesToUI = new Runnable() {
    public void run() { handler.postDelayed(this, 1000); }
};

public void addStars() { sendBroadcast(intentForStars); }

@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@Override
public void onDestroy() {
    unregisterReceiver(counter);

    PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
    PowerManager.WakeLock wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK
            | PowerManager.ACQUIRE_CAUSES_WAKEUP
            | PowerManager.ON_AFTER_RELEASE, "MyWakeLock");
    wakeLock.acquire();

    Settings.System.putInt(getContentResolver(), Settings.System.SCREEN_OFF_TIMEOUT, 30000);

    NotificationManager notify_manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    Intent intent_main_activity = new Intent(this.getApplicationContext(), MainActivity.class);
    PendingIntent pending_intent_main_activity = PendingIntent.getActivity(this, 0,
            intent_main_activity, 0);
    Notification notification_popup = new Notification.Builder(this)
            .setContentTitle("Friends Before Cents")
            .setContentText("Congrats! You've Won Some Coins.")
            .setSmallIcon(R.mipmap.ic_sentiment_very_satisfied_white_48dp)
            .setContentIntent(pending_intent_main_activity)
            .setAutoCancel(true)
            .build();
    notify_manager.notify(0, notification_popup);

    addStars();
}

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

You can not, the Doc reference states that once cancelled you need to create a new instance... 您不能,文档参考指出取消后就需要创建一个新实例...

the Doc : Doc

Note that calling this method from within the run method of a repeating timer task absolutely guarantees that the timer task will not run again. 请注意,从重复计时器任务的run方法中调用此方法绝对保证计时器任务不会再次运行。

So basically after cancel you need a new one... 所以基本上在取消之后,您需要一个新的 ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM