2014-08-27 3 views
0

요구 사항 : 버튼을 1 초 이상 누르고있는 경우에만 itemLookup이 수행되어야합니다. 단추를 3 초 동안 누르고 있으면 조회에 사용 된 녹음에 불필요한 데이터가 포함되지 않도록 단추 이벤트를 중지하십시오.Android : 트리거링 MotionEvent.ACTION_CANCEL

  • 문제점 : 디버깅의 OnTouchListener 이벤트라고 예상대로 TableLayoutForIntercept, 'MainActivity가 이전의 onInterceptTouchEvent가 호출되는'것을 확인하더라도 MotionEvent.ACTION_CANCEL가 호출되지 않습니다. 아마도 onInterceptTouchEvent의 목적을 이해하지 못했을까요? 이 문제에 대한 다른 게시물을 살펴 보았지만 모두 스 와이프 또는 드래그 이벤트가 아닌 버튼을 취소하는 이벤트를 처리하고 있습니다. 아마 이것은 할 수 없습니까?
  • 코드 : 해당 MainActivity의 관련 부분과 전체 TableLayoutForIntercept 클래스가 표시되고 물론 <com.company.myapplication.TableLayoutForIntercept></com.company.myapplication.TableLayoutForIntercept> 태그가 내 xml 레이아웃을 둘러 쌉니다.

    public class MainActivity extends Activity { 
    
        //... 
    
        DateTime recordingStartedTime; 
        DateTime recordingEndedTime; 
        boolean buttonHeldLongEnough = false; 
    
        PackageManager pm = getPackageManager(); 
        boolean micPresent = pm.hasSystemFeature(PackageManager.FEATURE_MICROPHONE); 
    
        if (micPresent) { 
         recordBtn.setOnTouchListener(new View.OnTouchListener() { 
    
          @Override 
          public boolean onTouch(View recordView, MotionEvent recordEvent) { 
    
           switch (recordEvent.getAction()) { 
    
            case MotionEvent.ACTION_DOWN: 
             // Try to record audio 
             try { 
              recordingOff.setVisibility(View.INVISIBLE); 
              recordingOn.setVisibility(View.VISIBLE); 
    
              recordingStartedTime = DateTime.now(); 
              constructPrepareStartRecording(); 
             } 
             catch (Exception ex) { 
              Log.e(MainActivity.class.getSimpleName(), "An unknown error occurred."); 
             } 
             return true; 
    
            case MotionEvent.ACTION_UP: 
             recordingOff.setVisibility(View.VISIBLE); 
             recordingOn.setVisibility(View.INVISIBLE); 
    
             recordingEndedTime = DateTime.now(); 
             Seconds seconds = Seconds.secondsBetween(recordingStartedTime, recordingEndedTime); 
             int secondsButtonHeld = seconds.getSeconds(); 
    
             // Button must have been held at least 1 second before running itemLookup 
             if (secondsButtonHeld > 0) { 
              buttonHeldLongEnough = true; 
             } 
             else { 
              buttonHeldLongEnough = false; 
             } 
    
             // Need to release resources regardless 
             stopReleaseResetRecording(); 
    
             if (buttonHeldLongEnough) { 
              itemLookup(); 
             } 
             return true; 
    
            case MotionEvent.ACTION_CANCEL: 
             // I think this is the event I have to trigger to halt the button press 
             boolean codeHasHitCancel = true; 
             return codeHasHitCancel; 
    
           } 
           return false; 
          } 
         }); 
        } 
        else { 
         toastTitle = "Unable To Record"; 
         toastMessage = "Device microphone not found."; 
         toast = new GenericCustomToast(); 
         toast.show(toastTitle, toastMessage, MainActivity.this); 
        } 
    
        //... 
    } 
    
    public class TableLayoutForIntercept extends TableLayout { 
    
        public TableLayoutForIntercept (Context context) { 
         super(context); 
        } 
    
        public TableLayoutForIntercept (Context context, AttributeSet attrs) { 
         super(context, attrs); 
        } 
    
        private CancelPressTask cancelPressTask = null; 
        private boolean stopTouchEvent = false; 
    
        @Override 
        public boolean onInterceptTouchEvent (MotionEvent event) { 
    
         final int action = event.getAction(); 
    
         switch (action) { 
    
          case MotionEvent.ACTION_DOWN: 
           stopTouchEvent = false; 
           cancelPressTask = new CancelPressTask(); 
           break; 
    
          case MotionEvent.ACTION_CANCEL: 
          case MotionEvent.ACTION_UP: 
           cancelPressTask.resetCancelPressTimer(); 
           cancelPressTask.stopCancelPressTimer(); 
           return stopTouchEvent; 
         } 
    
         return super.onInterceptTouchEvent(event); 
        } 
    
        @Override 
        public boolean onTouchEvent (MotionEvent event) { 
    
         if (!stopTouchEvent) { 
         return super.onTouchEvent(event); 
         } 
    
         return true; 
        } 
    
        private class CancelPressTask { 
    
         public final long CANCEL_PRESS_TIMEOUT = 3000; // 3 seconds 
    
         private Handler cancelPressHandler = new Handler(){ 
          public void handleMessage(Message msg) { 
          } 
         }; 
    
         private Runnable cancelPressCallback = new Runnable() { 
          @Override 
          public void run() { 
           stopTouchEvent = true; 
          } 
         }; 
    
         public void resetCancelPressTimer(){ 
          cancelPressHandler.removeCallbacks(cancelPressCallback); 
          cancelPressHandler.postDelayed(cancelPressCallback, CANCEL_PRESS_TIMEOUT); 
         } 
    
         public void stopCancelPressTimer(){ 
          cancelPressHandler.removeCallbacks(cancelPressCallback); 
         } 
        } 
    } 
    

답변

0

나는 이것에 대해 이동하는 또 다른 방법을 알아 냈어. 대신 방아쇠 방아쇠를 당기려고, 나는 을 훔치고 대신를 훔칩니다! 아래의 코드는 녹음을 멈추고, 사용자가 얼마나 오랫동안 버튼을 누르고 있는지에 관계없이 3 초가 지난 후 항목 검색을 수행합니다. 단 하나의 캐치는 너무 짧은 (1 초 미만) 레코딩을위한 것으로, 토스트 메시지를 통해 사용자에게 알리기 위해 전체 3 초가 걸립니다. 그러나 나는 그걸로 기꺼이 살고 있습니다.

public class Main Activity extends Activity { 

     DateTime recordingStartedTime; 
     DateTime recordingEndedTime = null; 
     boolean buttonHeldLongEnough = false; 
     LimitRecordingTask limitRecordingTask; 

     PackageManager pm = getPackageManager(); 
     boolean micPresent = pm.hasSystemFeature(PackageManager.FEATURE_MICROPHONE); 

     if (micPresent) { 
      recordBtn.setOnTouchListener(new View.OnTouchListener() { 
       @Override 
       public boolean onTouch(View recordView, MotionEvent recordEvent) { 

        limitRecordingTask = new LimitRecordingTask(); 
        switch (recordEvent.getAction()) { 

         case MotionEvent.ACTION_DOWN: 
          // Try to record audio 
          try { 
           recordBtn.setBackgroundColor(Color.DKGRAY); 
           recordingOff.setVisibility(View.INVISIBLE); 
           recordingOn.setVisibility(View.VISIBLE); 

           recordingStartedTime = DateTime.now(); 
           constructPrepareStartRecording(); 
           limitRecordingTask.resetRecordingTimer(); 
          } 
          catch (Exception ex) { 
           Log.e(MainActivity.class.getSimpleName(), "An unknown error occurred."); 
           limitRecordingTask.stopRecordingTimer(); 
          } 
          return true; 

         case MotionEvent.ACTION_UP: 
          // After 3 seconds limitRecordingTask will 'steal' this event 
          recordBtn.setBackgroundResource(R.drawable.custom_button); 
          recordingOff.setVisibility(View.VISIBLE); 
          recordingOn.setVisibility(View.INVISIBLE); 

          recordingEndedTime = DateTime.now(); 
          Seconds seconds = Seconds.secondsBetween(recordingStartedTime, recordingEndedTime); 
          int secondsButtonHeld = Math.abs(seconds.getSeconds()); 

          if (secondsButtonHeld > 0) { 
           buttonHeldLongEnough = true; 
          } 
          else { 
           buttonHeldLongEnough = false; 
          } 
          return true; 
        } 
        return false; 
       } 
      }); 
     } 
     else { 
      toastTitle = "Unable To Record"; 
      toastMessage = "Device microphone not found."; 
      toast = new GenericCustomToast(); 
      toast.show(toastTitle, toastMessage, MainActivity.this); 
     } 

     private class LimitRecordingTask { 

      public final long RECORDING_TIMEOUT = 3000; // 3 seconds 

      private Handler limitRecordingHandler = new Handler(){ 
       public void handleMessage(Message msg) { 
       } 
      }; 

      private Runnable limitRecordingCallback = new Runnable() { 
       @Override 
       public void run() { 
        // 'Stolen' MotionEvent.ACTION_UP 
        recordBtn.setBackgroundResource(R.drawable.custom_button); 
        recordingOff.setVisibility(View.VISIBLE); 
        recordingOn.setVisibility(View.INVISIBLE); 

        if (recordingEndedTime == null) { 
         recordingEndedTime = DateTime.now(); 
        } 
        Seconds seconds = Seconds.secondsBetween(recordingStartedTime, recordingEndedTime); 
        int secondsButtonHeld = Math.abs(seconds.getSeconds()); 

        if (secondsButtonHeld > 0) { 
         buttonHeldLongEnough = true; 
        } 
        else { 
         buttonHeldLongEnough = false; 
        } 

        limitRecordingTask.stopRecordingTimer(); 

        stopReleaseResetRecording(); 
        itemLookup(); 
       } 
      }; 

      public void resetRecordingTimer(){ 
       limitRecordingHandler.removeCallbacks(limitRecordingCallback); 
       limitRecordingHandler.postDelayed(limitRecordingCallback, RECORDING_TIMEOUT); 
      } 

      public void stopRecordingTimer(){ 
       limitRecordingHandler.removeCallbacks(limitRecordingCallback); 
      } 
     } 
    }