0

4 개의 RemoteView TextView가있는 사용자 정의 알림이 있습니다. onPause()가 호출되면 알림이 게시되고 화면이 켜져있는 동안 매 초마다 업데이트하려고합니다. onResume()이 호출되면 알림을 취소하고 싶습니다. 지금까지 나는 onPause()가 호출 될 때 true로 설정되고 onResume()이 호출 될 때 false로 설정되는 휘발성 부울을 갖도록 설정했습니다. HandlerThread를 시작한 다음 휘발성 부울을 검사하는 메서드가 있습니다. boolean가 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

가장 "안드로이드"방법 :

여기에 지금까지 내 코드입니다.

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

배경 (onPause)로 앱 이동하면 하나가 서비스를 시작하거나이를 알리는 말을하고, onResume과 반대에 메시지를 게시 할 수 있습니다.

이 (현재 솔루션에 문제가 당신의 활동이 중지시는하지만 여전히 원하는 것들의 OnDestroy/언제든지 죽을 수있다 알림 업데이트 예정에)


공지 사항 당신이 루퍼 MainThreads를 사용하여 HandlerThread을 만듭니다 :

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

하지만 다음 다른 문에 당신은 그만이 루퍼에게 :

timerNotificationHandler.getLooper().quit(); 

나는 이것이 어떤 행동을하는지 잘 모르겠습니다! 그러나 나는 그것이 잘못되었다는 느낌을 가지고 있습니다. 당신은 루핑에서 mainthreads 루퍼를 멈추고 싶지 않습니다, 그것은 당신의 활동이 예상대로 작동하지 않을 것이라는 것을 의미합니다. 당신의 else 문에서


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

당신은 또한 당신의 통지를 취소 할 수 있습니다

timerNotificationManager.cancel(1234); 
+0

https://developer.android.com/reference/android/app/NotificationManager.html#cancel(int)이 당신의 응답을 주셔서 대단히 감사합니다. 아직 서비스를 사용해 보려고하지 않았습니다. 나는 단지 약 2 개월 동안 프로그래밍을 해왔으며 이것은 나의 첫 번째 실제 프로젝트이다. 간단히 말해서 나는 멍청이다. Looper.quit()을 제거하고 NotificationManager.cancel (1234)으로 변경하고 try catch 블록의 주석 처리를 제거하면 알림이 취소되지만 1 초 후에 다시 표시됩니다. 어떤 아이디어가 그 원인일까요? 또한, 확실하게 ..... 나는 이것을 위해 handlerthread를 사용해야합니다. 맞습니까? 이것이 최상의 솔루션 인 것처럼 보입니다. 답변 해 주셔서 다시 한 번 감사드립니다. – IINEWMANII

+0

아마도'removeCallbacksAndMessages'를 호출했기 때문에 그럴 겁니다. 그러나'postDelayed'는 1 초 동안 게시하지 않으므로 이후에 메시지를 게시합니다. 당신은 여러 가지 방법으로 그것을 고칠 수 있습니다 : 1.1 초 후에 모두 취소하는 또 다른 실행 파일을 만들거나 취소 한 번 다시 자신을 게시하지 않기 위해 실행 파일에 플래그를 추가하십시오. – Blundell

+0

마침내 전화가 멈추지 않고 일하게되었습니다. 이제는 화면이 켜져있을 때만 알림이 업데이트되도록 계속 진행하고 있습니다. isScreenOn()이 더 이상 사용되지 않으므로 알아 내기가 어려울 정도로 17 이하의 API를 대상으로하고 있습니다. – IINEWMANII