less than 1 minute read Show
오늘도 열정적으로 개발하는 자팍이입니다. 오늘 배웠던 이 타이머는 어디서도 구하지 못해.. 직접 물어보고, 한참을 보다가 구현해낸 누군가에겐 별거 아니지만, 저에게는 값진 발견입니다.. 헤헤 금연 타이머 앱을 만들던 중.. 어떻게 하면, 입력한 시간과 날짜대로, 시간이 입력될까? 라는 생각이 들었습니다. 커뮤니티에 물어보니, 날짜나 시간을 계산하고, 그것을 초(밀리세컨드)로 변환하면, 그것이 가능하다고 했습니다. 하지만 처음에는 도저히 이해가 되지 않았습니다. 우선 예제를 보여드리겠습니다. 이 기능을 사용하시지 않더라도, 예제에 포함된 Calculate_Date.java안에 날짜 차이 구하기, 시간 차이 구하기, 현재 날짜와 시간 나타내는 메서드가 있으므로, 잘 활용하시길 바랍니다. 코드들MainActivity.java
보시는 거와 같이 복잡해 보일 수 있으나, 자세히 보면, 핸들러와 스레드 이외엔 별거 없습니다. 여기서 onCreate 부분에 버튼과 텍스트 뷰를 참조하고, Calculate_Date 객체를 인스턴스화 해줍니다. 그리고, 버튼을 리스너 해주고, 그 안에, 현재시간을 구하는 메서드와, 시간을 직접 입력하여, 그 시간 차를 구하는 메서드를 호출하여 파라미터에 넣어줍니다 (이 역시 Calculate_Date 안에 다 있습니다.) 그러고 나서 try문으로 예외 처리를 해준 다음, 스레드를 실행합니다! 그러면, 이제 쓰레드 쪽을 보겠습니다.
보시면, finallyTime을 전역 변수로 해두고,저 int i 변수에 int로 캐스팅하여 넣어두었습니다. 이렇게 하면, 시간이 몇 초 경과했는지, 핸들러에 전달할 수 있습니다. (예를 들어, 8000이란 숫자가 들어가면 8초부터 타이머가 시작됩니다.) int day = (int) finallyDate; 이 날짜 부분도 마찬가지입니다. 중요한 건 이 두 부분은 "초" 단위로 넣어야 하는 것인데, Calculate_Date 메서드에서 제가 다 포맷해놨으니, 궁금하면 살펴보시면 됩니다. 그리고 while반복문 처리를 해줍니다. arg1과 arg2에다가 i와 day가 1씩 증가하게 하여, (핸들러에 메시지 전달) 시간과 날짜를 구분 짓게 하기 위해 저런 식으로 arg를 나누어 두었습니다. 붙여서 쓰셔도 됩니다. 저렇게 전달되고, 혹시나 멈추는 상황을 대비해 0.01초마다 스레드를 실행하게 하는 Thread.sleep을 넣어주었습니다.
그리고 핸들러 부분을 보시면, 메시지를 전달받고 초, 시간, 분, 하루 단위로 저런 식으로 쓰여있습니다. msg.arg1이나 msg.arg2 같은 경우는 1초마다 1000밀리 세컨드이므로, 1000을 100으로 나누어 줌으로써 값은 1이 됩니다. % 는 산술 연산자로 다음에 나오는 숫자(같은 byte) 와 같아야 합니다. 그래서 int sec = (msg.arg1 / 100) % 60; 를 보시면, 60초까지 가면, 바로 00초로 바뀌는 걸 아실 수 있습니다. 나머지 분, 시간, 하루도 같다고 할 수 있습니다. int hour = (msg.arg1 / 100) / 3600 % 24; 이 시간 같은 경우도 3600분의 1이니까 한 시간을 의미하고, 마찬가지로 산술연산자 % 다음으로 나오는 24시간까지 시간으로 표시되고, 그다음부터는 00으로 바뀌는 것을 알 수 있습니다. 그리고 String result = String.format("%02d:%02d:%02d", hour, min, sec); 를 보시면, 앞에 인자에는 "&02d"라는 것을 3개 넣고, 뒤에 각각 자리에 들어갈 시간, 분, 초 인자를 넣어 포맷하는 메서드입니다. 이로 인해 result 값은 반복문으로 인하여 1초에 한 번씩 증가하여, 타이머가 구현되는 것입니다. 아래 oneDay도 마찬가지입니다. 여기서 잠깐 짚고 넘어가겠습니다. "&02d"가 무엇인가?입니다. % 는 명령을 시작한다는 의미이고, 0은 채워질 문자, 2는 총자릿수를 의미하고, d는 10진수 즉, 정수를 의미합니다. 타이머를 다룰 때 자주 사용되는 문자열 포맷팅을 위한 문법입니다. 그리고 xml문과 Caculate_date.java를 올려드리겠습니다.
쓰기 좋게 나누어 놓았으니, 필요에 맞게 쓰시면 됩니다. 중요한 건 calTimeBetweenAandB와 calDateBetweenAandB에서 calDate와 diff를 구하고, 다시 10으로 나누어 last를 붙인 long형태에 변수에 담아서 그대로 리턴을 하는 것입니다. 저도 사실 이유는 모르겠지만, 연산 후에는 0이 더 추가되어서 나와 가지고, 저렇게 만들었답니다. 이유를 아시는 분은 친절한 설명 부탁드립니다. 그리고 나머지 xml입니다.
이렇게 마무리를 하면 빼는 시간이 더 뒤에 있어서 -로 나오지만 이거는 순서를 바꾸거나, 날짜나 시간 값을 더 크게 하면 됩니다. 그냥 단순히 시간 차이를 구하고 싶으신 분들은 Math.abs메서드를 이용해 절댓값을 구하셔서 사용하시면 됩니다. 이상 초보 안드 개발자 자팍이였습니다. 감사합니다. 코드는 깃헙에 올려두었습니다. github.com/qjsqjsaos/Tistory3 qjsqjsaos/Tistory3 현재시간, 현재날짜, 시간 차이 구하기, 날짜 차이 구하기 입력 값을 받는 타이머 구현, 금연 앱 같은 스톱워치앱을 만들기 유용 - qjsqjsaos/Tistory3 github.com |