마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

안드로이드 버튼을 ACTION_DOWN 하였을 경우, 강제로 1초동안 눌려있을 수 있나요?

0 추천

현재 버튼을 누른 상태(ACTION_DOWN)이면 눌렀을 때의 현재 시간을 가져옵니다. 그리고 버튼에서 손을 떼면(ACTION_UP), 이 때의 현재 시간도 가져와서 그 시간차 만큼 오디오의 파일을 잘라내고 붙이고 합니다. 만약 사용자가 너무 빠른 속도로 버튼을 누르고 떼고 하면 유효하지 못한 오디오 파일을 생성합니다. 그래서 1초 이상은 무조건 누르는 기능을 구현하고 싶은데요.

버튼 ACTION_DOWN, ACTION_UP 모션 이벤트에 그러한 기능을 구현할 수 있는 방법이 있나요? 아시는 분은 혜안을 부탁드립니다. 아래는 터치리스너 쪽의 소스 코드 입니다.

 

recordBtn.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                switch (motionEvent.getAction()) {
                    case MotionEvent.ACTION_DOWN: {
                        long currentDuration = vAudioPlayer.getCurrentDuration();
                        // 녹음 시작 ( combineList 사이즈가 짝수일 때 )
                        if (mRecordThread != null) {
                            if (combineList.size() % 2 == 0) {
                                mRecordThread.startFileWrite(currentDuration);
                                combineList.add(currentDuration);
                            }
                        }
                    }

                    // 버튼, 이미지 뷰 애니메이션
                    micBg1.setVisibility(View.VISIBLE);
                    micBg2.setVisibility(View.VISIBLE);

                    micBg1.startAnimation(animMic1);
                    micBg2.startAnimation(animMic2);

                    //userImg.setImageBitmap(userImgBitmap);
                    userImg.startAnimation(animZoomIn);
                    // artistImg.setImageBitmap(artistBlurImg);
                    artistImg.startAnimation(animZoomOut);

                    break;
                    case MotionEvent.ACTION_UP: {
                        long currentDuration = vAudioPlayer.getCurrentDuration();
                        if (mRecordThread != null) {
                            // 병합을 시작 ( combineList가 홀수일 때: 레코드 버튼을 눌렀을 때 combineList의 사이즈가 홀수가 된다 )
                            if (combineList.size() % 2 == 1) {
                                mRecordThread.stopFileWrite();

                                File waveFile = new File(RecordActivity.currentCreateFileName.replaceAll("/ucc/", "/tmp/")
                                        + "_" + calTime(combineList.get(combineList.size() - 1), false) + "_uv.pcm");

                                // 위의 경로에 해당 녹음 파일이 존재하면 wav 파일로 변환,
                                if (waveFile.exists()) {

                                    copyWaveFile(RecordActivity.currentCreateFileName.replaceAll("/ucc/", "/tmp/") + "_" + calTime(combineList.get(combineList.size() - 1), false) + "_uv.pcm",
                                            RecordActivity.currentCreateFileName.replaceAll("/ucc/", "/tmp/") + "_" + calTime(combineList.get(combineList.size() - 1), false) + "_u0.wav");

                                    // wav 볼륨 파일 증폭
                                    if (mMp3ConcatThread != null) {
                                        mMp3ConcatThread.startCombine(null, 3333333333333333333L, combineList.get(combineList.size() - 1), currentDuration);
                                    }
                                }

                                combineList.add(currentDuration);
                                // startCombine Thread 분기 처리( if old_position: 0, 3333333333333333333L, 7777777777777777777L, 그 외 )
                                if (combineList.size() == 2) {
                                    // 0: 처음 한번 녹음할 때
                                    mMp3ConcatThread.startCombine(null, 0, combineList.get(combineList.size() - 2), currentDuration);
                                } else {
                                    // 그 외: 두번 이상 녹음할 때
                                    mMp3ConcatThread.startCombine(null, combineList.get(combineList.size() - 3), combineList.get(combineList.size() - 2), currentDuration);
                                }
                            }
                        }
                    }

                    // 버튼, 이미지 뷰 애니메이션
                    micBg1.setVisibility(View.GONE);
                    micBg2.setVisibility(View.GONE);

                    micBg1.clearAnimation();
                    micBg2.clearAnimation();

                    // userImg.setImageBitmap(userBlurImg);
                    userImg.startAnimation(animZoomOut);
                    // artistImg.setImageBitmap(artistImgBitmap);
                    artistImg.startAnimation(animZoomIn);
                    break;
                }
                return false;
            }
        });

 

준버기 (1,160 포인트) 님이 2018년 7월 27일 질문

1개의 답변

0 추천
그렇게 처리하려면 타이머를 써야 할 것 같네요.

사용자가 버튼을 누르면(ACTION_DOWN) 타이머가 시작된다. IsTimerOn = true. (private 전역 변수로 선언)
ACTION_UP의 경우 IsTimerOn = false;

방법1: 타이머는 100ms(이값은 로직에따라서 변경 가능) 마다 상태 체크를 하지만 1000ms가 되기 전까지는 IsTimerOn을 체크하지 않는다.
방법2: 타이머의 첫 딜레이를 1000ms로 세팅하면 첫 1초 동안은 체크안하겠죠.

이렇게 로직을 구성하면 됩니다.

타이머 샘플:

 final Handler handler2 = new Handler();
        handler2.postDelayed(new Runnable() {
            @Override
            public void run() {
                handler2.postDelayed(this, 100); // 두번째 이후 딜레이 100ms
                // 여기서 조건을 검색해서 수행하면 됨.
            }
       }, 100); // 첫 딜레이 100ms --> 이걸 1000으로 주면 첫 1초동안 체크 안함.
Will Kim (43,170 포인트) 님이 2018년 7월 27일 답변
답변 감사합니다. 핸들러를 어디서 생성하고 어떻게 돌려야 하나요? 아, 그리고 무조건 1초뒤에 실행이 아니고 1초 이상이어야 한다입니다. ㅠㅠ
...