안드로이드 Q에서 백그라운드에서 액티비티를 실행하지 못하도록 제한합니다. Q 이전에는 백그라운드에서 액티비티를 실행할 수 있었습니다. 하지만 알지 못하는 액티비티가 갑자기 실행되거나, 광고 등의 악성 앱의 액티비티가 실행되는 문제들이 있었습니다.
구글은 Q에서 사용자와 상호작용하지 않는 앱이 백그라운드에서 액티비티를 실행하지 못하도록 제한하였습니다. 백그라운드에서 액티비티를 실행해야 하면 노티피케이션으로 사용자에게 알림을 주어 실행하도록 할 수 있습니다.
이런 제한사항은 앱의 SDK API와 무관하게 안드로이드 Q 디바이스에 실행되는 모든 앱에 적용됩니다. 따라서 자신의 앱이 백그라운드에서 액티비티를 실행시킨다면 새로운 정책에 맞게 수정이 되어야 합니다.
액티비티 실행 조건
사용자와 상호작용을 하는 앱은 백그라운드에서 액티비티를 실행할 수 있습니다. 앱이 사용자와 상호작용하고 있다고 인식되는 조건은 어떤 것들이 있는지 알아보겠습니다.
앱의 화면이 Foregrond에 있을 때
Foreground에 화면이 실행 중이라면 상호작용을 하고 있다고 생각합니다.
앱의 액티비티가 백스택에 남아있을 때
액티비티에서 finish() 등으로 종료한지 얼마 안되었거나, 최근에 실행한 액티비티가 백스택에 남아있는 경우 사용자와 상호작용을 했다고 인식합니다.
시스템이 앱의 서비스에 바인드 했을 때
이 조건은 다음과 같은 서비스에만 적용됩니다.
- AccessibilityService
- AutofillService
- CallRedirectionService
- HostApduService
- InCallService
- TileService
- VoiceInteractionService
- VrListenerService
PendingIntent를 받았을 때
앱이 시스템으로부터 PendingIntent를 받거나, Foreground에서 실행 중인 앱으로부터 PendingIntent를 받았다면, 몇초간은 백그라운드에서 액티비티를 실행할 수 있습니다.
시스템 브로드 캐스트를 받았을 때
예를 들어 ACTION_NEW_OUTGOING_CALL, SECRET_CODE_ACTION 처럼, 앱이 인텐트를 브로드캐스트로 받았을 때 UI를 실행할 것이라고 예상되는 인텐트들이 있습니다. 이런 인텐트들을 브로드캐스트로 받으면 몇초간은 백그라운드에서 액티비티를 실행할 수 있습니다.
CompanionDeviceManager API
CompanionDeviceManager를 통해 앱이 하드웨어와 페어링되었을 때, 특정 상황에서 백그라운드 액티비티를 실행시킬 수 있습니다.
SYSTEM_ALERT_WINDOW
사용자가 앱에 SYSTEM_ALERT_WINDOW 권한을 부여하면, 이 앱은 항상 백그라운드에서 액티비티를 실행할 수 있습니다.
Notification으로 액티비티 실행
알림이나 전화가 왔을 때 처럼 갑자기 다른 화면으로 전환해야 하는 경우가 있습니다. 백그라운드 서비스는 액티비티를 실행하지 못하기 때문에 노티피케이션을 만들어 사용자가 앱을 실행할 필요가 있다고 알려야 합니다.
아래 예제는 GoogleDeveloper에 소개된 예제입니다.
예제는 Full Screen Intent
를 사용하며, 불필요하다면 이 코드를 제거하면 됩니다.
val fullScreenIntent = Intent(this, CallActivity::class.java)
val fullScreenPendingIntent = PendingIntent.getActivity(this, 0,
fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT)
val notificationBuilder = NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("Incoming call")
.setContentText("(919) 555-1234")
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_CALL)
// Use a full-screen intent only for the highest-priority alerts where you
// have an associated activity that you would like to launch after the user
// interacts with the notification. Also, if your app targets Android Q, you
// need to request the USE_FULL_SCREEN_INTENT permission in order for the
// platform to invoke this notification.
.setFullScreenIntent(fullScreenPendingIntent, true)
val incomingCallNotification = notificationBuilder.build()
노티피케이션을 만들었다면 startForeground()
로 사용자에게 알림을 보여줄 수 있습니다.
// Provide a unique integer for the "notificationId" of each notification.
startForeground(notificationId, notification)
노티피케이션이 발생하고 사용자가 누르면 설정한 액티비티가 실행됩니다.
백그라운드 실행 허용
백그라운드에서 액티비티 실행 제한
이라는 기능으로 앱의 기능을 테스트하기 어려울 수 있습니다.
테스트를 위해, 다음과 같이 개발자모드 또는 abb 명령어로 이런 제한사항들을 비활성화 할 수 있습니다.
- [설정 > 개발자모드]에서 'Allow background activity starts' 옵션을 비활성화
- adb shell settings put global background_activity_starts_enabled 1
참고
Related Posts
- Android 14 - 사진/동영상 파일, 일부 접근 권한 소개
- Android - adb push, pull로 파일 복사, 다운로드
- Android 14 - 암시적 인텐트 변경사항 및 문제 해결
- Jetpack Compose - Row와 Column
- Android 13, AOSP 오픈소스 다운로드 및 빌드
- Android 13 - 세분화된 미디어 파일 권한
- Android 13에서 Notification 권한 요청, 알림 띄우기
- Android 13에서 'Access blocked: ComponentInfo' 에러 해결
- 에러 해결: android gradle plugin requires java 11 to run. you are currently using java 1.8.
- 안드로이드 - 코루틴과 Retrofit으로 비동기 통신 예제
- 안드로이드 - 코루틴으로 URL 이미지 불러오기
- Android - 진동, Vibrator, VibrationEffect 예제
- Some problems were found with the configuration of task 에러 수정
- Query method parameters should either be a type that can be converted into a database column or a List
- 우분투에서 Android 12 오픈소스 다운로드 및 빌드
- Android - ViewModel을 생성하는 방법
- Android - Transformations.map(), switchMap() 차이점
- Android - Transformations.distinctUntilChanged() 소개
- Android - TabLayout 구현 방법 (+ ViewPager2)
- Android - 휴대폰 전화번호 가져오는 방법
- Android 12 - Splash Screens 알아보기
- Android 12 - Incremental Install (Play as you Download) 소개
- Android - adb 명령어로 bugreport 로그 파일 추출
- Android - adb 명령어로 App 데이터 삭제
- Android - adb 명령어로 앱 비활성화, 활성화
- Android - adb 명령어로 특정 패키지의 PID 찾기
- Android - adb 명령어로 퍼미션 Grant 또는 Revoke
- Android - adb 명령어로 apk 설치, 삭제
- Android - adb 명령어로 특정 패키지의 프로세스 종료
- Android - adb 명령어로 screen capture 저장
- Android - adb 명령어로 System 앱 삭제, 설치
- Android - adb 명령어로 settings value 확인, 변경
- Android 12 - IntentFilter의 exported 명시적 선언
- Android - adb 명령어로 공장초기화(Factory reset)
- Android - adb logcat 명령어로 로그 출력