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

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

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

사용자 환경

PIP 모드 동작 개선사항

Android 12에서는 PIP 모드의 동작을 개선합니다. 자세한 내용은 PIP 모드 개선사항을 참고하세요.

맞춤 알림

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. 맞춤 뷰를 사용하는 알림을 모두 테스트하여 예상대로 알림 창에 표시되는지 확인합니다. 테스트하는 동안 다음 사항을 고려하여 필요에 따라 조정합니다.

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

    • Android 12를 타겟팅하는 앱의 경우 모든 알림이 확장 가능합니다. 일반적으로 이는 setCustomContentView를 사용하는 경우 setBigCustomContentView도 사용하여 접힌 상태와 펼쳐진 상태가 일관되도록 하는 것이 좋다는 의미입니다.

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

Android 12를 타겟팅하는 앱에서 시스템은 Android App Links를 확인하는 방법을 몇 가지 변경합니다. 이러한 변경사항은 앱 연결 환경의 안정성을 개선하고 앱 개발자와 최종 사용자에게 더 많은 제어권을 제공합니다.

Android 12를 타겟팅하고 Android App Links 확인을 사용하여 앱에서 웹 링크를 연다면 변경된 확인 프로세스를 지원하도록 Android App Links 선언을 업데이트하세요. 수동으로 도메인 확인을 호출하여 선언의 안정성을 테스트할 수도 있습니다.

개인 정보 보호

대략적인 위치

두 가지 옵션 세트가 세로로 배치된 대화상자
그림 1. 앱이 Android 12를 타겟팅하고 단일 런타임 요청에서 ACCESS_FINE_LOCATIONACCESS_COARSE_LOCATION을 모두 요청할 때 표시되는 시스템 권한 대화상자

Android 12를 타겟팅하는 앱을 사용할 때 사용자는 앱이 대략적인 위치 정보에만 액세스하도록 요청할 수 있습니다.

앱이 Android 12를 타겟팅하고 ACCESS_FINE_LOCATION 런타임 권한을 요청한다면 ACCESS_COARSE_LOCATION 권한도 요청해야 합니다. 단일 런타임 요청에 두 권한을 모두 포함해야 합니다.

앱이 ACCESS_FINE_LOCATIONACCESS_COARSE_LOCATION을 모두 요청하면 시스템 권한 대화상자에는 그림 1과 같이 새로운 사용자 옵션이 포함됩니다.

  • 정확한 위치: ACCESS_FINE_LOCATION 권한이 제공하는 위치 정확도를 제공합니다.
  • 대략적인 위치: ACCESS_COARSE_LOCATION 권한이 제공하는 위치 정확도를 제공합니다.

Android 12의 대략적인 위치 자세히 알아보기

앱 최대 절전 모드

Android 12에서는 Android 11(API 수준 30)에서 도입된 권한 자동 초기화 동작을 확장합니다. 앱이 Android 12를 타겟팅하고 사용자가 몇 달 동안 앱과 상호작용하지 않는다면 시스템은 부여된 모든 권한을 자동 초기화하고 앱을 최대 절전 모드 상태로 전환합니다.

최대 절전 모드인 앱의 특성은 다음과 같습니다.

  • 시스템이 성능 대신 저장공간을 최적화합니다. 앱 캐시에 있는 모든 파일이 삭제됩니다.
  • 앱이 백그라운드에서 작업이나 알림을 실행할 수 없습니다.
  • 앱이 Firebase 클라우드 메시징을 통해 전송되는 높은 우선순위의 메시지를 비롯하여 푸시 알림을 수신할 수 없습니다.

사용자가 다음에 앱과 상호작용할 때 앱이 최대 절전 모드를 종료하므로 작업과 경고, 알림을 다시 만들 수 있습니다. 그러나 앱이 최대 절전 모드로 전환되기 전에 예약된 모든 작업과 경고, 알림의 일정은 변경해야 합니다. 이 워크플로는 사용자가 시스템 설정에서 앱을 수동으로 강제 종료할 때와 비슷합니다. 이 워크플로를 더 쉽게 지원하려면 WorkManager를 사용하세요. 앱이 최대 절전 모드를 종료할 때 그리고 기기가 부팅된 후 호출되는 ACTION_BOOT_COMPLETED broadcast receiver에 일정 변경 로직을 추가할 수도 있습니다.

사용자에게 최대 절전 모드 사용 중지 요청

앱의 사용 사례가 최대 절전 모드에 영향받을 것으로 예상된다면 사용자에게 최대 절전 모드 및 권한 자동 초기화 예외를 앱에 허용하라는 요청을 보낼 수 있습니다. 이 예외는 앱이 다음 중 하나 이상을 실행하는 경우와 같이 사용자가 앱과 상호작용하지 않아도 앱이 주로 백그라운드에서 작동한다고 예상하는 상황에 유용합니다.

  • 가족 구성원의 위치를 주기적으로 보고하여 가족의 안전을 제공합니다.
  • 기기와 앱 서버 간에 데이터를 동기화합니다.
  • TV와 같은 스마트 기기와 통신합니다.
  • 시계와 같은 호환 기기와 페어링합니다.

예외를 요청하려면 Intent.ACTION_APPLICATION_DETAILS_SETTINGS 인텐트 작업이 포함된 인텐트를 호출합니다. 표시되는 화면에서 사용자는 권한 삭제 및 여유 공간 확보라는 옵션을 사용 중지할 수 있습니다.

최대 절전 모드 동작 테스트

테스트 목적으로 앱을 최대 절전 모드 상태로 전환하려면 다음 작업을 실행하세요.

  1. 기기에서 동작을 사용 설정합니다.

    adb shell device_config put app_hibernation app_hibernation_enabled true
    
  2. 앱이 최대 절전 모드로 전환되도록 앱 상태를 변경합니다. --global 플래그가 포함된 명령어는 앱을 '전체 최대 절전 모드'로 강제 전환하여 시스템이 멀티 사용자 기기의 모든 사용자를 위해 앱을 최대 절전 모드로 전환한 상황을 시뮬레이션합니다.

    adb shell cmd app_hibernation set-state PACKAGE-NAME true && \
      adb shell cmd app_hibernation set-state --global PACKAGE-NAME true
    

움직임 감지 센서의 속도가 제한됨

잠재적으로 민감한 사용자 정보를 보호하기 위해 앱이 Android 12를 타겟팅하는 경우 시스템은 특정 움직임 감지 센서와 위치 센서의 데이터 새로고침 빈도를 제한합니다. 이 데이터에는 기기의 가속도계, 자이로스코프, 지자기장 센서에 기록된 값이 포함됩니다.

새로고침 빈도 제한은 센서 데이터에 액세스하는 방법에 따라 다릅니다.

  • registerListener() 메서드를 호출하면 센서 샘플링 레이트가 200Hz로 제한됩니다. registerListener() 메서드의 오버로드된 모든 변형에도 적용됩니다.
  • SensorDirectChannel 클래스를 사용하면 센서 샘플링 레이트가 일반적으로 약 50Hz인 RATE_NORMAL로 제한됩니다.

앱이 Android 12를 타겟팅하고 높은 속도로 움직임 감지 센서 데이터를 수집해야 한다면 HIGH_SAMPLING_RATE_SENSORS 권한을 선언해야 합니다. 이 권한 선언 없이 앱이 높은 속도로 움직임 감지 센서 데이터를 수집하려고 하면 SecurityException이 발생합니다.

데이터 액세스 분석

Android 11(API 수준 30)에서 도입된 데이터 액세스 분석 API를 사용하면 앱의 사용 사례에 기반하여 저작자 표시 태그를 생성할 수 있습니다. 이러한 태그를 통해 앱에서 특정 유형의 데이터 액세스를 실행하는 부분을 더 쉽게 확인할 수 있습니다.

앱이 Android 12를 타겟팅한다면 다음 코드 스니펫에 나온 형식을 사용하여 이러한 저작자 표시 태그를 앱의 매니페스트 파일에서 선언해야 합니다. 앱이 Android 12를 타겟팅하고 개발자가 앱의 매니페스트 파일에서 선언하지 않은 저작자 표시 태그를 사용하려고 하면 시스템은 null 태그를 만들고 Logcat에 메시지를 기록합니다.


<manifest ...>
    <!-- The value of "android:tag" must be a literal string, and the
         value of "android:label" must be a resource. The value of
         "android:label" should be user-readable. -->
    <attribution android:tag="sharePhotos"
                 android:label="@string/share_photos_attribution_label" />
    ...
</manifest>

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 속성을 명시적으로 선언해야 합니다.

다음 코드 스니펫은 인텐트 필터가 포함되고 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 스튜디오의 메시지

앱에 인텐트 필터를 사용하지만 android:exported를 선언하지 않는 활동이나 서비스, broadcast receiver가 포함되어 있다면 사용하는 Android 스튜디오 버전에 따라 다음과 같은 경고 메시지가 표시됩니다.

Android 스튜디오 2020.3.1 Canary 11 이상

다음 메시지가 표시됩니다.

  1. 다음 린트 경고가 매니페스트 파일에 표시됩니다.

    When using intent filters, please specify android:exported as well
    
  2. 앱을 컴파일하려고 하면 다음과 같은 빌드 오류 메시지가 표시됩니다.

    Manifest merger failed : Apps targeting Android 12 and higher are required \
    to specify an explicit value for android:exported when the corresponding \
    component has an intent filter defined.
    
이전 버전의 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 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에서는 앱이 안전하지 않은 방식으로 인텐트를 실행하면 경고를 표시하는 디버깅 기능을 제공합니다. 예를 들어 앱이 URI에서 다시 생성된 인텐트를 안전하지 않은 방식으로 실행하거나 다음 섹션에서 정의하는 중첩된 인텐트를 안전하지 않은 방식으로 실행할 수 있습니다.

중첩된 인텐트 정보

중첩된 인텐트는 다른 인텐트에서 추가 항목으로 전달되는 인텐트입니다. 앱에서 다음 두 가지 작업을 모두 실행한다면 StrictMode 위반이 발생합니다.

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

앱에서 안전하지 않은 인텐트 실행을 확인하려면 다음 코드 스니펫과 같이 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 위반 발생을 최소화하려면 다음을 실행합니다.

  • 인텐트 내 필수 추가 항목만 복사하고 필요한 정리 및 검증을 실행합니다. 앱은 한 인텐트에서 새 구성요소를 실행하는 데 사용되는 다른 인텐트로 추가 항목을 복사할 수 있습니다. 이는 앱이 putExtras(Intent)putExtras(Bundle)를 호출할 때 발생합니다. 앱이 이러한 작업 중 하나를 실행하면 수신 구성요소에서 예상하는 추가 항목만 복사합니다. 복사본을 수신하는 다른 인텐트가 내보내지 않은 구성요소를 실행하는 경우 추가 항목을 정리하고 검증한 후 구성요소를 실행하는 인텐트에 복사합니다.
  • 중첩된 인텐트의 내부 실행: 이러한 구성요소를 내보내지 않았는지 확인합니다.
  • 중첩된 인텐트의 교차 앱 출시: 중첩된 인텐트 대신 PendingIntent를 사용합니다. 이렇게 하면 PendingIntent가 포함 Intent에서 분리될 때 앱 구성요소가 호출 프로세스의 ID를 사용하여 PendingIntent를 실행할 수 있습니다. 이 구성을 통해 제공자 앱이 호출 앱의 모든 구성요소(내보내지 않은 구성요소 포함)에 콜백을 전송할 수 있습니다.

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

성능

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

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

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

정확한 알람 권한

앱의 시스템 리소스 절약을 유도하기 위해 Android 12에는 정확한 알람을 설정하는 Android 12를 타겟팅하는 앱에 관한 '알람 및 리마인더' 특수 앱 액세스 권한이 필요합니다.

이 특수 앱 액세스 권한을 가져오려면 매니페스트에서 SCHEDULE_EXACT_ALARM 권한을 요청하세요.

정확한 알람은 허용되는 사용 사례 섹션에 설명된 상황 중 하나와 같이 사용자에게 표시되는 기능에만 사용해야 합니다.

사용자와 시스템은 모두 '알람 및 리마인더' 특수 앱 액세스 권한을 취소할 수 있습니다. 앱의 '알람 및 리마인더' 특수 앱 액세스 권한이 취소되면 앱이 중지되고 향후 모든 정확한 알람이 취소됩니다.

'알람 및 리마인더' 특수 앱 액세스 권한이 앱에 부여되면 시스템은 ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED 브로드캐스트를 앱에 전송합니다. 앱은 다음을 실행하는 broadcast receiver를 구현해야 합니다.

  1. 앱에 여전히 특수 앱 액세스 권한이 있는지 확인합니다. canScheduleExactAlarms()를 호출하면 됩니다.
  2. 현재 상태에 따라 앱에 필요한 정확한 알람의 일정을 변경합니다. 이 로직은 앱이 ACTION_BOOT_COMPLETED 브로드캐스트를 수신할 때 실행하는 작업과 비슷합니다.

정확한 알람을 설정하지만 특수 앱 액세스 권한이 부여되지 않은 API를 앱에서 사용하려고 하면 SecurityException이 발생합니다.

허용되는 사용 사례 섹션에 설명된 상황 중 하나와 같이 앱의 사용 사례에 정확한 알람이 꼭 필요한지 고려합니다. 더 긴 작업이나 네트워크 액세스가 필요한 작업을 실행하려면 WorkManagerJobScheduler를 사용하세요. 기기가 잠자기 모드일 때 작업을 실행하려면 setAndAllowWhileIdle()을 사용하여 부정확한 알람을 만들고 알람에서 작업을 시작합니다.

정확한 알람과 부정확한 알람

앱은 다음과 같은 메서드를 호출할 때 정확한 알람을 설정합니다.

이와는 달리 개발자는 다음과 같은 메서드를 호출할 때 부정확한 알람을 설정합니다.

이 권한의 허용되는 사용 사례

&#39;알람 및 리마인더 설정 허용&#39; 옵션
그림 2. 사용자가 앱이 정확한 알람을 설정하도록 허용할 수 있는 시스템 설정의 '알람 및 리마인더' 특수 앱 액세스 권한 페이지

앱의 사용자에게 표시되는 기능에 다음 상황과 같이 정확하게 시간이 지정된 작업이 필요한 경우에만 앱은 정확한 알람을 사용하고 관련 권한과 broadcast receiver를 선언해야 합니다.

  • 앱이 알람 시계 앱이거나 타이머 앱입니다.
  • 앱에서 사용자가 작업 및 이벤트 알림과 같은 정확하게 시간이 지정된 작업을 예약할 수 있습니다.

Android 12에서는 정확한 알람을 중요하고 시간에 민감한 중단으로 간주합니다. 따라서 정확한 알람은 새로운 포그라운드 서비스 실행 제한에 영향받지 않습니다.

사용자에게 앱 액세스 권한 부여 요청

필요하다면 사용자를 그림 2와 같이 시스템 설정의 알람 및 리마인더 화면으로 보낼 수 있습니다. 그러려면 다음 단계를 완료하세요.

  1. 앱의 UI에서 사용자에게 앱이 정확한 알람을 예약해야 하는 이유를 설명합니다.
  2. ACTION_REQUEST_SCHEDULE_EXACT_ALARM 인텐트 작업이 포함된 인텐트를 호출합니다.

동작 변경 사용 설정

테스트 목적으로 동작 변경을 사용 설정하려면 다음 중 하나를 실행하세요.

  • 개발자 옵션 설정 화면에서 앱 호환성 변경사항을 선택합니다. 표시되는 화면에서 앱 이름을 탭하고 REQUIRE_EXACT_ALARM_PERMISSION을 사용 설정합니다.
  • 개발 머신의 터미널 창에서 다음 명령어를 실행합니다.

    adb shell am compat enable REQUIRE_EXACT_ALARM_PERMISSION PACKAGE_NAME
    

알림 트램펄린 제한사항

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

앱 성능과 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를 식별할 수 있습니다. 다음 터미널 명령어의 출력을 확인하면 됩니다.

adb shell dumpsys activity service \
  com.android.systemui/.dump.SystemUIAuxiliaryDumpService

출력의 섹션에 'NotifInteractionLog'라는 텍스트가 포함되어 있습니다. 이 섹션에는 알림 탭으로 인해 시작되는 구성요소를 식별하는 데 필요한 정보가 포함되어 있습니다.

앱 업데이트

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

  1. 사용자가 알림을 탭한 후 표시되는 활동과 연결된 PendingIntent 객체를 만듭니다.
  2. 알림 빌드의 일부로 이전 단계에서 만든 PendingIntent 객체를 사용합니다.

활동의 출처를 식별하려면(예: 로깅을 실행하기 위해) 알림을 게시할 때 추가 항목을 사용합니다. 중앙 집중식 로깅의 경우 ActivityLifecycleCallbacksJetpack 수명 주기 관찰자를 사용하세요.

동작 전환

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

백업 및 복원

Android 12에서는 Android 12 이상에서 실행되거나 Android 12 이상을 타겟팅하는 앱에서 백업 및 복원이 작동하는 방식을 변경합니다. 자세한 내용은 백업 및 복원 변경사항을 참고하세요.

연결성

동시 P2P + 인터넷 연결

Android 12부터 동시 P2P와 인터넷 연결을 지원하는 기기는 피어 기기와 기본 인터넷 제공 네트워크로의 동시 Wi-Fi 연결을 모두 유지하므로 사용자 환경이 더 원활해집니다. 이 기능은 API 수준 31 이상을 타겟팅하는 모든 앱에 자동으로 사용 설정됩니다. 더 낮은 API 수준을 타겟팅하는 앱에서는 피어 기기에 연결하기 전에 기본 Wi-Fi 네트워크의 연결이 해제되는 기존 동작이 계속 발생합니다.

호환성

WifiManager.getConnectionInfo()는 단일 네트워크의 경우에만 WifiInfo를 반환할 수 있습니다. 따라서 Android 12에서는 API 동작이 다음과 같이 변경되었습니다.

  • 단일 Wi-Fi 네트워크만 사용할 수 있는 경우 WifiInfo가 반환됩니다.
  • Wi-Fi 네트워크를 두 개 이상 사용할 수 있고 통화 앱이 P2P 연결을 트리거한 경우 피어 기기에 상응하는 WifiInfo가 반환됩니다.
  • Wi-Fi 네트워크를 두 개 이상 사용할 수 있고 통화 앱이 P2P 연결을 트리거하지 않은 경우 기본 인터넷 제공 연결의 WifiInfo가 반환됩니다.

듀얼 동시 Wi-Fi 네트워크를 지원하는 기기에서 더 나은 사용자 환경을 제공하려면 모든 앱(특히 P2P 연결을 트리거하는 앱)이 WifiManager.getConnectionInfo() 호출에서 이전하고 대신 NetworkCallback.onCapabilitiesChanged()를 사용하여 NetworkCallback을 등록하는 데 사용되는 NetworkRequest와 일치하는 모든 WifiInfo 객체를 가져오는 것이 좋습니다. getConnectionInfo()는 Android 12부터 지원 중단됩니다.

다음 코드 샘플은 NetworkCallback에서 WifiInfo를 가져오는 방법을 보여줍니다.

Kotlin

val networkCallback = object : ConnectivityManager.NetworkCallback() {
  ...
  override fun onCapabilitiesChanged(
           network : Network,
           networkCapabilities : NetworkCapabilities) {
    val transportInfo = networkCapabilities.getTransportInfo()
    if (transportInfo !is WifiInfo) return
    val wifiInfo : WifiInfo = transportInfo
    ...
  }
}

자바

final NetworkCallback networkCallback = new NetworkCallback() {
  ...
  @Override
  public void onCapabilitiesChanged(
         Network network,
         NetworkCapabilities networkCapabilities) {
    final TransportInfo transportInfo = networkCapabilities.getTransportInfo();
    if (!(transportInfo instanceof WifiInfo)) return;
    final WifiInfo wifiInfo = (WifiInfo) transportInfo;
    ...
  }
  ...
};

NFC 결제에 화면 끄기 사용 설정

Android 12 이상을 타겟팅하는 앱에서는 requireDeviceScreenOnfalse로 설정하여 기기 화면이 켜지지 않은 상태에서 NFC 결제를 사용 설정할 수 있습니다. 꺼진 화면이나 잠금 화면에서 NFC 결제에 관한 자세한 내용은 꺼진 화면 및 잠금 화면 동작을 참고하세요.

공급업체 라이브러리

공급업체 제공 네이티브 공유 라이브러리

실리콘 공급업체나 기기 제조업체에서 제공한 비 NDK 네이티브 공유 라이브러리에는 앱이 Android 12 이상을 타겟팅하면 기본적으로 액세스할 수 없습니다. <uses-native-library> 태그를 사용하여 명시적으로 요청된 때만 라이브러리에 액세스할 수 있습니다.

앱이 Android 11 이하를 타겟팅한다면 <uses-native-library> 태그가 필요하지 않습니다. 이 경우 NDK 라이브러리인지와 상관없이 모든 네이티브 공유 라이브러리에 액세스할 수 있습니다.

업데이트된 비 SDK 제한사항

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

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

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

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