Android 6.0 마시멜로 리뷰

marojun
marojun’s Android
23 min readJul 19, 2015

안드로이드 마시멜로 이슈 분석

얼마전 Android 6.0 SDK 및 Developer Preview 3 가 발표되어 해당 내용으로 테스트 진행, 글 수정하였습니다.

결론부터 말씀드리면 마시멜로 릴리즈 전 거의 모든 앱들은 서비스 플로우 및 코드 수정이 필요하게 되었습니다. 제 경우는 그 범위가 어마어마 하네요.

이번에 진행할 Android 마시멜로 리뷰는 구글에서 발표한 내용과 이를 통해 발생할 예상 이슈를 살펴보고 어떤식으로 코드를 수정해야 할지에 대해 알아보도록 하겠습니다.

개발자 분들은 구글에서 발표한 마시멜로 관련문서들은 간략하게나마 읽어보셨을 것으로 판단됩니다.

여기서 집중적으로 살펴볼 것은 “새로운 앱 권한 모델" 과 “절전 최적화" 입니다. 구글 측 발표는 아무래도 새로운 기능을 발표할 때 긍정적인 부분을 중점적으로 이야기 할텐데 오늘 리뷰를 통해 긍정적인 측면과 부정적인 측면을 같이 제대로 이해하시는 시간이 되었으면 합니다.

새로운 앱 권한 모델 — 런타임 권한

테스트하실때 단말의 OS를 꼭 preview 3 으로 업데이트 하셔야 합니다. preview 2 의 경우 단말의 OS를 22로 리턴하여 마시멜로(23) 관련 테스트를 정상적으로 진행 하실 수 없습니다.

먼저 해당 모델에 대한 구글의 설명을 살펴 보겠습니다.

마시멜로 개발자 미리 보기에서는 새로운 앱 권한 모델을 소개하여 사용자가 앱을 설치하고 업그레이드하는 과정을 간소화할 수 있습니다. 미리 보기에서 실행되는 앱이 새 권한 모델을 지원하는 경우, 사용자가 앱을 설치하거나 업그레이드할 때 아무런 권한을 허용하지 않아도 됩니다. 그 대신, 앱이 필요할 때마다 권한을 요청하고 시스템이 사용자에게 해당 권한을 요청하는 대화창을 표시합니다.

언뜻보면 아 그렇구나 라고 넘어 갈 수 있는데 좀 더 생각해봅시다. “앱이 필요할 때마다 사용자에게 권한을 요청한다”라는 것을 무엇을 의미할까요? 안드로이드의 권한들은 protectionLevel 이라는, 중요도에 따라 분류되어지는 기준값을 가지고 있습니다. 이 중 특정 레벨(PROTECTION_DANGEROUS)로 선언되어있는 권한들의 경우 해당 사용자가 직접 허용을 해야 사용할 수 있다는 것을 의미합니다.

허용이 필요한 권한 그룹 및 권한 리스트

예를 들어 사진을 촬영하는 기능이 앱에 있을 경우 해당 권한(Manifest.permission.CAMERA)을 사용자가 수락해야 촬영할 수 있습니다. 그런데 여기서 문제는 해당 권한을 수락하지 않는 상태에서 사진을 촬영하는 기능을 실행하면 크래시가 발생하여 앱이 종료 될 수 있다는 것입니다.

구글 가이드에서는 권한이 없을 경우 기능이 요청되었을때 대한 상황을 다음과 같이 설명합니다. “앱이 해당 권한을 필요로 하는 작업을 수행하려 시도한다고 해도 그 작업이 반드시 예외를 발생시키는 것은 아닙니다. 그 대신에 빈 데이터 세트를 반환하거나 오류를 신호하거나, 기타 예기치 못한 동작을 선보일 수 있습니다.”

즉, 앱이 권한이 없어도 안정적으로 구동되도록 (크래시를 통한 종료가 되지 않도록) 처리해 준다는 보장이 없다는 것입니다. 실제로 몇몇 앱들에서는 권한 없음으로 인한 앱 종료 현상이 발생함을 확인하였습니다.

메서드 예외사항

* Intent 를 통해 수행할 수 있는 대체가능 기능들은 Intent 를 통해 수행될 경우 별도의 권한 허용이 없어도 사용 가능합니다. 예를 들어 사진을 촬영하거나, 주소록을 선택하거나 전화를 걸거나 메시지시를 쓰는 등과 같은 기능들이 대표적입니다.

구글은 이 부분의 해결을 위해 새로 발표한 권한 관련 메서드를 통해 권한 부족을 안정적으로 처리하라 가이드하고 있지만 이 말은 다시 생각해보면 앱 내 모든 권한을 사용하는 부분을 일일이 확인하고 분기 처리를 해야 된다는 말과 같습니다. 그리고 이전에 사용자 권한요청이 필요한 기능 호출시 먼저 해당 기능에 대한 권한을 사용자가 승락했는지에 대한 쿼리작업도 필요합니다. 이에 대한 플로우는 다음과 같습니다.

  1. 사용자가 앱내 사진 촬영하기 버튼 클릭
  2. 단말에 설치된 OS가 마시멜로 인지 판단
  • Build.VERSION.SDK_INT < 23 — 마시멜로는 API LEVEL 이 23이므로 위 조건이 false 일 경우 다음 단계로 넘어가도록 합니다.

3. checkSelfPermission 을 통해 사진을 촬영하는 권한이 PERMISSION_GRANTED (허용) 상태인지 판단

if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED)

4. 허용 상태가 아닌경우(false) 왜 해당 권한이 필요한지를 설명

if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.CAMERA)){
// 권한 필요 설명 UI 노출
}

5. requestPermissions 을 통해 권한 요청

ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA},
REQUEST_CAMERA);

6. 권한 허용 팝업노출

7. onRequestPermissionsResult 을 통해 사용자 허용여부 판단

8. 허용여부에 따른 코드 분기 처리

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
if (requestCode == REQUEST_CAMERA) {
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 허용
} else {
// 비허용
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}

그나마 위 분기처리는 2번 항목을 보시면 아시겠지만 마시멜로 기준으로 빌드된 앱들에 대해서만 적용됩니다. 즉, 마시멜로 이전 버전으로 빌드된 프로젝트는 마시멜로에서 안정적으로 처리가 불가능하다는 말입니다. 아래 CASE를 통해 좀 더 자세히 살펴보도록 하겠습니다.

CASE1. 현재 앱이 마시멜로 버전 이하로 빌드되어 있는경우

아직 컴파일 타겟을 마시멜로 설정해 마켓에 배포된 앱은 아직 없겠지요. 현재 기준으로 서비스하는 모든 앱을 통칭한다고 생각하시면 됩니다. 이 상태에서 디바이스의 OS 가 마시멜로로 업데이트 되었다고 가정해 봅니다.

이럴경우 기존에 OS에서 사용하고 있는 앱들은 권한을 모두 사용자가 승낙한 것으로 인지, 정상적으로 동작합니다. 그러나 마시멜로에서는 아래와 같이 앱 별로 해당 앱의 권한을 사용자가 수동으로 ON/OFF 할 수 있는 메뉴가 존재합니다. (시스템의 설정 화면으로 이동하여 앱 >app_name > 권한) 여기에서 사용자가 권한을 OFF 하면 해당 권한에 해당되는 기능을 사용자가 수행하면 권한이 없기에 앱이 종료 될 수 있습니다.

또한 사용자가 앱을 삭제하고 다시 설치한 경우에는 권한이 모두 OFF 된 상태로 실행되기 때문에 문제는 심각해집니다. — 해당 부분은 구글에서 전달받은 정책이나 preview3 에서 테스트한 결과 targetSdkVersion이 23보다 낮은경우 재설치 시 권한이 모두 ON 되어있으며 23인 경우 OFF 되었다. “targetSdkVersion 에 상관없이 마시멜로 버전의 단말에 새로 설치되는 모든앱은 default OFF 이다”라는 정책과 맞지 않기때문에 해당부분은 정식 이미지가 발표될때가지 모니터링 할 필요가 있다.

현재로서는 디바이스의 OS M 으로 업데이트 되기 전에 위에 설명한 분기처리를 모두 적용하여 M 타겟으로 배포하는 것이 최선의 방법입니다.

CASE2. 현재 앱이 마시멜로 버전으로 빌드되어 있는경우

마시멜로 버전을 타겟으로 앱을 생성한 경우 사용자가 앱을 실행하면 위에서 설명한 분기처리는 모두 적용했을 것입니다. 그러나 마시멜로 버전 기준 앱을 마켓에 배포하면 해당 앱은 마시멜로 버전의 디바이스에서만 사용하는 것이 아니기 때문에 해당 버전이 마시멜로 버전 이상인지를 확인하여 마시멜로 버전 이상일 경우에 대해서만 권한관련 분기처리하도록 코드를 관리해야 할 것 입니다.

Build.VERSION.SDK_INT >=23 // 마시멜로 버전 이상 확인

CASE3. 앱이 백그라운드에서만 동작하는 경우 (UI가 없는 경우)

현재 구글 문서상으로는 UI가 존재하는 앱에 대해서만 권한을 요청 할 수 있다고 가이드 되어 있습니다. 이에 해당 특성이 있는 앱들은 특정 레벨 이상의 권한을 요하는 기능을 사용할 수 없습니다.

런타임 권한에 대한 자체 FAQ

Q1. 권한 그룹에 관련 권한이 4개가 있다고 하자 그럼 관련 권한 1개에 대해 사용자가 승인을 하게 되면 해당 권한 그룹 전체가 승인되는 것인가 아니면 정확히 그룹 중 해당 권한만 승인되는 것인가?

- 테스트 결과 CONTACTS 그룹의 경우 READ_CONTACT 만 승인하였지만 이외의 WRITE_CONTACTS 관련 작업도 모두 수행 가능했다. 그러나 STORAGE 그룹의 경우는 WRITE_EXTERNAL_STORAGE는 제외하고 READ_EXTERNAL_STORAGE 만 승인했을 경우 파일을 생성하지 못했다. 즉, 그룹에 따라 관련 권한을 승인하면 해당 그룹에 대해 승인되는 것이 있고 안그러는 것이 있는것으로 보인다. 이에 부작용을 최소한하기 위해서라도 정확히 필요한 권한이 있다면 모두 요청하는것이 좋을 것으로 판단된다.

개별 권한이 아닌 그룹 권한으로 ex) Manifest.permission_group.CONTACTS 권한 요청할 경우에는 승인되지 않았다.

Q2. 이전버전의 프리뷰에서는 여러개의 다른 그룹의 권한을 요청할 경우 그중 하나의 권한만을 승인할 수 있었는데 지금은 어떤가?

- 다른 그룹의 경우 다음 이미지 처럼 순서대로 권한 요청을 할 수 있도록 제공한다. (거부 또는 허용을 선택하면 다음 권한으로 바뀐다.) 즉, 앱 구동시 메인화면에 진입시 사용자에게 해당 앱에서 사용하는 모든 권한에 대해 한번에 허용하도록 적용할 수 있다. — 그러나 구글가이드를 보면 모든 기능에 대해 앱 구동시 권한 요청을 하게 되면 사용자는 부담을 느끼게 되어 앱을 종료하는 결과를 초래할 수 있다라고 되어 있다. 즉, 정말 필수적인 권한들에서만 요청하고 이후 부가적인 기능에 대한 권한은 각각의 기능을 수행할 때 요청하도록 가이드 하고 있다.

Q3. 가이드를 보면 위에 보여지는 권한 팝업이 노출되기 전에 자체 서비스에서 별도의 권한 설명 뷰를 노출하고 이후 권한 팝업이 노출되어야 한다고 되어 있는데 꼭 만들어야 하는가?

- 코드상으로보면 권한 설명 뷰를 노출하는것에 대해 강제는 없다. 그러나 사용자에게 충분한 설명을 하지 않을 경우에 대한 부작용을 고려해야 한다. 예를들어 앱 구동시 위와 같은 권한관련 팝업이 노출된다고 하자 사용자는 이러한 권한이 정확이 어디에 쓰지는지 모르기 때문에 거부를 할 수 있다. 이후 해당 권한이 필요한 기능을 수행했거나 다시 앱을 구동했을때는 팝업에 다시 묻지 않기라는 체크박스가 생성되어서 노출된다. (동일한 권한에 대한 팝업이 2번째 노출되었을때 부터 활성화) 사용자는 다시 묻지 않기에 체크를 하고 거부를 누른다. 이 케이스가 발생하면 사용자는 OS 설정 - 해당 앱 관리에 진입하여 권한 메뉴에서 각각의 권한에 대해 직접 ON 하지 않는 이상 권한관련 기능을 영원히 사용할 수 없게 된다. 설명 뷰를 만들지 안만들지는 해당 상황을 인지하고 판단하도록 하자.

Q4. 정확히 shouldShowRequestPermissionRationale() 의 용도가 무엇인가?

해당 권한이 왜 필요로 한지 설명이 필요한 상태(설명 뷰가 노출되어야 하는 상태)인지를 명확하게 하기 위해서 만든 API 로 판단된다. 구글의 설명은 다음과 같다.

이 메서드는 사용자가 이전에 권한 요청을 거부한 경우에 ‘true’ 값을 반환합니다. 이 경우, 권한 요청을 위한 대화창에는 다음과 같이 ‘다시 묻지 않기’ 체크박스가 함께 표시됩니다.

사용자가 이를 선택하면, 이 후에 앱이 requestPermissions 메서드를 호출하더라도, 권한 요청 대화창이 표시되지 않으며, 바로 사용자가 해당 권한을 거부 할 때와 동일하게 콜백 함수가 호출 됩니다. 따라서, 이 메서드가 ‘true’ 값을 반환하면, 여러분의 앱이 해당 권한을 요구하는 이유와 왜 그 권한이 필요한지 사용자에게 조금 더 자세한 설명을 할 필요가 있습니다.

실제 테스트 진행결과는 아래와 같다.

  1. 단말의 OS가 마시멜로보다 낮은버전이라면 false

2. 해당 권한이 ON (승인이 되어있는 경우) 되어 있는 경우 false

3. 해당 권한에 대해 OFF (승인이 되어 있지 않는 경우) 되어 있는 경우 첫 호출시 false

4. 3번 케이스 이후 호출 ture (다시 묻지 않기를 체크하고 거부한적이 없음)

5. 해당 권한에 대해 다시 묻지 않기를 체크한 상태로 거부한경우 false

각각의 상황에 대한 리턴값을 참고하여 해당 메서드를 사용할지 안할지에 대한 여부를 판단하도록 하자. 예를 들어 사용자가 해당 권한이 필요한 기능을 첫 수행한 경우 (이전에 권한 거부하지 않은경우) 해당 메서드를 수행하면 false 가 반환된다. 이후부터는 해당 메서드를 호출하면 true 가 반환된다. 구글의 입장에서는 첫번째 권한요청에 대해서는 사용자에게 어떤 이유로 해당 권한을 사용해야 하는가에 대해 설명을 하는것보다 다시 해당 권한이 필요한 기능을 수행했을때 설명을 보여주는 것이 맞다고 판단하는 것 같다.

이러한 속성을 통해서 해당 권한에 대해 다시 묻지 않기를 체크한 상태를 판단할 수도 있을 것 같다. 첫번때 권한 요청시 OS 팝업의 거부 사항을 내부적으로 저장하고 있다가 해당 권한에 대해 승인이 되어 있지 않았지만 shouldShowRequestPermissionRationale() 리턴값이 false 인 경우 이전에 해당 권한에 대해 거부한 이력이 있는지를 판단. 거부한적이 있다면 다시 묻지 않기를 체크한 상태로 거부한 것임을 유추할 수 있다. 이를 통해 해당 앱의 메뉴(사용자가 권한을 ON 시킬수 있는 메뉴가 있는)로 이동할 수 있는, 사용자가 이전에 거부한상태로 판단하여 설정에서 해당 권한을 켜달라고 요청하는 UI를 노출시킬수도 있을 것이다.

참고로 해당 권한에 대해 다시 묻지 않기를 체크한 상태로 거부한 경우 사용자가 설정에서 해당 권한의 상태를 변경하면 다시 묻지 않기에 대해 체크한 상태를 reset 한다.

복잡하시죠. 구글도 런타임 권한 적용해 따른 혼란을 인지하고 이러한 상황에 대한 가이드를 제시하고 있습니다.

Educate before asking : 앱 실행시 튜토리얼 모드를 통해 왜 해당 권한을 사용하는지 정의

Ask up-front : 앱의 핵심기능이 권한이 필요한 경우 예를 들어 푸딩 카메라앱을 사용자가 구동했을 경우 사용자는 너무나 당연히 카메라를 사용하고자 앱을 실행했기 때문에 별도의 설명이 없이 카메라 권한 팝업을 노출한다.

Ask in context : 사용자들이 사용하고자 하는 기능에 대해 권한을 노출한다.

Educate in context : 사용자가 어떤기능을 사용하고자 원하거나 도움이 될 것 같다 판단이 되면 설명을 통해 이러한 권한을 승인하면 해당 기능을 사용하거나 도움을 받을 수 있다 설명한다.

Only ask for relevant permissions : 하나 이상의 권한을 요청할때는 서로 관련이 있는 권한들에 대해 요청하도록 한다.

절전 최적화 — Doze, 앱 대기 모드

구글에서는 사용자의 배터리 효율을 위해 DOZE 및 앱 대기 모드를 발표하였습니다. 배터리 효율을 중시하는 사용자 입장에서는 반길만한 일이지만 개발자 입장에서는 좀 곤혹스럽기도 합니다.

두 모드의 차이점은 단말의 절전 최적화를 위한 대상에 따라 구별되어 집니다. 즉, Doze 모드는 핸드폰 자체 그러니까 핸드폰에 설치되어 있는 모든 앱이 대상이 되고 앱 대기 모드는 각각의 앱이 대상이 된다고 보시면 됩니다.

그렇다면 Doze 와 앱 대기 모드가 각각 어떤 상황에서 진입하는지 구글의 가이드를 통해 알아보도록 하겠습니다.

DOZE 모드 : 기기의 플러그가 뽑히고 화면이 꺼진 채로 일정 시간 동안 변화 없는 상태로 유지되면, Doze 상태로 들어갑니다. 이 상태에서는 기기가 시스템을 절전 모드 상태로 유지하려 시도합니다. 이 모드에서 기기는 정기적으로 잠시 동안 정상 작동을 재개하여 앱 동기화가 일어날 수 있도록 하고 보류된 작업이 있으면 시스템이 이를 수행할 수 있도록 합니다.

해당 모드에 진입하게 되면 네트워크, 백그라운드 작업, 잡스케줄러, AlarmManager, WAKE LOCK, 동기화 어댑터, WiFi 스캔 등을 구현 및 구동 할 수 없게 됩니다. 물론 잠시 깨워 작업을 하는 몇가지 방법이 있지만(높은 우선순위의 GCM, setAlarmClock() 및 AlarmManager.setAndAllowWhileIdle() 을 통해 잠시 회피 가능.) 해당 방법을 통해도 정의된 작업이 다 실행될때 까지 기다려주는것이 아니라 내부적으로 정의된 몇 초 정도만 작업 가능하며 이때에도 정상적인 상태에서 할 수 있는 대부분의 기능이 동작하지는 않습니다. (모드에서 벗어나기 위한 꼼수 코드들을 다 무시합니다.) DOZE 모드는 해당 모드에서 벗어나게 되면 보류되어 있던 작업과 동기화를 모두 실행하고 유휴 앱에는 하루에 한 번 정도 네트워크 액세스가 허용한다고 가이드 되어 있기는 하지만 꼭 테스트가 필요한 부분으로 보입니다.

AlarmManager 는 해당 모드에서 벗어났을 경우 다시 수행됨을 확인하였습니다만 다양한 조건에서의 테스트를 진행한 후 공유하겠습니다.

앱 대기 모드 : 시스템이 보기에 앱이 활성 사용 중이 아닌 경우(앱이 포그라운드가 아닌경우) 해당 앱은 유휴 상태라고 판별할 수 있습니다. 구글의 가이드는 다음과 같습니다.

해당 상태에서 일정 시간 동안 아래 이벤트중 어느 한 가지도 발생하지 않을 경우 앱이 유휴 상태인 것으로 간주합니다.

디바이스가 충전 중이 아닌 경우, 유휴 상태인 것으로 간주된 앱은 네트워크 액세스를 할 수 없고, 동기화 작업이 일시 중단됩니다. 디바이스가 충전 중일 때는 네트워크 액세스가 허용되며 보류 중이었던 작업이 실행됩니다. 디바이스가 오랜 시간 동안 유휴 상태인 경우, 유휴 앱은 하루에 한 번 정도 네트워크 액세스가 허용됩니다.

만일 여러분의 앱이 사용자 상호작용 없이 백그라운드 상에서만 동작하는 경우, 유휴 상태 앱으로 지정될 수 있습니다.

즉, 앱의 노티가 띄워져 있거나 위젯이 설정되어 있다면 앱 대기 모드로 전환되지 않습니다. 즉, 앱 대기 모드가 되기 전에 해당앱의 노티가 활성화 되거나(도착하거나) 위젯을 설명하면 해당 모드로 진입하지 않습니다. 또한 아래 그림과 같이 설정의 배터리 최적화 메뉴에 해당 앱이 배터리 최적화를 사용하지 않겠다고 사용자 혹은 제조사가 설정해 놓으면 해당 모드로 진입하지 않습니다.

앱 대기 모드의 제약사항은 현재 테스트 중입니만 Doze 모드와는 달리 백그라운드 작업 및 AlaramManager 가 동작함을 확인하였습니다. — 네트워크 작업은 불가- 정확한 내용은 테스트 후 내용 반영하도록 하겠습니다.

그렇다면 각각의 모드는 언제 빠져나올까요?

Doze 모드의 경우 디바이스가 움직이면 해당 상태를 벗어나게 되며

앱 대기 모드의 경우는 해당 앱 구동시 벗어 나게 됩니다.

DOZE 모드 진입 Test

  1. 먼저 기기의 플러그가 뽑힌 상태로 만들기 위해 adb 명령어를 입력합니다.
$ adb shell dumpsys battery unplug

2. 이후 DOZE 모드에 진입하기 위한 명령어를 입력합니다.

$ adb shell dumpsys deviceidle step

위와 같이 입력했을 경우 저의 경우 아래와 같은 단계로 DOZE 모드에 진입 하였습니다.

SEULMAROJEONui-iMac:~ seulmarojeon$ adb shell dumpsys deviceidle stepStepped to: IDLE_PENDINGSEULMAROJEONui-iMac:~ seulmarojeon$ adb shell dumpsys deviceidle stepStepped to: SENSINGSEULMAROJEONui-iMac:~ seulmarojeon$ adb shell dumpsys deviceidle stepStepped to: IDLESEULMAROJEONui-iMac:~ seulmarojeon$ adb shell dumpsys deviceidle stepStepped to: IDLE_MAINTENANCE

여기서 보이는 IDLE 과 MAINTENANCE 단계가 DOZE 모드 입니다. 해당 명령어를 입력하여 순차적으로 해당 모드로 진입하도록 합니다. 좀 더 자세하게 설명드리자면 단말의 상태는 아래와 같이 변경되어 집니다.

ACTIVE (화면켜짐) -> INACTIVE (화면꺼짐) -> IDLE_PENDING -> SENSING -> IDLE <-> IDLE_MAINTENANCE

그렇다면 각각의 상태로 변경되는 시간은 어떻게 알 수 있을까요?

$ adb shell dumpsys deviceidle

위 명령어를 수행하면 아래와 같이 단계별 상태에 빠지는 시간이라 생각되어지는 단말의 정보를 볼 수 있습니다.

구글 가이드에 정확히 DOZE 모드로 진입하는 시간을 말하지 않는 이유는 해당 조건은 각 제조사에서 정의하기 때문입니다. 그렇기에 정확한 설명은 직접 제조사에 문의하거나 위 명령어를 통해 단말별 세팅값으로 유추하셔야 합니다.

Doze 모드가 해제 되는 조건인 단말 움직임을 테스트 하기 위해 DOZE 모드에서 단말을 흔들면 아래와 같이 해제됨을 확인할 수 있었습니다.

SEULMAROJEONui-iMac:~ seulmarojeon$ adb shell dumpsys deviceidle stepStepped to: IDLE_PENDING

앱 대기 모드 진입 Test

  1. 구글 가이드대로 기기의 플러그가 뽑힌 상태로 만들기 위해 adb 명령어를 입력합니다.
adb shell dumpsys battery unplug

2. 대상이 되는 앱을 앱 대기 모드로 전환합니다.

SEULMAROJEONui-iMac:~ seulmarojeon$ adb shell am set-inactive com.example.android.system.runtimepermissions true

3. 해당 앱이 앱 대기 모드가 되었는지 확인합니다.

SEULMAROJEONui-iMac:~ seulmarojeon$ adb shell am get-inactive com.example.android.system.runtimepermissions

4. 이에 대한 결과가 Idle=true 로 나온다면 모드로 진입한 것입니다.

혹시나 명령어를 제대로 입력했는데 Idle=false 가 나오시는 분들은 adb shell dumpsys battery unplug 명령어를 제대로 입력하셨는지 확인하시기 바랍니다. 해당 명령어를 입력하지 않고 앱 대기 모드 전환 명령어를 수행하면 Idle=false 가 반환됩니다.

앱 대기 모드의 경우 언제 진입하는지 구글에 문의한 결과 해당 진입 조건도 각 제조사에서 결정하나 구글의 경우 기본값을 몇 주 동안 사용하지 않은 앱 (실행하지 않거나 노티가 안왔거나 위젯설정이 안되어 있는 경우) 에 대해 적용하도록 되어 있습니다. 제조사에서 이 값을 변경할 수는 있지만 해당 값의 단위는 시간이 아니라 일(day) 단위로 변경하도록 되어 있음을 확인하였습니다.

혹시 Doze 모드에 진입하게 되면 각각의 앱들이 대기모드로 전환되는게 아닌가라고 궁금하신 분들이 계실까봐 공유드립니다. 아래와 같이 DOZE 모드에 진입시 제가 테스트한 앱에 대해 대기모드 여부를 체크해보았습니다. 결과는 둘은 별개로 동작함을 알 수 있습니다.

SEULMAROJEONui-iMac:~ seulmarojeon$ adb shell dumpsys deviceidle stepStepped to: IDLESEULMAROJEONui-iMac:~ seulmarojeon$ adb shell am get-inactive com.example.android.system.runtimepermissionsIdle=false

여기까지가 각각의 모드 진입 Test 에 대한 설명입니다. 다음 업데이트에서는 각각의 모드로 진입했을때 다양한 조건에서 테스트를 진행하여 어떤 기능이 수행되고 안되는지에 대해 추가 정리하도록 하겠습니다.

Android 6.0 SDK 및 fianl 개발 버전인 Developer Preview 3가 발표되었습니다. 단말의 6.0 업데이트가 얼마남지 않았다는것을 개발자 분들은 인지하시고 테스트를 통한 빠른 대응 및 기획 공유가 필요하겠습니다. 이후 업데이트 되는 상황에 대해 혼란드리지 않도록 계속적으로 업데이트 하도록 하겠습니다.

문의 사항은 트위터 @_marojun 로 멘션주시면 최대한 답변드리겠습니다. 감사합니다.

--

--

marojun
marojun’s Android

전슬마로. KTH, SK Planet, NCSOFT 에서 iOS와 Android를 개발하고 있다. — 안드로이드 개발 그룹 https://www.facebook.com/groups/junsle/