이 블로그는 더 이상 업데이트되지 않습니다.

최신 내용을 확인하시려면 여기를 클릭해주세요.

Android (12)


Sudoku Solver

Sudoku Solver는 스도쿠 게임의 해법을 찾아주는 어플리케이션입니다.
어려운 스도쿠 게임에서 한계에 봉착했을 때, 여러분들께 활로를 제공해 드립니다.
친구, 직장 동료와의 내기에서 승리하십시오!
– Google Play Store의 Sudoku Solver 설명문

위에서 말한것과 같이, Sudoku Solver는 스도쿠(스도쿠가 뭔지 모르신다면 여기 참조)의 해답을 찾아주는 어플리케이션입니다.

어느 날인가, 갑자기 페이스북에 스도쿠를 풀어주는 프로그램들을 만들어서 올리는걸 보고 ‘아, 나도 하나 만들어볼까?’ 해서 만들어진 어플리케이션입니다. 페이스북에 갑자기 스도쿠 프로그램들이 올라온 까닭이 KAIST 학생들의 Assignment 이었기 때문이라 들었지만 Command Line Interface로 만들면 스도쿠를 입력하기 힘들었기 때문에 GUI로 제작하리라 마음을 먹었습니다.

요새 계속 사용해서 손에 익은것이 JAVA였고, 그중에서도 Android Application을 계속 만들고 있었기 때문에 Android Application이 된 것 뿐이지 사실 큰 이유는 없었습니다. 애초에 스도쿠를 풀어주는 Object는 따로 구현이 되어있어서 터미널에서도 충분히 사용할 수 있습니다.(다만, 스도쿠를 입력받는 부분과 해결한 스도쿠를 출력하는 부분을 따로 만들어줘야 하겠지요.)

풀이를 완료한 후에 실행 시간을 보여주는건 단순히 필요했다기 보단 공간이 남길래(…) 넣었습니다. 만약 시간이 난다면 OCR 기능을 추가해서 카메라로 비추면 자동으로 스도쿠를 풀어주는 기능도 추가를 하고싶습니다.

다운로드는 아래 버튼으로 할 수 있습니다.

Get it on Google Play




ProgressMultiPartEntity를 이용한 File upload progress 구현

안드로이드에서 서버로 파일을 업로드해야 할 때가 있다.
이때, MultipartEntity라는 것을 이용하여 FileBody를 추가하여 업로드 할 수 있다.

이를 이용하면 쉽게 파일을 업로드 할 수 있다.
그렇다면, 파일 업로드의 progress를 확인하려면 어떻게 해야 할까?

구글링을 해 본 결과, 여기에서 해답을 찾을 수 있었다.
따로 ProgressMultiPartEntity와 ProgressListener를 정의하여 사용하면 된다.




코드에서 생성한 View에 Id 생성하기

안드로이드에서 ListView를 사용하면서 ViewHolder 패턴이란 것을 많이 사용해 봤을 것이다.
(아니라면 [Android] ListView 구현시에 뷰홀더(ViewHolder) 사용하기 를 보자.)

viewHolder 패턴을 사용하면서 하나의 ListView에 서로 다른 구조를 가진 View들을 보여주게 되면, convertView.getId() 메서드를 이용하여 View의 교체 여부를 결정하게 된다.

위와 같은 코드를 사용하면서, 차츰 View.getId() 메서드를 이용해 View를 비교하는 방법을 즐겨 사용하게 되었는데, 그러던 와중에 문제점이 하나 발생했다.

만약 Id를 가져오고자 하는 View가 코드상에서 생성된 View라면, Id가 없다…
따라서 Id를 따로 생성해 주어야 한다.

API Level 17 부터는 View.generateViewId() 메서드를 사용하면 되겠지만, 보통 진저브레드까지 지원하도록 앱을 만드는 나는 사용할 수 없었다.

그럴 때 사용할 수 있는 메서드가 있다.
역시 내가 구현한 코드는 아니지만, 유용해보여 소개한다.

* 참고
http://stackoverflow.com/questions/1714297/android-view-setidint-id-programmatically-how-to-avoid-id-conflicts




ViewPager에서 현재 보고있는 Fragment 알아내기

안드로이드에서 ViewPager를 사용할 때, 현재 보고있는 Fragment를 알아내는 것은 여간 골치아픈 일이 아니다.

Fragment 내에서 OnResume()가 호출되는 순간으로는 올바르게 알아 낼 수 없다.
onPageChangeListener 등을 쓰는 방법도 있겠지만, 아주 간단하게 구현할 수 있는 방법이 있다.

바로 setUserVisibleHint 메소드를 오버라이드 하는 방법이다.
Android Support Library (rev 11) 에서도 사용이 가능하다.

적용하고자 하는 Fragment에서 다음과 같이 사용하자.

* 참고
http://stackoverflow.com/questions/10024739/how-to-determine-when-fragment-becomes-visible-in-viewpager




비트플래그 (Bitflag)

한번에 여러 가지 속성을 동시에 지정할 때, 편리하게 사용 할 수 있는 방법 중에 하나가 비트플래그이다.
간단하게 안드로이드에서 비트플래그를 사용하는 법을 알아보자.
(사실, 자바랑 똑같다)

우선 사용하는 연산자는 다음과 같다.

~A : NOT 연산자 – A의 각 비트가 0이면 1로, 1이면 0으로 바뀐다.
A & B : AND비트 연산자 – 두 비트가 모두 1일 때 1이다.
A | B : OR비트 연산자  – 두 비트가 모두 0일 때 0이다.
A ^ B : XOR비트 연산자  – 두 비트가 모두 달라야 1이다.

아래는 간단한 예제.

http://pastebin.com/9HspchLS




Type Replace “…” with ellipsis character (…, … ?

ADT에서 Type Replace “…” with ellipsis character (…, …) ? 라는 경고가 뜬다.

ctrl + 1을 이용한 빠른 수정으로 수정이 안되는걸 보니 버그인듯.

쉽게 말하면 …을 말줄임표 유니코드로 바꾸라는 말씀.
아래처럼 바꾸면 된다.




3D Filp Animation

간단하게 안드로이드에서 사용할 수 있는 3D Filp Animation 입니다.
제가 작성한 코드는 아니고, 유용해 보여서 소개합니다.

세로축을 중심으로 플립하는 animation인데,
중간에 camera.rotateY(degrees); 를 camera.rotateX(degrees); 로 바꿔주면 가로축을 중심으로 회전합니다.
http://pastebin.com/dP7aVmM9




setLayoutParams와 java.lang.ClassCastException

안드로이드에서 setLayoutParams 메서드를 사용했더니 java.lang.ClassCastException이 발생한다면, LayoutParams를 잘못 사용했을 확률이 높다.

어떤 View에 LayoutParams를 적용할 때에는 View의 부모 레이아웃 클래스의 LayoutParams를 적용해야 한다.

예를들어 RelativeLayout a내부에 있는 LinearLayout b에 LayoutParams를 적용한다면,

이런식으로 말이다.

마찬가지로, ListView 내부의 자식 View에서는 AbsListView.LayoutParams를 사용한다.




SHA-1, HMAC 해쉬 함수

안드로이드에서 SHA-1과 HMAC hash를 위한 class를 만들어 봤습니다.
역시 구글신은 위대합니다…

http://pastebin.com/r8qnVDUb




AES 암호화 / 복호화 ( ~ Android jelly bean 4.2)

안드로이드 내부에 여러 데이터를 저장하다 보면, 사용자가 쉽게 열어보지 못하도록 암호화해야 하는 상황이 생긴다. 그때 사용 할 수 있는 방법을 찾다가, AES 암호화를 사용하면 좋겠다는 생각이 들었다. 그래서 간단하게 class를 만들어 사용하던 도중, 안드로이드 4.2 젤리빈에서는 정상동작하지 못하고 뻗어버리는 상황에 봉착했다. 이를 해결하기 위해 이곳저곳 돌아다녀 완성한 class를 소개한다. class를 사용하기 전에 key를 우선 바꾸어주자. 실제로 사용하는 메소드는 제일 처음의 encrypt와 decrypt 뿐이다.

http://pastebin.com/6CLVTu9x

이 소스코드의 대부분은 제가 작성한 코드가 아닌, 구글링의 결과물이며, 이를 사용해서 발생한 어떠한 일에도 저는 책임을 질 수 없습니다.