API Level: 개념, API 버전 및 targetSdk

저자: IT Sectr 게시일: 2026-02-08 읽는 시간: 12 분

API Level Android는 Android 플랫폼의 특정 릴리스에 고유하게 대응하는 정수 식별자입니다. 각 OS 버전에는 고유한 번호가 있습니다: Android 14 = API 34, Android 15 = API 35. 개발자는 build.gradle에서 minSdkVersion, targetSdkVersion, compileSdkVersion의 세 가지 매개변수를 관리하여 호환성과 새로운 기능에 대한 액세스를 제어합니다. Android Developers에 따르면 올바른 API Level 선택은 보안 및 사용자 범위에 중요합니다.

핵심 요점

  • API Level — Android API 버전의 정수 식별자, API 1(Android 1.0)부터 API 36(Android 16)까지
  • minSdkVersion — 앱 설치를 위한 최소 Android 버전, 사용자 범위 결정
  • targetSdkVersion — 앱이 테스트된 버전; 해당 버전의 동작 변경 포함
  • compileSdkVersion — 컴파일에 사용되는 SDK 버전; targetSdk >= 이어야 하며 새 API에 대한 액세스 제공
  • Google Play는 targetSdkVersion이 현재 API Level로부터 1년을 초과하지 않아야 함

API Level Android란?

API Level Android는 Android Framework API의 각 공개 릴리스에 할당되는 정수 식별자입니다. 첫 번째 릴리스 Android 1.0은 API Level 1, Android 1.5는 API Level 3, Android 2.2는 API Level 8, Android 4.0은 API Level 14, Android 8.0은 API Level 26, Android 12는 API Level 31, Android 14는 API Level 34, Android 15는 API Level 35, Android 16(2025)은 API Level 36입니다. 각 새 API Level은 새 클래스, 메서드, 상수, 권한을 추가하고 기존의 동작을 변경할 수 있습니다.

API Level은 각 릴리스마다 엄격하게 1씩 증가하지 않습니다. 예를 들어 Android 4.4W(Wear)는 API 20이고 Android 5.0은 API 21입니다. 차이는 내부 반복 및 Wear OS 장치와 관련이 있습니다. 개발자에게 중요한 것은 버전 이름(KitKat, Lollipop, Tiramisu)이 아니라 API Level입니다. 호환성 검사에 코드에서 사용되는 것이 바로 API Level입니다.

API Level의 주요 목적은 하위 호환성입니다. API 34에 대해 컴파일된 앱은 API 34 이하의 장치에서 실행될 수 있습니다(확인 없이 새 API를 사용하지 않는 경우). Android Runtime(ART)은 시스템 수준에서 API 호출을 확인하고 앱의 targetSdkVersion에 따라 동작 변경을 적용합니다.

Android가 API Level을 처리하는 방법

앱 설치 시 PackageManager는 장치의 API Level이 AndroidManifest.xml의 minSdkVersion >= 인지 확인합니다. 조건이 충족되지 않으면 설치가 "App not installed" 메시지와 함께 차단됩니다. 실행 중에 Android Runtime은 더 높은 API Level이 필요한 API 호출을 모니터링하고 현재 버전에 메서드가 없으면 NoSuchMethodError 또는 UnsatisfiedLinkError를 생성합니다.

구성 요소API Level 처리 역할
PackageManager설치 중 minSdkVersion 확인
Android Runtime(ART)런타임에 API 호환성 검사 수행
Google Play Store장치 API Level별로 앱 필터링
SDK Manager필요한 API Level에서 컴파일을 위한 플랫폼 다운로드
lintminSdk 이상의 API 사용에 대해 경고하는 정적 분석기

minSdk, targetSdk, compileSdk: 각 매개변수의 차이점과 역할

build.gradle 파일(Module: app)에서 개발자는 세 가지 API Level 매개변수(minSdkVersion, targetSdkVersion, compileSdkVersion)를 지정합니다. 이들을 혼동하는 것은 초보 Android 개발자의 가장 흔한 실수 중 하나입니다. 각 매개변수는 호환성의 다른 측면을 담당하며 값이 일관되어야 합니다.

minSdkVersion

minSdkVersion은 앱을 설치하고 실행할 수 있는 최소 API Level입니다. minSdk보다 낮은 API Level의 장치는 Google Play에서 앱을 볼 수 없고 설치할 수 없습니다. 값은 대상 사용자에 따라 선택됩니다: minSdk 21(Android 5.0)은 장치의 97%를 커버, minSdk 26(Android 8.0)은 약 85%, minSdk 31(Android 12)은 약 55%(Android Studio Distribution Dashboard, 2026 데이터). minSdk가 낮을수록 범위는 넓어지지만 더 많은 하위 호환성 코드가 필요합니다.

targetSdkVersion

targetSdkVersion은 앱이 테스트된 API Level입니다. Android는 targetSdk를 사용하여 동작 변경을 적용합니다: 앱이 targetSdk 33을 지정하면 시스템은 API 33에서 도입된 모든 동작 변경을 활성화합니다. targetSdk가 31이면 시스템은 API 32-33 변경을 적용하지 않고 이전 동작과의 호환성을 유지합니다. 이것은 보안에 가장 중요한 매개변수입니다: Google Play는 targetSdk가 현재 API Level로부터 1년을 초과하지 않아야 합니다.

compileSdkVersion

compileSdkVersion은 코드가 컴파일되는 Android SDK 버전입니다. 컴파일 시간에 어떤 API를 사용할 수 있는지 결정합니다. compileSdk는 targetSdk >= 이어야 하며 이상적으로는 최신 안정적인 API Level과 같아야 합니다. compileSdk를 높여도 런타임 동작에는 영향을 미치지 않습니다. 컴파일러가 새 API를 사용할 수 있게 됩니다. compileSdk를 높인 후에는 더 이상 사용되지 않는 API와 새로운 권한 요구사항에 대해 코드를 확인해야 합니다.

kotlin
// build.gradle.kts — API Level 설정 예제
plugins {
    id("com.android.application") version "8.7.0"
    id("org.jetbrains.kotlin.android") version "2.1.0"
}

android {
    namespace = "com.example.myapp"
    compileSdk = 36  // Android 16

    defaultConfig {
        applicationId = "com.example.myapp"
        minSdk = 26      // Android 8.0
        targetSdk = 36    // Android 16
        versionCode = 1
        versionName = "1.0.0"
    }

    buildTypes {
        release {
            isMinifyEnabled = true
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }

    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
    }

    kotlinOptions {
        jvmTarget = "17"
    }
}

dependencies {
    implementation("androidx.core:core-ktx:1.15.0")
    implementation("androidx.appcompat:appcompat:1.7.0")
    implementation("androidx.activity:activity-ktx:1.9.3")
}

build.gradle.kts 예제에서 compileSdk = 36(작성 시점 최신), targetSdk = 36, minSdk = 26(Android 8.0)입니다. compileSdk 36은 모든 Android 16 API에 대한 액세스를 제공합니다. targetSdk 36은 모든 Android 16 동작 변경을 활성화합니다. minSdk 26은 ~85%의 장치를 커버합니다. AndroidX Activity KTX와 AppCompat은 프래그먼트와 테마에 대한 하위 호환성을 제공합니다.

AndroidManifest.xml

minSdk 및 targetSdk 매개변수는 AndroidManifest.xml에서도 지정할 수 있지만 최신 프로젝트는 build.gradle을 사용합니다. Gradle의 값이 매니페스트를 재정의합니다. 매니페스트에서는 Gradle 빌드 구성을 사용하지 않는 라이브러리 및 모듈에 대해 을 지정하는 것이 유용할 수 있습니다.

동작 변경: targetSdk가 앱 동작에 미치는 영향

동작 변경은 targetSdk가 특정 API Level 이상인 앱에만 적용되는 Android 시스템 작동 방식의 수정입니다. 각 새 Android 릴리스는 업데이트되지 않은 경우 기존 앱을 손상시킬 수 있는 동작 변경을 도입합니다. 이것은 Android의 주요 보안 메커니즘입니다: 이전 앱은 이전처럼 계속 작동하고 새 앱은 현재 규칙을 따릅니다.

버전별 주요 동작 변경

Android 10(API 29) — Scoped Storage: targetSdk 29+ 앱은 공유 파일 시스템에 직접 액세스할 수 없으며 MediaStore, SAF 또는 자체 저장소를 통해서만 가능합니다. Android 11(API 30) — Package Visibility: 패키지 필터, 앱은 상호 작용하는 설치된 패키지만 볼 수 있습니다. Android 12(API 31) — Foreground Service Notification: 모든 포그라운드 서비스는 시작 후 10초 이내에 알림을 표시해야 합니다. Android 13(API 33) — POST_NOTIFICATIONS: 푸시 알림을 위한 런타임 권한. Android 14(API 34) — Foreground Service Types: 매니페스트에서 포그라운드 서비스 유형의 필수 선언.

kotlin
// Android 13(API 33) 동작 변경 처리: POST_NOTIFICATIONS
import android.Manifest
import android.content.pm.PackageManager
import android.os.Build
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat

class NotificationHelper {

    fun requestNotificationPermission(activity: MainActivity) {
        // POST_NOTIFICATIONS 권한은 API 33+에서만 작동
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
            return  // API 33 미만에서는 권한이 필요하지 않음
        }

        when {
            ContextCompat.checkSelfPermission(
                activity,
                Manifest.permission.POST_NOTIFICATIONS
            ) == PackageManager.PERMISSION_GRANTED -> {
                // 권한이 이미 부여됨, 알림을 보낼 수 있음
                showNotification(activity)
            }

            activity.shouldShowRequestPermissionRationale(
                Manifest.permission.POST_NOTIFICATIONS
            ) -> {
                // 권한이 필요한 이유 설명 표시
                activity.showRationale()
            }

            else -> {
                // 권한 요청
                activity.requestPermissionLauncher.launch(
                    Manifest.permission.POST_NOTIFICATIONS
                )
            }
        }
    }

    private fun showNotification(context: Context) {
        // 알림 생성 및 표시
        val notification = android.app.Notification.Builder(context, "default_channel")
            .setSmallIcon(android.R.drawable.ic_dialog_info)
            .setContentTitle("알림")
            .setContentText("새 메시지")
            .build()
        val manager = context.getSystemService(Context.NOTIFICATION_SERVICE)
            as android.app.NotificationManager
        manager.notify(1, notification)
    }
}

// Activity에 requestPermissionLauncher 등록
class MainActivity : ComponentActivity() {
    val requestPermissionLauncher = registerForActivityResult(
        ActivityResultContracts.RequestPermission()
    ) { isGranted: Boolean ->
        if (isGranted) {
            // 권한이 부여됨
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}

Kotlin에서 POST_NOTIFICATIONS 처리 예제: Build.VERSION.SDK_INT >= TIRAMISU 확인, ActivityResultContracts.RequestPermission을 통해 런타임 권한 요청, 콜백에서 결과 처리. 이 권한이 없으면 targetSdk 33+ 앱은 푸시 알림을 표시할 수 없습니다. API 33 미만에서는 권한이 필요하지 않습니다. 확인 코드가 사용 불가능한 API 호출을 방지합니다.

Scoped Storage(Android 10+)

Scoped Storage는 가장 중요한 동작 변경 중 하나입니다. API 29(targetSdk 29+)부터 앱은 Pictures, Downloads, Music, Documents 디렉토리에 직접 파일 액세스할 수 없습니다. 대신 미디어에는 MediaStore, 임의 파일에는 SAF(Storage Access Framework), 자체 저장소에는 getExternalFilesDir()이 사용됩니다. 예외는 MANAGE_EXTERNAL_STORAGE 권한이 있는 앱으로 Google Play 승인이 필요합니다.

API Level 및 targetSdk에 대한 Google Play 요구사항

Google Play는 앱 게시를 위해 targetSdkVersion의 필수 요구사항을 설정합니다. 2024년 8월부터 Google Play는 targetSdkVersion >= API 33(Android 13)을 요구합니다. 매년 임계값이 상승합니다: 새 앱 및 업데이트는 현재 주요 API Level로부터 1년을 초과하지 않는 targetSdk를 지정해야 합니다. 요구사항 위반은 게시 차단 및 스토어에서 앱 제거로 이어집니다.

Google Play가 요구사항을 강화하는 이유

주된 이유는 보안입니다. 각 새 Android API Level은 공격 벡터를 차단하는 동작 변경을 도입합니다: Scoped Storage(API 29)는 파일 도난 방지, POST_NOTIFICATIONS(API 33)는 스팸 알림 보호, Foreground Service Types(API 34)는 숨겨진 백그라운드 서비스를 제한합니다. targetSdk가 낮은 앱은 이러한 보호를 받지 못하고 사용자에게 위협이 됩니다. Google Play는 최신 장치에서 오래된 앱을 허용할 수 없습니다.

요구사항 준수 확인

Google Play Console은 APK/AAB 업로드 시 targetSdkVersion을 확인합니다. targetSdk가 요구사항보다 낮으면 콘솔이 "Your app currently targets API level X and must target at least API level Y" 메시지와 함께 게시를 차단합니다. 개발자는 build.gradle을 업데이트하고, 앱을 재컴파일하고, 동작 변경을 테스트하고, 다시 업로드해야 합니다. AAB 형식은 모든 새 게시에 권장됩니다(2021년 8월부터 필수).

날짜최소 targetSdkAndroid 버전
2022년 8월31Android 12
2023년 8월33Android 13
2024년 8월33Android 13
2025년 8월34Android 14
2026년 8월(예정)35Android 15

코드에서 API Level 확인: Build.VERSION.SDK_INT

Build.VERSION.SDK_INT는 앱이 실행 중인 장치의 API Level을 포함하는 정적 정수 상수입니다. 런타임 Android 버전 확인을 위한 기본 도구입니다. Build.VERSION_CODES에는 각 API Level에 대한 명명된 상수가 포함됩니다: VERSION_CODES.TIRAMISU(33), VERSION_CODES.UPSIDE_DOWN_CAKE(34), VERSION_CODES.VANILLA_ICE_CREAM(35). if(SDK_INT >= VERSION_CODES.TIRAMISU)를 통한 비교가 표준 패턴입니다.

kotlin
// Android 코드에서 API Level 확인 예제
import android.os.Build
import android.os.Build.VERSION
import android.os.Build.VERSION_CODES
import android.graphics.drawable.AdaptiveIconDrawable

class ApiLevelHelper {

    // 1. 기본 API Level 확인
    fun isAtLeastTiramisu(): Boolean {
        return VERSION.SDK_INT >= VERSION_CODES.TIRAMISU  // 33
    }

    // 2. 확인이 포함된 적응형 API 호출
    fun getAdaptiveIcon(drawable: android.graphics.drawable.Drawable):
            android.graphics.drawable.Drawable? {
        // AdaptiveIconDrawable은 API 26(Android 8)에서만 사용 가능
        if (VERSION.SDK_INT >= VERSION_CODES.O) {
            return AdaptiveIconDrawable(drawable, null)
        }
        return drawable  // 이전 장치용 fallback
    }

    // 3. POST_NOTIFICATIONS 권한 확인(API 33+만 해당)
    fun canRequestNotificationPermission(): Boolean {
        return VERSION.SDK_INT >= VERSION_CODES.TIRAMISU
    }

    // 4. API Level별 이미지 제공자 선택
    fun getImagePickerProvider(): String {
        return when {
            VERSION.SDK_INT >= VERSION_CODES.UPSIDE_DOWN_CAKE -> {
                // API 34+는 PhotoPicker 사용
                "photo_picker"
            }
            VERSION.SDK_INT >= VERSION_CODES.KITKAT -> {
                // API 19+는 Intent ACTION_OPEN_DOCUMENT 사용
                "open_document"
            }
            else -> {
                // Legacy: ACTION_GET_CONTENT(모든 버전)
                "get_content"
            }
        }
    }

    // 5. @TargetApi를 통한 Java 스타일 확인(하위 호환성용)
    @Suppress("DEPRECATION")
    fun checkLegacyStorage(): Boolean {
        // Scoped Storage 동작은 SDK_INT가 아닌 targetSdk에 따라 다름
        return VERSION.SDK_INT < VERSION_CODES.Q  // Android 10
    }

    // 6. 분석을 위한 빌드 정보
    fun getDeviceApiInfo(): Map<String, Any> {
        return mapOf(
            "sdk_int" to VERSION.SDK_INT,
            "release" to VERSION.RELEASE,
            "codename" to VERSION.CODENAME,
            "incremental" to VERSION.INCREMENTAL,
            "preview_sdk" to VERSION.PREVIEW_SDK_INT
        )
    }
}

// 테스트
fun main() {
    val helper = ApiLevelHelper()
    println("API Level: ${VERSION.SDK_INT}")
    println("Is Tiramisu+: ${helper.isAtLeastTiramisu()}")
}

ApiLevelHelper 클래스는 모든 주요 API Level 확인 패턴을 보여줍니다: SDK_INT >= VERSION_CODES를 사용한 isAtLeastTiramisu, 이전 버전을 위한 fallback이 있는 getAdaptiveIcon, when 다중 분기를 사용한 getImagePickerProvider, 분석을 위한 getDeviceApiInfo. 핵심 규칙은 SDK_INT를 확인하지 않고 새 API를 호출하지 않는 것입니다. 그렇지 않으면 이전 장치에서 NoSuchMethodError로 앱이 충돌합니다.

ANT(Android New API)와 lint

Android Studio에는 minSdkVersion 이상의 API 사용에 대해 경고하는 정적 분석기 lint가 포함되어 있습니다. SDK_INT 확인 없이 메서드가 호출되면 lint가 오류로 강조 표시합니다: "Call requires API level 34(current min is 26)". 해결책: 메서드에 @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)를 추가하거나 SDK_INT의 if-확인. @TargetApi는 더 이상 사용되지 않는 어노테이션이며 @RequiresApi가 권장됩니다.

API Level과 Android 버전 대응 표

API Level 표는 개발자를 위한 참조 도구입니다. 장치의 API Level을 알면 Android 버전과 사용 가능한 기능을 확인할 수 있습니다. 표는 API Level 1(2008)부터 API Level 36(2025)까지의 모든 주요 Android 릴리스를 나열합니다. 코드명(Cupcake, Donut, Tiramisu, VanillaIceCream)은 Google 내부 및 VERSION_CODES에서 사용됩니다.

API LevelAndroid 버전코드명년도
11.02008
31.5Cupcake2009
82.2Froyo2010
144.0Ice Cream Sandwich2011
194.4KitKat2013
215.0Lollipop2014
236.0Marshmallow2015
268.0Oreo2017
289Pie2018
2910Quince Tart (10)2019
3011Red Velvet Cake2020
3112Snow Cone2021
3313Tiramisu2022
3414Upside Down Cake2023
3515Vanilla Ice Cream2024
3616Baklava2025

표: 동작 변경에 대한 임계 API Level

다음 표는 targetSdk를 높일 때 하위 호환성을 깨는 동작 변경을 도입하는 주요 API Level을 보여줍니다:

API Level동작 변경앱에 미치는 영향
29Scoped StoragePictures/Downloads/Music에 직접 파일 액세스 불가
30Package VisibilityqueryIntentActivities()가 상호 작용하는 패키지만 표시
31Foreground Service Notification10초 이내 필수 알림
33POST_NOTIFICATIONS알림을 위한 런타임 권한
34Foreground Service Types매니페스트에서 포그라운드 서비스 유형 선언
35Privacy Sandbox광고 식별자 제한

자주 묻는 질문

Android에서 API Level이란 무엇인가요?

API Level Android는 Android API 버전의 정수 식별자입니다. 각 릴리스에는 고유한 번호가 있습니다: Android 13 = API 33, Android 14 = API 34, Android 15 = API 35, Android 16 = API 36. 개발자는 build.gradle에서 minSdkVersion, targetSdkVersion, compileSdkVersion을 지정하여 호환성을 관리합니다. API Level은 사용 가능한 클래스, 메서드 및 동작 변경을 결정합니다.

minSdk와 targetSdk, compileSdk의 차이점은 무엇인가요?

minSdkVersion — 앱 설치를 위한 최소 Android 버전. targetSdkVersion — 앱이 테스트된 버전, 동작 변경 포함. compileSdkVersion — 코드 컴파일을 위한 SDK 버전. minSdk가 가장 낮고, targetSdk는 가능한 최신, compileSdk는 적어도 targetSdk 이상이어야 합니다. 세 가지 모두 build.gradle에서 지정됩니다.

targetSdk를 장치의 Android 버전보다 낮게 설정하면 어떻게 되나요?

targetSdkVersion이 장치의 API Level보다 낮으면 Android는 targetSdk 이후 도입된 동작 변경을 비활성화합니다. 예를 들어 Android 14(API 34)에서 targetSdk = 28인 경우 Scoped Storage, POST_NOTIFICATIONS, Foreground Service Types가 적용되지 않습니다. Google Play는 사용자 안전을 위해 targetSdkVersion이 현재 API Level로부터 1년을 초과하지 않아야 합니다.

장치의 API Level을 어떻게 확인하나요?

장치의 API Level은 상수 Build.VERSION.SDK_INT(예: Android 14의 경우 34)를 통해 사용할 수 있습니다. 비교를 위해 Build.VERSION_CODES의 명명된 상수를 사용하세요: if(SDK_INT >= VERSION_CODES.TIRAMISU). Build.VERSION.RELEASE는 버전 문자열("14")을 반환합니다. SDK_INT 값은 클래스 로드 시 캐시되며 모든 스레드에서 액세스할 수 있습니다.

Google Play는 왜 매년 새로운 targetSdk를 요구하나요?

Google Play는 보안 동작 변경을 구현하기 위해 매년 targetSdkVersion 요구사항을 높입니다. 각 새 API Level은 Scoped Storage, POST_NOTIFICATIONS, Privacy Sandbox 및 기타 보호 기능을 도입합니다. targetSdk가 낮은 앱은 이러한 보호를 우회하고 사용자에게 위험을 초래합니다. 이 요구사항은 스토어의 모든 앱이 현재 규칙에 따라 테스트되었음을 보장합니다.

요약

  • API Level — Android API 버전(1-36)의 정수 식별자, 앱 호환성 관리에 사용
  • minSdkVersion은 설치를 위한 최소 API Level 설정, targetSdkVersion — 동작 변경이 있는 버전, compileSdkVersion — 컴파일용 버전
  • 동작 변경(Scoped Storage, POST_NOTIFICATIONS, Foreground Service Types)은 targetSdk >= 해당 API Level인 경우에만 적용
  • Google Play는 targetSdk가 1년을 초과하지 않아야 하며, 그렇지 않으면 앱 게시를 차단
  • Build.VERSION.SDK_INT — fallback으로 새 API를 안전하게 호출하기 위한 장치 API Level의 런타임 확인
  • lint는 Android Studio에서 minSdk 이상의 API 사용에 대해 경고하고 메서드에 @RequiresApi를 권장
  • API 34+ 동작 변경에는 필수 포그라운드 서비스 유형이 포함, API 35+ — 광고 식별자 제한이 있는 Privacy Sandbox

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기