Android 12 개발자 프리뷰에 오신 것을 환영합니다. 초기에 자주 의견을 제공하여 Android 12를 최고의 버전으로 만들도록 도와주세요.

동작 변경사항: Android 12를 타겟팅하는 앱

이전 버전과 마찬가지로 Android 12에는 앱에 영향을 미칠 수 있는 동작 변경사항이 포함되어 있습니다. 다음 동작 변경사항은 Android 12 이상을 타겟팅하는 앱에만 적용됩니다. 앱이 Android 12를 타겟팅하는 경우 이러한 동작을 올바르게 지원하도록 앱을 수정해야 합니다(적용되는 경우).

다음 표에는 앱이 Android 12를 타겟팅하는 경우 앱에 영향을 미치는 주요 변경사항이 요약되어 있습니다. 이 표는 변경사항을 모두 제공하지는 않습니다.

주요 변경사항 영향을 받는 앱
포그라운드 서비스 시작 제한
일부 예외를 제외하고, 앱은 백그라운드에서 실행되는 동안 포그라운드 서비스를 더 이상 시작할 수 없습니다. 포그라운드 서비스를 시작하려고 하면 예외가 발생합니다.
백그라운드에서 실행되는 동안 포그라운드 서비스를 시작하는 앱
인텐트 필터가 포함된 앱 구성요소는 내보낸 속성을 선언해야 함
인텐트 필터가 포함된 앱 구성요소는 android:exported 속성을 명시적으로 설정해야 합니다. 이 속성을 설정하지 않은 앱은 Android 12에 설치할 수 없습니다.
매니페스트 파일에서 <intent-filter> 속성을 선언하는 앱
안전하지 않은 중첩된 인텐트 실행
이제 엄격한 모드 테스트에서 앱이 안전하지 않은 방식으로 중첩된 인텐트를 사용할 때를 감지합니다.
다른 앱을 실행하여 내부 인텐트를 통한 콜백을 예상하는 앱

Android 12에서 실행되는 모든 앱에 영향을 주는 동작 변경사항의 목록도 검토하시기 바랍니다.

개인정보 보호

WebView의 최신 SameSite 쿠키 동작

Android의 WebView 구성요소는 Google의 Chrome 브라우저를 지원하는 오픈소스 프로젝트인 Chromium에 기반합니다. 지난 한 해 동안 Chromium은 타사 쿠키 처리에 변경사항을 도입하여 보안과 개인정보 보호를 강화하고 사용자에게는 더 높은 투명성과 제어 기능을 제공했습니다. 이러한 변경사항은 이미 많은 Chrome 사용자에게 배포되었으며 Android 12부터는 이제 변경사항이 WebView에 적용됩니다.

쿠키의 SameSite 속성은 모든 요청과 함께 전송될 수 있는지 아니면 동일한 사이트 요청으로만 전송될 수 있는지를 제어합니다. Android 12의 WebView 기본 버전(버전 89.0.4385.0)에는 타사 쿠키의 기본 처리를 개선하고 의도하지 않은 교차 사이트 공유를 방지할 수 있는 다음과 같은 개인정보 보호 변경사항이 포함되어 있습니다.

  • SameSite 속성이 없는 쿠키는 SameSite=Lax로 간주됩니다.
  • SameSite=None이 있는 쿠키는 Secure 속성도 지정해야 합니다. 즉, 보안 컨텍스트가 필요하고 HTTPS를 통해 전송되어야 합니다.
  • 사이트의 HTTP 버전과 HTTPS 버전 간의 링크는 이제 교차 사이트 요청으로 간주되므로 쿠키가 SameSite=None; Secure로 적절하게 표시되지 않는 한 전송되지 않습니다.

개발자의 경우 일반적으로, 중요한 사용자 흐름에서 교차 사이트 쿠키 종속 항목을 식별하고 SameSite 속성이 필요에 따라 적절한 값과 함께 명시적으로 설정되어 있는지 확인하는 것이 좋습니다. 웹사이트 또는 HTTP에서 HTTPS로 이동하는 동일한 사이트 탐색에서 작동하도록 허용된 쿠키를 명시적으로 지정해야 합니다.

웹 개발자를 위한 이러한 변경사항에 관한 자세한 안내는 SameSite 쿠키 설명Schemeful SameSite를 참고하세요.

앱에서 SameSite 동작 테스트

앱에서 WebView를 사용하는 경우 또는 쿠키를 사용하는 웹사이트나 서비스를 개발자가 관리하는 경우 Android 12 WebView에서 흐름을 테스트하는 것이 좋습니다. 문제가 발견되면 새로운 SameSite 동작을 지원하도록 쿠키를 업데이트해야 할 수 있습니다.

사용자가 안전하지 않은 페이지에서 시작하여 안전한 페이지로 전환하는 로그인 흐름, 구매, 기타 인증 흐름뿐 아니라 로그인 및 삽입된 콘텐츠에 문제가 있는지 확인합니다.

WebView로 앱을 테스트하려면 다음 단계 중 하나를 완료하여 테스트하려는 앱에 새로운 SameSite 동작을 사용 설정해야 합니다.

  • WebView devtools에서 UI 플래그 webview-enable-modern-cookie-same-site를 전환하여 테스트 기기에서 SameSite 동작을 수동으로 사용 설정합니다.

    이 접근 방식을 사용하면 Android 12를 포함하여 Android 5.0(API 수준 21) 이상을 실행하고 WebView 버전 89.0.4385.0 이상을 실행하는 기기에서 테스트할 수 있습니다.

  • targetSdkVersion으로 Android 12를 타겟팅하도록 앱을 컴파일합니다.

    이 접근 방식을 사용한다면 Android 12와 WebView 버전 89.0.4385.0 이상을 실행하는 기기를 사용해야 합니다.

Android에서 WebView의 원격 디버깅에 관한 자세한 내용은 Android 기기 원격 디버깅 시작하기를 참고하세요.

기타 자료

SameSite 최신 동작과 Chrome 및 WebView 출시에 관한 자세한 내용은 Chromium SameSite 업데이트 페이지를 참고하세요. WebView 또는 Chromium에서 버그를 발견하면 공개 Chromium Issue Tracker에 신고할 수 있습니다.

ADB 백업 제한

비공개 앱 데이터를 보호할 수 있도록 Android 12에서는 adb backup 명령어의 기본 동작을 변경합니다. Android 12를 타겟팅하는 앱의 경우 사용자가 adb backup 명령어를 실행하면 앱 데이터는 기기에서 내보내는 다른 시스템 데이터에서 제외됩니다.

테스트 또는 개발 워크플로가 adb backup을 사용하는 앱 데이터에 의존하는 경우 이제 android:debuggable을 앱의 매니페스트 파일에서 true로 설정하여 앱 데이터 내보내기를 선택할 수 있습니다.

보안

더 안전한 구성요소 내보내기

의견 보내기 아이콘구성요소 내보내기 관련 새로운 요구사항에 관한 의견을 기다리고 있습니다. 간단한 설문조사에 참여하여 의견을 들려주세요. 특히 이번 변경사항으로 영향을 받는 앱의 사용 사례를 알려주세요.

앱이 Android 12를 타겟팅하고 인텐트 필터를 사용하는 활동이나 서비스, broadcast receiver를 포함하면 이러한 앱 구성요소의 android:exported 속성을 명시적으로 선언해야 합니다.

경고: 활동이나 서비스, broadcast receiver에서 인텐트 필터를 사용하지만 명시적으로 선언된 android:exported 값이 없으면 Android 12를 실행하는 기기에 앱을 설치할 수 없습니다.

Android 스튜디오를 사용할 때 이러한 앱을 설치하려고 하면 Logcat에 다음과 같은 오류 메시지가 표시됩니다.

Installation did not succeed.
The application could not be installed: INSTALL_FAILED_VERIFICATION_FAILURE
List of apks:
[0] '.../build/outputs/apk/debug/app-debug.apk'
Installation failed due to: 'null'

앱에서 선언해야 하는 android:exported 값을 선언하지 않으면 Logcat에는 다음과 같은 오류 메시지가 표시됩니다.

Targeting S+ (version 10000 and above) requires that an explicit value for \
android:exported be defined when intent filters are present

다음 코드 스니펫은 인텐트 필터가 포함되고 Android 12용으로 올바르게 구성된 서비스의 예를 보여 줍니다.

<service android:name="com.example.app.backgroundService"
         android:exported="false">
    <intent-filter>
        <action android:name="com.example.app.START_BACKGROUND" />
    </intent-filter>
</service>

대기 중인 인텐트는 변경 가능 여부를 선언해야 함

의견 보내기 아이콘 대기 중인 인텐트 관련 새로운 요구사항에 관한 의견을 기다리고 있습니다. 간단한 설문조사에 참여하여 의견을 들려주세요. 특히 이번 변경사항으로 영향을 받는 앱의 사용 사례를 알려주세요.

앱이 Android 12를 타겟팅하는 경우 앱에서 만드는 각 PendingIntent 객체의 변경 가능 여부를 지정해야 합니다. 이 추가 요구사항은 앱의 보안을 강화합니다.

지정된 PendingIntent 객체가 변경 가능한지 불가능한지 여부를 선언하려면 PendingIntent.FLAG_MUTABLE 또는 PendingIntent.FLAG_IMMUTABLE 플래그를 각각 사용합니다. 앱에서 변경 가능 여부 플래그를 설정하지 않고 PendingIntent 객체를 만들려고 하면 시스템에서 IllegalArgumentException이 발생하고 다음 메시지가 Logcat에 표시됩니다.

PACKAGE_NAME: Targeting S+ (version 10000 and above) requires that one of \
FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.

Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if \
some functionality depends on the PendingIntent being mutable, e.g. if \
it needs to be used with inline replies or bubbles.

가능한 경우 변경 불가능한 대기 중인 인텐트 만들기

대부분의 경우 앱에서는 다음 코드 스니펫과 같이 변경 불가능한 PendingIntent 객체를 만들어야 합니다. PendingIntent 객체를 변경할 수 없으면 앱은 인텐트를 수정하여 인텐트 호출의 결과를 조정할 수 없습니다.

Kotlin

val pendingIntent = PendingIntent.getActivity(applicationContext,
        REQUEST_CODE, intent,
        /* flags */ PendingIntent.FLAG_IMMUTABLE)

자바

PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(),
        REQUEST_CODE, intent,
        /* flags */ PendingIntent.FLAG_IMMUTABLE);

그러나 특정 앱에서는 대신 변경 가능한 PendingIntent 객체를 만들어야 합니다.

앱에서 변경 가능한 PendingIntent 객체를 만든다면 명시적 인텐트를 사용하여 ComponentName을 채우는 것이 좋습니다. 이렇게 하면 다른 앱이 PendingIntent를 호출하고 제어 기능을 앱에 다시 전달할 때마다 앱의 동일한 구성요소가 항상 시작됩니다.

대기 중인 인텐트 변경 가능 여부 테스트

앱에서 변경 가능 여부 선언이 누락되었는지 확인하려면 Android 스튜디오에서 다음과 같은 린트 경고를 찾습니다.

Warning: Missing PendingIntent mutability flag [UnspecifiedImmutableFlag]

개발자 프리뷰 중에 PENDING_INTENT_EXPLICIT_MUTABILITY_REQUIRED 앱 호환성 플래그를 사용 중지하여 테스트 목적으로 이 시스템 동작을 사용 중지할 수 있습니다.

안전하지 않은 중첩된 인텐트 실행

플랫폼 보안을 개선하기 위해 Android 12에서는 앱이 안전하지 않은 방식으로 중첩된 인텐트를 실행하면 경고를 표시하는 디버깅 기능을 제공합니다. 중첩된 인텐트는 다른 인텐트에서 추가 항목으로 전달되는 인텐트입니다. 앱에서 다음 두 가지 작업을 모두 실행한다면 StrictMode 위반이 발생합니다.

  1. 앱은 전달된 인텐트의 추가 항목에서 중첩된 인텐트를 분리합니다.
  2. 앱은 인텐트를 startActivity(), startService() 또는 bindService()로 전달하는 등 즉시 중첩된 인텐트를 사용하여 앱 구성요소를 시작합니다.

안전하지 않은 중첩된 인텐트 실행을 감지하도록 앱 구성

앱에서 안전하지 않은 중첩된 인텐트 실행을 확인하려면 다음 코드 스니펫과 같이 VmPolicy를 구성할 때 detectUnsafeIntentLaunch()를 호출합니다. 앱에서 StrictMode 위반을 감지하면 잠재적으로 민감한 정보를 보호하기 위해 앱 실행을 중지하는 것이 좋습니다.

Kotlin

fun onCreate() {
    StrictMode.setVmPolicy(VmPolicy.Builder()
        // Other StrictMode checks that you've previously added.
        // ...
        .detectUnsafeIntentLaunch()
        .penaltyLog()
        // Consider also adding penaltyDeath()
        .build())
}

자바

protected void onCreate() {
    StrictMode.setVmPolicy(new VmPolicy.Builder()
        // Other StrictMode checks that you've previously added.
        // ...
        .detectUnsafeIntentLaunch()
        .penaltyLog()
        // Consider also adding penaltyDeath()
        .build());
}

더 책임감 있는 인텐트 사용

앱에서는 중첩된 인텐트를 실행하여 앱 내부의 구성요소 간에 이동하거나 다른 앱을 대신하여 작업을 실행할 수 있습니다. 어떤 경우든 StrictMode 위반 발생을 최소화하려면 다음을 실행합니다.

  • 중첩된 인텐트의 내부 실행: 이러한 구성요소가 내보내지지 않았는지 확인합니다.
  • 중첩된 인텐트의 교차 앱 출시: 중첩된 인텐트 대신 PendingIntent를 사용합니다. 이렇게 하면 PendingIntent가 포함 Intent에서 분리될 때 앱 구성요소가 호출 프로세스의 ID를 사용하여 PendingIntent를 실행할 수 있습니다. 이 구성을 통해 제공자 앱이 호출 앱의 모든 구성요소(내보내지 않은 구성요소 포함)에 콜백을 전송할 수 있습니다.

    이 사례를 식별하고 앱을 변경하는 방법에 관한 자세한 내용은 Medium의 Android 중첩 인텐트에 관한 블로그 게시물을 참고하세요.

성능

포그라운드 서비스 시작 제한

Android 12를 타겟팅하는 앱은 몇 가지 특수한 사례를 제외하고 백그라운드에서 실행되는 동안 더 이상 포그라운드 서비스를 시작할 수 없습니다. 앱이 백그라운드에서 실행되는 동안 포그라운드 서비스를 시작하려고 하면 예외가 발생합니다(일부 특수한 사례 제외). 앱이 백그라운드에서 실행되는 동안 WorkManager를 사용하여 작업을 예약하고 시작해 보세요.

앱이 어떻게 영향을 받는지 이러한 변경사항에 기반하여 앱을 어떻게 업데이트할 수 있는지에 관한 자세한 내용은 포그라운드 서비스 시작 제한 가이드를 참고하세요. GitHub에서 WorkManagerSample을 살펴볼 수도 있습니다.

서비스나 broadcast receiver에서 알림 트램펄린을 만들 수 없음

의견 보내기 아이콘 이러한 알림 트램펄린 동작 변경사항에 관한 의견을 기다리고 있습니다. 간단한 설문조사에 참여하여 의견을 들려주세요. 특히 이번 변경사항으로 영향을 받는 앱의 사용 사례를 알려주세요.

사용자가 알림과 상호작용할 때 일부 앱은 사용자가 최종적으로 보고 상호작용하는 활동을 결국 시작하는 앱 구성요소를 실행하여 알림 탭에 응답합니다. 이 앱 구성요소를 알림 트램펄린이라고 합니다.

앱 성능과 UX를 개선하기 위해 Android 12를 타겟팅하는 앱은 알림 트램펄린으로 사용되는 서비스broadcast receiver에서 활동을 시작할 수 없습니다. 즉, 사용자가 알림을 탭하거나 알림 내에서 작업 버튼을 탭한 후, 앱은 서비스나 broadcast receiver 내부에서 startActivity()를 호출할 수 없습니다.

앱이 알림 트램펄린 역할을 하는 서비스나 broadcast receiver에서 활동을 시작하려고 하면 시스템에서는 활동이 시작되지 못하게 하고 다음 메시지가 Logcat에 표시됩니다.

Indirect notification activity start (trampoline) from PACKAGE_NAME, \
this should be avoided for performance reasons.

앱 업데이트

앱이 알림 트램펄린 역할을 하는 서비스나 broadcast receiver에서 활동을 시작하는 경우 다음 이전 단계를 완료하세요.

  1. 다음 활동 중 하나와 연결된 PendingIntent 객체를 만듭니다.

    • 사용자가 알림을 탭한 후 표시되는 활동(권장)
    • 트램펄린 활동 또는 사용자가 알림을 탭한 후 표시되는 활동을 시작하는 활동
  2. 알림 빌드의 일부로 이전 단계에서 만든 PendingIntent 객체를 사용합니다.

동작 전환

개발자 프리뷰 중에 앱을 테스트할 때 NOTIFICATION_TRAMPOLINE_BLOCK 앱 호환성 플래그를 사용하여 이 제한을 사용 설정하거나 사용 중지할 수 있습니다.

비 SDK 인터페이스 제한사항

Android 12에는 Android 개발자와의 공동작업 및 최신 내부 테스트를 기반으로 제한된 비 SDK 인터페이스의 업데이트된 목록이 포함되어 있습니다. 가능하면 Google은 비 SDK 인터페이스를 제한하기 전에 공개 대안을 사용할 수 있게 합니다.

Android 12를 타겟팅하지 않는 앱의 경우 이러한 변경사항 중 일부는 개발자에게 곧바로 영향을 주지 않을 수도 있습니다. 그러나 현재 앱의 타겟 API 수준에 따라 일부 비 SDK 인터페이스를 사용할 수 있지만 비 SDK 메서드 또는 필드를 사용하면 항상 앱이 중단될 위험성이 높아집니다.

앱에서 비 SDK 인터페이스를 사용하는지 확실히 알 수 없는 경우 앱을 테스트하여 확인할 수 있습니다. 앱에서 비 SDK 인터페이스를 사용하는 경우 대체 SDK로의 이전을 계획해야 합니다. 일부 앱의 경우 비 SDK 인터페이스 사용에 관한 유효한 사용 사례가 있음을 알고 있습니다. 앱 기능을 구현하기 위해 비 SDK 인터페이스 대신 무엇을 사용해야 할지 알 수 없다면 새 공개 API를 요청해야 합니다.

이 Android 버전의 변경사항을 자세히 알아보려면 Android 12의 비 SDK 인터페이스 제한사항 업데이트를 참고하세요. 비 SDK 인터페이스에 관해 전반적으로 알아보려면 비 SDK 인터페이스 제한사항을 참조하세요.

맞춤 알림 변경사항

Android 12는 완전한 맞춤 알림의 모양을 변경합니다. 이전에는 맞춤 알림이 전체 알림 영역을 사용하여 자체 레이아웃과 스타일을 제공했습니다. 이로 인해 사용자에게 혼동을 주거나 다양한 기기에서 레이아웃 호환성 문제를 일으킬 수 있는 안티패턴이 생겼습니다.

Android 12를 타겟팅하는 앱의 경우 맞춤 콘텐츠 뷰가 포함된 알림은 더 이상 전체 알림 영역을 사용하지 않습니다. 대신 시스템에서 표준 템플릿을 적용합니다. 이 템플릿은 맞춤 알림이 알림의 아이콘 및 확장 어포던스(접힌 상태)와 알림의 아이콘, 앱 이름, 축소 어포던스(펼친 상태) 등 모든 상태에서 다른 알림과 동일한 장식을 보유하도록 합니다. 이 동작은 Notification.DecoratedCustomViewStyle의 동작과 거의 동일합니다.

이러한 방식을 통해 Android 12는 모든 알림이 시각적으로 일관되고 쉽게 검색되도록 하며 사용자에게 검색 가능하고 친숙한 알림 확장 기능을 제공합니다.

다음 그림은 표준 템플릿의 맞춤 알림을 보여 줍니다.

다음 예는 맞춤 알림이 접힌 상태와 펼친 상태로 렌더링되는 방식을 보여 줍니다.

Android 12의 변경사항은 Notification.Style의 맞춤 서브클래스를 정의하거나 Notification.Builder의 메서드 setCustomContentView(RemoteViews), setCustomBigContentView(RemoteViews), setCustomHeadsUpContentView(RemoteViews)를 사용하는 앱에 영향을 줍니다.

앱에서 완전한 맞춤 알림을 사용하면 가능한 한 빨리 새 템플릿으로 테스트하여 필요한 사항을 조정하는 것이 좋습니다.

  1. 맞춤 알림 변경 사용 설정

    1. 앱의 targetSdkVersionS로 변경하여 새 동작을 사용 설정합니다.
    2. 다시 컴파일합니다.
    3. Android 12를 실행하는 기기나 에뮬레이터에 앱을 설치합니다.
  2. 맞춤 뷰를 사용하는 알림을 모두 테스트하여 예상대로 알림 창에 표시되는지 확인합니다.

  3. 맞춤 뷰 측정에 유의합니다. 일반적으로 맞춤 알림에 제공되는 높이는 이전보다 낮습니다. 접힌 상태에서 맞춤 콘텐츠의 최대 높이는 106dp에서 48dp로 줄었습니다. 가로 공간도 더 적습니다.

  4. '보행 중 주의 알림' 상태가 예상대로 표시되도록 하려면 알림 채널의 중요도를 'HIGH'(화면에 표시)로 올려야 합니다.

연결성

Android 12 이상을 타겟팅하는 기기가 하드웨어 지원 기기에서 실행되는 경우 P2P 연결을 사용하면 피어 기기에 연결할 때 기존 Wi-Fi 연결이 해제되지 않습니다. 이 기능 지원을 확인하려면 WifiManager.isMultiStaConcurrencySupported()를 사용하세요.