https://developer.android.com/training/monitoring-device-state/doze-standby.html#using_gcm



http://blog.hellworld.me/1



안녕하세요. 첫 글을 이런 별 가치 없는 걸로(?) 작성하게 되네요.


1. 서론

  일하는 곳에서 넥서스 5 던져주고는 DOZE 모드일 때 알림이 오게 하라고 해서 쇼 몇 번 해보고 글 씁니다.(나 안드로이드의 안 자도 모르는데... ㅠㅠ)


2. Doze 모드란?

  doze 모드란 안드로이드 6.0(=안드로이드 M, 마시멜로)에 새로 추가된 좀 빡센(?) 대기모드입니다. 배터리 소모량에 대해 걱정을 많이하던 구글은 위 방법으로 배터리를 관리하도록 하였고, 효율이 괜찮다고 하네요. 위 모드는 다음과 같은 경우에 들어가게 됩니다.

  1) 충전 중이 아님

  2) 스크린이 꺼져있음

  3) 1, 2 상태에서 오랜 시간(참고글에 의하면 제조사에서 지정한다고 합니다) 있을 것

그리고 1, 2, 3 조건을 만족하는 경우에 Doze 모드에 접어들었을 시 다음과 같은 상황이 벌어진다고 합니다.

  1) 네트워크 차단

  2) 백그라운드 작업 중지

  3) 기타 등등

저는 앞에서도 이야기했듯이 안드로이드의 안 자도 모르니 기술적인 글은 참고글을 참고하시기 바랍니다.


  - 참고글: http://thdev.net/632

  - 참고글: https://medium.com/marojuns-android/%EC%A2%80-%EB%8D%94-%EC%83%9D%EA%B0%81%ED%95%B4%EB%B3%B8-android-m-%EB%A6%AC%EB%B7%B0-13fbb98c9a87


3. 왜 문제가 되는가?

  알람 시계 앱 만드는 데 문제가 생기는 것도 있지만 저희 회사의 서비스는 백그라운드 상태에서 서버에 TCP로 연결된 채 푸시 알림을 받기 때문입니다. 네트워크가 차단되면 알림을 받을 수 없는데... 그러면 큰일나잖아요. 이 상황에서 순수하게 TCP 뻘짓만으로는 Doze모드에서 탈출할 수 없다고 합니다.


4. 어떻게 하면 Doze 모드에서 탈출할 수 있는가?

  1) 스크린을 킨다.

  2) 핸드폰을 흔든다.

  3) 충전기를 꼽는다.

  4) GCM을 받는다.

  5) 화이트 리스트에 등록한다.

위 방법들 중, 1, 2, 3은 핸드폰을 건드려야 하는 부분이고 5는 구글신 및 제조사에서 기록하는 부분이라 저는 손을 쓸 수 없습니다. 그래서 굵게 쓴 4) 방법으로 탈출하고자 합니다.


5. 실험 실시

  먼저 안드로이드를 강제로 Doze 모드로 바꿔줍니다.(시간은 소중하니까요) 참고글 보면 정확히 나와있으니 전 요약만 하겠습니다.

  1) adb를 설치한다. (제가 쓰는 Ubuntu에서는 sudo apt-get install android-tools-adb 요거 하면 됩니다)

  2) 그와 동시에 핸드폰은 개발자 모드로 맞춰놓습니다. 하는 법은 다른 곳에 많이 소개되어있습니다.(요약: 설정 -> 핸드폰 정보 에서 빌드번호 난타, 그 다음 설정 -> 개발자 옵션 -> USB 디버깅 허용 체크, 그 다음 폰에 기기 허용하겠냐고 뜨면 OK 누릅니다)

  3) adb devices 를 실행하여 기기가 잘 물려있나 확인합니다. offline 이 아니라 devices 라고 떠있으면 성공입니다.

  4) adb shell dumpsys battery unplug 을 실행하여 충전모드 아니라고 강제 지정을 합니다.

  5) 그 다음 스크린을 끕니다.

  6) 이후 adb shell dumpsys deviceidle step 이 명령을 통하여 상태를 강제로 전환합니다. 연타할 때마다 값이 바뀌는데 출력 값이 IDLE 이 되면 냅둡니다. 연타하면 상태가 풀린다고 옆에 계신 고수분께서 이야기해줬습니다.

  7) 이제 GCM을 보내봅시다. 이번에 GCM이 3.0으로 올라가면서 굉장히 많은 것이 바뀌었습니다. 구독-발행 개념 보내기, iOS 발송 지원 등이 추가되었지만 저는 priority 필드에 주목하였습니다. 자세한 내용은 참조글 링크하니 읽어보시기 바랍니다.(영어라니! 뷁!) curl을 이용하여 가볍게 쏴 봅시다.

참고글: https://developers.google.com/cloud-messaging/http-server-ref

curl --header "Authorization: key=너의 API Key" --header Content-Type:"application/json"  https://gcm-http.googleapis.com/gcm/send -d "{\"registration_ids\":[\"보내 볼 대상의 GCM 토큰\"], \"delay_while_idle\" : false, \"priority\" : \"high\"}"

매뉴얼에 의하면 high 는 iOS에서 7~10 정도라고 합니다.

저 명령을 쏴봅니다. 에러 안 떴으면 잘 나갔을 것입니다. 이 GCM 푸시를 받으면 Doze 모드가 해제됩니다.


6. 결론

  GCM 3.0으로 priority : high 맞추고 쏘면 Doze 모드가 풀린다.


7. 기타

  - GCM 2.0 과 3.0은 받는 위치가 바뀌었습니다. GCM 3.0의 받는 위치(endpoint)는 https://gcm-http.googleapis.com/gcm/send 입니다. 라이브러리가 구버전이거나 HTTP로 구현하였을 때, endpoint가 다르다면 업데이트를 하시기 바랍니다.

  - 참고로 node.js의 gcm 라이브러리 중 하나인 node-gcm 은 작성일 기준 15일 전에 업데이트가 되었습니다.(링크: https://github.com/ToothlessGear/node-gcm)

  - http://googledevkr.blogspot.kr/2015/10/gcmonandroid-doze.html 여기에 다 나와있는데... 헛짓했네요. ㅋㅋㅋㅋㅋㅋ자표시동일