Android 시스템에 핑을 보내다가 신기한 사실을 알아냈다

나는 집에서 라즈베리 파이를 이용해 음악을 틀어 두는데 내 핸드폰을 향해 주기적으로 핑을 보내다가 일정 시간동안 응답이 없으면 내가 집에 없는 것으로 판단하고 음악을 멈추게 해 놓았다. 그런데 핸드폰을 가만히 두면 배터리를 아끼기 위해(충전기에 꽂혀 있는데도) 시스템이 잠든 상태에 빠지고 핑에 대한 응답을 하지 않아 음악이 멈추는 일이 자주 발생했다.

그래서 Android 시스템이 화면이 꺼진 후 얼마나 시간이 지나야 잠드는지 확인하고 싶어서 Wi-Fi monitor를 통해 와이파이 신호를 살펴보고 있었는데 놀라운 사실을 발견했다. 핑에 대한 응답은 안 하지만 내 핸드폰의 맥 어드레스가 발신지인 와이파이 패킷이 잡히고 있었다.
혹시나 내가 핑을 보내는 패킷의 목적지 주소까지 스캔해서 그렇게 잘못 뜨는 건가 싶어 핸드폰의 와이파이를 꺼 봤는데 그 상태에서는 패킷이 잡히지 않았다. 핑에 대한 응답은 없는데 패킷은 발생하는 이 상황을 좀 더 살펴봐야겠다.

결론적으로 음악을 꺼 주는 스크립트는 주기적으로 핑을 보내는 부분은 그대로 두고 Wi-Fi monitor로부터 해당 맥어드레스가 발신지인 패킷이 최근에 있었는지를 확인하도록 바꿨다. 뭔가 하찮은 일에 과한 노력을 쏟은 거 아닌가 싶지만 애초에 이 프로젝트가 그러라고 만든 프로젝트니 상관 없겠지.

Android ART 때문에 부팅이 너무 오래 걸린다

ART(Android Runtime)이라는 게 생기면서 롬을 업데이트 하거나 한 후 부팅을 할 때 시스템에 설치 된 모든 앱에 대해서 최적화를 해야 한단다1. 문제는 이걸 스킵을 할 수도 없고 이게 돌아가는 동안은 부팅이 끝나지 않는데 10분 정도 걸린다. 모든 앱에 대해서 이걸 해야 할 이유도 모르겠고(부팅에 필요한 앱만 우선적으로 한 뒤 UI를 띄워주고 백그라운드에서 아직 사용하지 않은 앱들을 최적화 하면 안 되나?) 이걸 오래 걸리지 않게 하는 게 현재로선 유일한 해결책이라고 한다.
문제는 그 유일한 해결책이 설치한 앱을 최소한으로 남기고 다 지우라는 거다2 (아니면 업데이트 주기를 늦추든가).

Android Studio를 사용해서 빌드를 했을 때 플레이 스토어 버전이 지워지는 경우

Android 앱을 만들어서 플레이 스토어에 배포를 하다보면 생기는 문제인데 IDE에서 빌드를 해서 폰에 앱을 올릴 경우 원래 있던 플레이 스토어에서 설치한 앱을 지우고 다시 설치하도록 되어있다. signing이 맞지 않아서 그렇다.
어차피 문제가 생기는 부분은 지우고 설치할 때 데이터가 날아가는 부분 말고는 없을 줄 알고 나는 여태까지 Titanium Backup을 이용해서 데이터만 살려내는 방식을 사용했다. 하지만 문제는 이것 뿐이 아니었다.

플레이 스토어에서 설치한 앱은 크래시가 발생하면 기본적으로 개발자에게 리포트를 할 수 있는 기능이 있다. 이 정보는 개발자가 버그를 고치는 데 엄청난 도움을 준다. 나 또한 내가 만든 앱을 밖에서 사용하다가 크래시가 나면 일단 리포트를 해 두고 집에 가서 확인을 한다.
하지만 개발중인 버전을 폰에 설치하게 되면 앱이 죽을 때 아무런 일도 발생하지 않고 “Unfortunatly ~~ is crached” 비스무리한 메시지만 뜨게 된다.

어떻게 방법이 없나 하고 트윗을 올렸더니 한 분이 패키지 네임을 다르게 하면 된다고 알려주셨다.
(다만 패키지 이름 뒤에 -debug를 붙이는 건 형식에 어긋나서 사용하지 못하고 .debug를 사용했다.)
패키지 네임이 다르면 당연히 다른 패키지로 인식하고 그러면 지우지 않고도 두 개의 앱이 한 번에 설치될 수 있다. 이 것을 gradle을 이용하면 매번 패키지네임을 바꾸지 않고 릴리즈용과 디버그용 앱의 패키지네임을 자동으로 다르게 설정할 수 있다.
그래서 build.gradle 파일을 어떻게 수정하면 되나 하고 찾아봤는데 buildTypes 밑에서는 applicationId를 사용할 수 없고 applicationIdSuffix라는 속성을 사용할 수 있었다. 그렇게 해서 build.gradle 파일을 이렇게 수정하였다.

<생략>
android {
    compileSdkVersion 19
    buildToolsVersion '19.1.0'

    defaultConfig {
        applicationId "kai.twitter.voice"
        minSdkVersion 10
        targetSdkVersion 19
        versionCode 20
        versionName "1.4.0"
    }

    buildTypes {
        debug {
            applicationIdSuffix ".debug"
            versionNameSuffix "-debug"
        }
        release {

        }
    }

    packagingOptions {
        exclude 'META-INF/LICENSE.txt'
    }
}
<생략>

이제 개발을 하는 데 마음이 좀 편해졌다.
한 가지 문제점이 있다면 아이콘도, 이름도 똑같아서 앱 서랍에서는 구분을 할 수 없다는 정도 뿐이다.