0

我有一個自定義通知有四個RemoteView TextViews。當onPause()被調用時,我想發佈通知,然後在屏幕開啓時每秒更新一次。當onResume()被調用時,我想取消通知。到目前爲止,我已經設置好了,以便我有一個volatile變量布爾值,當onPause()被調用時設置爲true,並且在調用onResume()時設置爲false。我有一個方法啓動一個HandlerThread,然後檢查volatile布爾值。如果布爾值爲true,則應更新通知,如果該值爲false,則應取消通知並關閉HandlerThread。如何停止通知多數民衆贊成在處理程序線程

一切似乎都工作正常,只要開始通知並更新它每秒。但是,當調用onResume()時,它不會停止通知。

我沒有屏幕上的東西編碼,因爲我想弄清楚如何關閉通知和HandlerThread,然後再轉到那個。

這是到目前爲止我的代碼:

void setUpTimerNotif() { 

    handlerThread = new HandlerThread("TimerNotificationHandler", Process.THREAD_PRIORITY_BACKGROUND); 

    handlerThread.start(); 

    timerNotificationHandler = new Handler(handlerThread.getLooper()); 

    timerNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 

    Intent timerNotifIntent = new Intent(MainActivity.this, MainActivity.class); 
    timerNotifIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); 

    final PendingIntent pendingTimerNotifIntent = PendingIntent.getActivity(MainActivity.this, 
      1234, timerNotifIntent, PendingIntent.FLAG_UPDATE_CURRENT); 

    final RemoteViews remoteTimerViews = new RemoteViews(getPackageName(), R.layout.timer_notification); 

    final NotificationCompat.Builder timerNotificationBuilder = new NotificationCompat.Builder(MainActivity.this); 

    if (timerNotificationRunning) { 
     timerNotificationHandler.postDelayed(
       new Runnable() { 
        @Override 
        public void run() { 

         long timerNotifTimeOne = wakeUpTime - System.currentTimeMillis(); 
         long timerNotifTimeTwo = wakeUpTimeTwo - System.currentTimeMillis(); 
         long timerNotifTimeThree = wakeUpTimeThree - System.currentTimeMillis(); 
         long timerNotifTimeFour = wakeUpTimeFour - System.currentTimeMillis(); 

         String timeOne = timerFormat(timerNotifTimeOne); 
         String timeTwo = timerFormat(timerNotifTimeTwo); 
         String timeThree = timerFormat(timerNotifTimeThree); 
         String timeFour = timerFormat(timerNotifTimeFour); 

         String hmsOne = ("Timer 1: " + timeOne); 
         String hmsTwo = ("Timer 2: " + timeTwo); 
         String hmsThree = ("Timer 3: " + timeThree); 
         String hmsfour = ("Timer 4: " + timeFour); 

         remoteTimerViews.setTextViewText(R.id.timer_one_notification_view, hmsOne); 

         remoteTimerViews.setTextViewText(R.id.timer_two_notification_view, hmsTwo); 

         remoteTimerViews.setTextViewText(R.id.timer_three_notification_view, hmsThree); 

         remoteTimerViews.setTextViewText(R.id.timer_four_notification_view, hmsfour); 

         timerNotificationBuilder.setPriority(Notification.PRIORITY_HIGH) 
           .setAutoCancel(false) 
           .setOngoing(true) 
           .setOnlyAlertOnce(true) 
           .setSmallIcon(R.mipmap.ic_launcher) 
           .setContentIntent(pendingTimerNotifIntent) 
           .setCustomBigContentView(remoteTimerViews) 
           .setVisibility(NotificationCompat.VISIBILITY_PUBLIC); 

         timerNotificationManager.notify(1234, timerNotificationBuilder.build()); 

         timerNotificationHandler.post(this); 

        } 
       }, 1000 
     ); 
    } else { 
     timerNotificationManager.cancelAll(); 

     if (timerNotificationHandler != null) { 
      timerNotificationHandler.removeCallbacksAndMessages(null); 
     } 

     timerNotificationHandler.getLooper().quit(); 

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { 
      handlerThread.quitSafely(); 
     } else { 
      handlerThread.quit(); 

      /*try { 
       handlerThread.join(); 
       handlerThread = null; 
       timerNotificationHandler = null; 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      }*/ 
     } 

     Log.v(TAG, "Timer Notification Cancelled"); 
    } 

} 

回答

1

最「Android」的方式做,這是使用一個後臺服務。

https://developer.android.com/guide/components/services.html

當你的應用程序移動到背景中(的onPause)你要麼啓動該服務或發佈消息的說法,指出這一點,並在的onResume相反。

(與當前解決方案的問題是你的活動可以在任何時候被殺死的onStop /的onDestroy但你還是想要去通知更新)


通知您使用MainThreads的Looper創建HandlerThread:

timerNotificationHandler = new Handler(handlerThread.getLooper()); 

但隨後在else語句你告訴這個彎針退出:

timerNotificationHandler.getLooper().quit(); 

我不太確定這給了什麼行爲!但是我有一種感覺,那就是錯誤 - 你不想阻止主線程循環,這意味着你的活動不能按預期工作(可能是你的問題)。

https://developer.android.com/reference/android/os/Looper.html#quit()


在你else語句也可能要取消您的通知:

https://developer.android.com/reference/android/app/NotificationManager.html#cancel(int)

timerNotificationManager.cancel(1234); 
+0

非常感謝您的回覆。我還沒有嘗試過使用服務來做到這一點。我只編程了大約兩個月,這是我第一個真正的項目。總之我是一個noob。如果我刪除Looper.quit()並更改爲NotificationManager.cancel(1234),並取消註釋try catch塊,它將取消通知,但之後它會返回一秒。任何想法可能會導致什麼?另外,只是要確定.....我應該使用handlerthread,對吧?這似乎是最好的解決方案。再次感謝您的回覆。 – IINEWMANII

+0

這可能是因爲你調用'removeCallbacksAndMessages',但是'postDelayed'不會發布1秒,所以之後會發布消息。你可以通過多種方式修復它:創建另一個可在1.1秒後全部取消的runnable,或者向runnable添加一個標記,以便在取消後不會再發布自己的文件 – Blundell

+0

我終於在沒有導致電話凍結的情況下工作。現在我正在開始製作,因此通知只會在屏幕打開時更新。我試圖將目標API定位爲17,所以它似乎很難弄清楚,因爲isScreenOn()已被棄用。 – IINEWMANII

相關問題