2016-08-19 162 views
0

我有這個服務,它啓動一個計時器,每當上述服務啓動時。這個想法是,如果用戶手動打開屏幕(即應用程序進入「計數器」BroadcastReceiver),定時器將被取消。否則,如果定時器自行完成,服務將自動停止(當然,通過onDestroy)。如何在計時器取消後重新啓動計時器?

我的問題是當我想重新啓動服務,沒有殺死應用程序。第一。如果我只輸入一個新的秒數並啓動服務,我會收到以下錯誤:java.lang.IllegalStateException: Timer was canceled

如何擺脫上述問題?

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

回答

0

你不能,一旦取消了文件引用狀態,你需要創建一個新的實例...

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.

所以基本上取消後你需要一個新的一...