[Android 14] 안드로이드 14 타겟팅시 변경되는 주요 사항들
동작 변경: Android 14 이상을 대상으로 하는 앱
이전 릴리스와 마찬가지로 Android 14에는 앱에 영향을 줄 수 있는 동작 변경 사항이 포함되어 있습니다. 다음 동작 변경 사항은 Android 14 이상을 대상으로 하는 앱에만 적용됩니다. 앱이 Android 14 이상을 대상으로 하는 경우 해당하는 경우 이러한 동작을 올바르게 지원하도록 앱을 수정해야 합니다.
핵심 기능
포그라운드 서비스 유형은 필수 항목입니다.
앱이 Android 14를 대상으로 하는 경우 앱 내의 각 포그라운드 서비스 에 대해 하나 이상의 포그라운드 서비스 유형을 지정 해야 합니다. 앱의 사용 사례를 나타내는 포그라운드 서비스 유형을 선택해야 합니다. 시스템은 특정 사용 사례를 충족하기 위해 특정 유형의 포그라운드 서비스를 기대합니다.
참고: Android 14에는 상태 및 원격 메시징 사용 사례를 위한 포그라운드 서비스 유형이 도입되었습니다. 시스템은 또한 짧은 서비스 , 특수 사용 사례 및 시스템 예외를 위한 새로운 유형을 예약합니다 .
앱의 사용 사례가 이러한 유형과 연결되지 않은 경우 WorkManager 또는 사용자 시작 데이터 전송 작업을 사용하도록 로직을 마이그레이션하는 것이 좋습니다 .
OpenJDK 17 업데이트
Android 14는 앱 및 플랫폼 개발자를 위한 라이브러리 업데이트 및 Java 17 언어 지원을 포함하여 최신 OpenJDK LTS 릴리스의 기능에 맞추기 위해 Android의 핵심 라이브러리를 새로 고치는 작업을 계속합니다.
이러한 변경 사항 중 일부는 앱 호환성에 영향을 줄 수 있습니다.
- 정규 표현식에 대한 변경 사항 : 잘못된 그룹 참조는 이제 OpenJDK의 의미 체계를 더 밀접하게 따르도록 허용되지 않습니다. IllegalArgumentException클래스에서 an이 발생하는 새로운 사례를 볼 수 있으므로 java.util.regex.Matcher정규 표현식을 사용하는 영역에 대해 앱을 테스트해야 합니다. 테스트하는 동안 이 변경 사항을 활성화 또는 비활성화하려면 호환성 프레임워크 도구를DISALLOW_INVALID_GROUP_REFERENCE 사용하여 플래그를 토글합니다 .
- UUID 처리 : 이 java.util.UUID.fromString()메서드는 이제 입력 인수의 유효성을 검사할 때 보다 엄격한 검사를 수행하므로 IllegalArgumentException역직렬화 중에 가 표시될 수 있습니다. 테스트하는 동안 이 변경 사항을 활성화 또는 비활성화하려면 호환성 프레임워크 도구를ENABLE_STRICT_VALIDATION 사용하여 플래그를 토글합니다 .
- ProGuard 문제 : 경우에 따라 ProGuard를 사용하여 앱을 축소, 난독화 및 최적화하려고 하면 클래스 추가로 java.lang.ClassValue인해 문제가 발생합니다. Class.forName(“java.lang.ClassValue”)문제는 클래스 반환 여부 에 따라 런타임 동작을 변경하는 Kotlin 라이브러리에서 발생합니다 . 앱이 사용 가능한 클래스 없이 이전 버전의 런타임에 대해 개발된 경우 java.lang.ClassValue이러한 최적화는 computeValue에서 파생된 클래스에서 메서드를 제거할 수 있습니다 java.lang.ClassValue.
보안
암시적 및 보류 중인 의도에 대한 제한 사항
Android 14를 대상으로 하는 앱의 경우 Android는 앱이 다음과 같은 방식으로 내부 앱 구성요소에 암시적 인텐트를 전송하지 못하도록 제한합니다.
- 암시적 인텐트는 내보낸 구성 요소에만 전달됩니다. 앱은 내보내지 않은 구성요소에 전달하기 위해 명시적 인텐트를 사용하거나 구성요소를 내보낸 것으로 표시해야 합니다.
- 앱이 구성요소 또는 패키지를 지정하지 않는 인텐트로 변경 가능한 보류 인텐트를 생성하는 경우 이제 시스템에서 예외가 발생합니다.
이러한 변경 사항은 악성 앱이 앱의 내부 구성 요소에서 사용하도록 의도된 암시적 의도를 가로채는 것을 방지합니다.
예를 들어 앱의 매니페스트 파일에서 선언할 수 있는 인텐트 필터는 다음과 같습니다.
<activity
android:name=".AppActivity"
android:exported="false">
<intent-filter>
<action android:name="com.example.action.APP_ACTION" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
앱이 암시적 인텐트를 사용하여 이 활동을 시작하려고 하면 예외가 발생합니다.
// Throws an exception when targeting Android 14.
context.startActivity(new Intent("com.example.action.APP_ACTION"));
내보내지 않은 활동을 시작하려면 앱에서 명시적 인텐트를 대신 사용해야 합니다.
// This makes the intent explicit.
Intent explicitIntent =
new Intent("com.example.action.APP_ACTION")
explicitIntent.setPackage(context.getPackageName());
context.startActivity(explicitIntent);
런타임에 등록된 브로드캐스트 수신기는 내보내기 동작을 지정해야 합니다.
Android 14를 타겟팅하고 컨텍스트에 등록된 수신기를 사용하는 앱 및 서비스는 수신기를 기기의 다른 모든 앱으로 내보내야 하는지 여부를 나타내는 플래그를 각각 또는 로 지정해야 RECEIVER_EXPORTED합니다 RECEIVER_NOT_EXPORTED. 이 요구사항은 Android 13에 도입된 이러한 수신기의 기능을 활용하여 보안 취약성으로부터 앱을 보호하는 데 도움이 됩니다 .
브로드캐스트 전송을 모니터링하기 위해 Android에서 브로드캐스트 수신기를 등록하는 방법에는 동적 등록과 정적 등록의 두 가지 방법이 있습니다.
동적 등록은 코드에 등록하는 것이고 정적 등록은 AndroidManifest.xml에 등록하는 것입니다.
따라서 Android 14부터 앱이 캐시 상태에 들어가는 한 동적으로 등록된 모든 브로드캐스트 수신기는 더 이상 브로드캐스트를 수신할 수 없습니다. 수신될 수 있었던 모든 브로드캐스트는 일시적으로 시스템 브로드캐스트 대기열에 들어가며, 앱이 전경으로 돌아오면 이 대기열의 브로드캐스트가 한 번에 전달됩니다.
또한 이 변경은 dynamic 모드로 등록된 broadcast receiver에만 해당되며 static 모드로 등록된 broadcast receiver는 이전 동작에서 변경되지 않은 상태로 유지됩니다.
시스템 브로드캐스트만 수신하는 수신기의 경우 예외
앱이 와 같은 메서드를 통해 시스템 브로드캐스트 에 대해서만 수신기를 등록하는 경우 수신기를 등록할 때 플래그를 지정하면 안 됩니다.Context#registerReceiverContext#registerReceiver()
더 안전한 동적 코드 로딩
앱이 Android 14를 대상으로 하고 DCL(Dynamic Code Loading)을 사용하는 경우 동적으로 로드되는 모든 파일을 읽기 전용으로 표시해야 합니다. 그렇지 않으면 시스템에서 예외가 발생합니다. 코드 삽입 또는 코드 변조로 인해 앱이 손상될 수 있는 위험이 크게 증가하므로 가능하면 앱에서 동적으로 코드를 로드하지 않는 것이 좋습니다 .
코드를 동적으로 로드해야 하는 경우 다음 접근 방식을 사용하여 동적으로 로드된 파일(예: DEX, JAR 또는 APK 파일)을 열자마자 내용이 작성되기 전에 읽기 전용으로 설정합니다.
File jar = new File("DYNAMICALLY_LOADED_FILE.jar");
try (FileOutputStream os = new FileOutputStream(jar)) {
// Set the file to read-only first to prevent race conditions
jar.setReadOnly();
// Then write the actual file content
} catch (IOException e) { ... }
PathClassLoader cl = new PathClassLoader(jar, parentClassLoader);
이미 존재하는 동적으로 로드된 파일 처리
동적으로 로드된 기존 파일에 대해 예외가 발생하지 않도록 하려면 앱에서 파일을 동적으로 다시 로드하기 전에 파일을 삭제하고 다시 만드는 것이 좋습니다. 파일을 재생성할 때 쓰기 시 파일을 읽기 전용으로 표시하기 위한 이전 지침을 따르십시오. 또는 기존 파일의 레이블을 읽기 전용으로 다시 지정할 수 있지만 이 경우 파일을 보호하기 위해 먼저 파일의 무결성을 확인하는 것이 좋습니다(예: 신뢰할 수 있는 값에 대해 파일의 서명 확인). 악의적인 행동으로부터 앱.
우편 경로 순회
Android 14를 대상으로 하는 앱의 경우 Android는 다음과 같은 방식으로 Zip 경로 순회 취약성을 방지하고 ZipFile(String)zip 파일 항목 이름에 “..”가 포함되어 있거나 “/”로 시작하는 경우 오류를 ZipInputStream.getNextEntry() 발생시킵니다 .ZipException
앱은 를 호출하여 이 유효성 검사를 거부할 수 있습니다 dalvik.system.ZipPathValidator.clearCallback().
백그라운드에서 활동 시작에 대한 추가 제한 사항
Android 14를 대상으로 하는 앱의 경우 시스템은 앱이 백그라운드에서 활동을 시작하도록 허용되는 시기를 추가로 제한합니다.
- 앱이 PendingIntentusing PendingIntent#send() 또는 유사한 메서드를 보낼 때 보류 중인 의도를 시작하기 위해 자체 백그라운드 활동 시작 권한을 부여하려는 경우 앱은 이제 옵트인해야 합니다. 옵트인하려면 앱이 ActivityOptions번들을 전달해야 합니다 setPendingIntentBackgroundActivityStartMode(MODE_BACKGROUND_ACTIVITY_START_ALLOWED).
- 보이는 앱이 메서드를 사용하여 백그라운드에 있는 다른 앱의 서비스를 바인딩할 때 bindService() 바인딩된 서비스에 자체 백그라운드 활동 시작 권한을 부여하려면 보이는 앱이 이제 옵트인해야 합니다. BIND_ALLOW_ACTIVITY_STARTS 옵트인하려면 메서드 를 호출할 때 앱에서 플래그를 포함해야 합니다 bindService().
이러한 변경 사항은 악성 앱이 API를 남용하여 백그라운드에서 파괴적인 활동을 시작하는 것을 방지하여 사용자를 보호하기 위해 기존 제한 세트를 확장합니다.
업데이트된 비 SDK 제한 사항
Android 14에는 Android 개발자와의 협업 및 최신 내부 테스트를 기반으로 제한된 비 SDK 인터페이스의 업데이트된 목록이 포함되어 있습니다. 가능할 때마다 우리는 비 SDK 인터페이스를 제한하기 전에 공개 대안을 사용할 수 있는지 확인합니다.
앱이 Android 14를 대상으로 하지 않는 경우 이러한 변경 사항 중 일부는 즉시 적용되지 않을 수 있습니다. 그러나 현재 일부 비 SDK 인터페이스( 앱의 대상 API 수준에 따라 다름 )를 사용할 수 있지만 비 SDK 메서드 또는 필드를 사용하면 항상 앱이 중단될 위험이 높습니다.
앱에서 비 SDK 인터페이스를 사용하는지 확실하지 않은 경우 앱을 테스트하여 확인할 수 있습니다. 앱이 비 SDK 인터페이스에 의존하는 경우 SDK 대안으로의 마이그레이션 계획을 시작해야 합니다. 그럼에도 불구하고 일부 앱에는 비 SDK 인터페이스를 사용하는 유효한 사용 사례가 있음을 이해합니다. 앱의 기능에 대해 비 SDK 인터페이스를 사용하는 것 외에 다른 방법을 찾을 수 없는 경우 새 공개 API를 요청 해야 합니다 .
이 Android 릴리스의 변경사항에 대해 자세히 알아보려면 Android 14의 비 SDK 인터페이스 제한 업데이트를 참조하세요 . 일반적으로 비 SDK 인터페이스에 대해 자세히 알아보려면 비 SDK 인터페이스에 대한 제한 사항을 참조하십시오 .
모든 앱에 대한 적용 사항(Android 버전 모든 대상)
일정 정확한 알람은 기본적으로 거부됩니다.
정확한 알람은 사용자가 의도한 알림 또는 정확한 시간에 발생해야 하는 작업을 위한 것입니다. Android 14부터 Android 13 이상을 대상으로 새로 설치된 대부분의 앱에 SCHEDULE_EXACT_ALARM 권한이 더 이상 사전 부여되지 않습니다 . 권한은 기본적으로 거부됩니다.
정확한 알람 예약 권한에 대한 변경 사항 에 대해 자세히 알아보십시오 .
컨텍스트에 등록된 브로드캐스트는 앱이 캐시되는 동안 대기합니다.
Android 14에서 시스템은 앱이 캐시된 상태 에 있는 동안 컨텍스트에 등록된 브로드캐스트를 대기열에 배치할 수 있습니다 . 이는 Android 12(API 레벨 31)에서 비동기 바인더 트랜잭션을 위해 도입한 대기열 동작과 유사합니다. 매니페스트 선언 브로드캐스트는 대기열에 추가되지 않으며 브로드캐스트 전달을 위해 앱이 캐시된 상태에서 제거됩니다.
앱이 포그라운드로 돌아가는 것과 같이 캐시된 상태를 벗어나면 시스템은 대기 중인 모든 브로드캐스트를 전달합니다. 특정 브로드캐스트의 여러 인스턴스를 하나의 브로드캐스트로 병합할 수 있습니다.
앱은 자신의 백그라운드 프로세스만 종료할 수 있습니다.
Android 14부터 앱이 를 호출하면 killBackgroundProcesses()API가 자체 앱의 백그라운드 프로세스만 종료할 수 있습니다.
다른 앱의 패키지 이름을 전달하면 이 메서드는 해당 앱의 백그라운드 프로세스에 영향을 미치지 않으며 Logcat에 다음 메시지가 나타납니다.
Invalid packageName: com.example.anotherapp
앱은 killBackgroundProcesses()API를 사용하거나 이전 OS 버전에서도 다른 앱의 프로세스 수명 주기에 영향을 미치려고 시도해서는 안 됩니다. Android는 캐시된 앱을 백그라운드에 유지하고 시스템에 메모리가 필요할 때 자동으로 종료하도록 설계되었습니다. 앱이 다른 앱을 불필요하게 종료하는 경우 나중에 해당 앱을 완전히 다시 시작해야 하므로 시스템 성능이 저하되고 배터리 소모가 증가할 수 있습니다. 이렇게 하면 기존 캐시된 앱을 다시 시작하는 것보다 훨씬 더 많은 리소스가 필요합니다.
참고: 타사 애플리케이션이 Android 기기의 메모리, 전력 또는 열 동작을 개선하는 것은 불가능합니다. 앱이 오해의 소지가 있는 주장에 관한 Google Play 정책을 준수하는지 확인해야 합니다 .
보안
설치 가능한 최소 대상 API 레벨
Android 14부터 targetSdkVersion23 미만의 앱은 설치할 수 없습니다. 이러한 최소 대상 API 수준 요구 사항을 충족하도록 앱을 요구하면 사용자의 보안 및 개인 정보 보호가 향상됩니다.
맬웨어는 최신 Android 버전에 도입된 보안 및 개인 정보 보호를 우회하기 위해 이전 API 수준을 대상으로 하는 경우가 많습니다. 예를 들어 일부 맬웨어 앱은 targetSdkVersionAndroid 6.0 Marshmallow(API 레벨 23)에서 2015년에 도입한 런타임 권한 모델의 영향을 받지 않기 위해 22를 사용합니다. 이 Android 14 변경으로 인해 맬웨어가 보안 및 개인 정보 보호 개선을 피하는 것이 더 어려워졌습니다. 더 낮은 API 수준을 대상으로 하는 앱을 설치하려고 하면 설치에 실패하고 Logcat에 다음 메시지가 표시됩니다.
INSTALL_FAILED_DEPRECATED_SDK_VERSION: App package must target at least SDK version 23, but found 7
Android 14로 업그레이드하는 기기에서는 targetSdkVersion23 미만인 모든 앱이 설치된 상태로 유지됩니다.
이전 API 수준을 대상으로 하는 앱을 테스트해야 하는 경우 다음 ADB 명령을 사용합니다.
adb install --bypass-low-target-sdk-block FILENAME.apk
미디어 소유자 패키지 이름이 수정될 수 있음
미디어 스토어는 특정 미디어 파일을 저장한 앱을OWNER_PACKAGE_NAME 나타내는 열에 대한 쿼리를 지원합니다 . Android 14부터 다음 조건 중 하나 이상이 참이 아닌 한 이 값이 수정됩니다.
- 미디어 파일을 저장한 앱에는 다른 앱에 항상 표시되는 패키지 이름이 있습니다.
- 미디어 스토어를 쿼리하는 앱이 QUERY_ALL_PACKAGES 권한을 요청합니다.주의: 권한 사용에는 Google Play 정책이 적용QUERY_ALL_PACKAGES 됩니다 .
Android에서 개인 정보 보호를 위해 패키지 가시성을 필터링하는 방법에 대해 자세히 알아보세요 .
사용자 경험
사용자가 닫을 수 없는 알림을 경험하는 방식 변경
앱에서 사용자에게 닫을 수 없는 포그라운드 알림을 표시하는 경우 Android 14는 사용자가 이러한 알림을 닫을 수 있도록 동작을 변경했습니다.
이 변경 사항은 사용자 가 또는 를 Notification.FLAG_ONGOING_EVENT통해 설정하여 포그라운드 알림을 해제하지 못하도록 하는 앱에 적용됩니다 . 사용자가 이러한 알림을 실제로 해제할 수 있도록 의 동작이 변경되었습니다.Notification.Builder#setOngoing(true)NotificationCompat.Builder#setOngoing(true)FLAG_ONGOING_EVENT
이러한 종류의 알림은 다음 조건에서 여전히 닫을 수 없습니다.
- 전화가 잠겨 있을 때
- 사용자가 모든 알림 지우기 작업을 선택하는 경우(우발적인 해제에 도움이 됨)
또한 이 새로운 동작은 다음 사용 사례에서 해제할 수 없는 알림에 적용되지 않습니다.
- 다음을 사용하여 생성된 알림MediaStyle
- 보안 및 개인 정보 보호 사례로 사용을 제한하는 정책
- 장치 정책 컨트롤러(DPC) 및 기업용 지원 패키지
사진 및 비디오에 대한 부분 액세스 권한 부여
참고: 앱에서 이미 사진 선택기를 사용하는 경우 이 변경을 지원하기 위해 조치를 취할 필요가 없습니다.
Android 14에서 사용자는 앱이 Android 13(API 레벨 33)에 도입된 시각적 미디어 권한을 요청할 때 자신의 사진 및 동영상에 대한 부분 액세스 권한을 부여할 수 있습니다. READ_MEDIA_IMAGES또는 READ_MEDIA_VIDEO.
새 대화 상자에는 다음 권한 선택 항목이 표시됩니다.
- 사진 및 동영상 선택: Android 14의 새로운 기능입니다. 사용자는 앱에서 사용할 특정 사진 및 동영상을 선택합니다.
- 모두 허용 : 사용자는 장치의 모든 사진 및 비디오에 대한 전체 라이브러리 액세스 권한을 부여합니다.
- 허용하지 않음 : 사용자가 모든 액세스를 거부합니다.
앱에서 이 변경 사항을 보다 원활하게 처리하려면 새 READ_MEDIA_VISUAL_USER_SELECTED권한을 선언하는 것이 좋습니다. 사용자가 미디어 라이브러리에 부분 권한을 부여하는 사례를 지원하는 방법에 대해 자세히 알아보세요 .
접근성
200%까지 비선형 글꼴 크기 조정
Android 14부터 시스템은 최대 200%의 글꼴 크기 조정을 지원하여 저시력 사용자에게 WCAG(웹 콘텐츠 접근성 지침) 에 부합하는 추가 접근성 옵션을 제공합니다 .
이미 조정된 픽셀(sp) 단위를 사용하여 텍스트 크기를 정의한 경우 이 변경 사항이 앱에 큰 영향을 미치지 않을 것입니다. 그러나 앱이 유용성에 영향을 주지 않고 더 큰 글꼴 크기를 수용할 수 있도록 최대 글꼴 크기를 활성화(200%)한 상태에서 UI 테스트를 수행 해야 합니다.
[reference]
- https://developer.android.com/about/versions/14
- https://developer.android.com/about/versions/14/behavior-changes-all
- https://developer.android.com/about/versions/14/behavior-changes-14