targetSdkVersion — アプリケーションがテストされ最適化されたAndroid API Levelです。このパラメーターはbuild.gradleで指定され、実行時にどの動作変更(behavioural changes)がアプリケーションに適用されるかを決定します。targetSdkVersionがデバイスのAPI Levelより低い場合、Androidは新しいバージョンで導入された動作変更を無効にし、古いアプリとの互換性を維持します。Android Developersによると、Google PlayはtargetSdkVersionが現在のAPI Levelから1年以内であることを要求しています。
重要ポイント
targetSdkVersionはbuild.gradleの整数パラメーターで、アプリがテストされたAPI Levelを宣言します。Androidシステムはこのパラメーターを使用して、実行時にアプリにどの動作変更を適用するかを決定します。targetSdkVersion = 33の場合、AndroidはAPI 33までに導入されたすべての動作変更を適用しますが、API 34+の変更は適用しません。targetSdkVersion = 34の場合はAPI 34までの変更が適用され、以降同様です。
targetSdkVersionとminSdkVersionの主な違いは動作メカニズムです。minSdkはインストール時に一度チェックされ、条件を満たさないとインストールをブロックします。targetSdkVersionは、アプリが実行されているAndroidバージョンに関係なく、各デバイス上のシステムの実行時動作に影響します。targetSdk 31の同じアプリでも、Android 13、14、15では動作が異なります。これは31を超える動作変更が無効になっているためです。
targetSdkVersionメカニズムはAndroidに組み込まれた下位互換性ツールです。これがないと、OSアップデートのたびに何千もの古いアプリが壊れてしまいます。GoogleはこのメカニズムをAndroid 2.1(API Level 7)で導入し、それ以来、既存のアプリケーションを壊すことなく新しいセキュリティ、プライバシー、リソース管理ルールを導入する標準的な方法として使用しています。
// build.gradle.kts — defaultConfigのtargetSdkVersion
android {
namespace = "com.example.myapp"
compileSdk = 36
defaultConfig {
applicationId = "com.example.myapp"
minSdk = 26
targetSdk = 36 // Android 16でテスト済み
versionCode = 1
versionName = "1.0.0"
}
}
// コードで現在のtargetSdkを確認
fun isUsingScopedStorage(): Boolean {
// Context.getApplicationInfo().targetSdkVersionにアプリのtargetSdkが含まれる
return context.applicationInfo.targetSdkVersion >= VERSION_CODES.Q
}この例では、targetSdk = 36によりAndroid 16のすべての動作変更が有効になります。コードはcontext.applicationInfo.targetSdkVersionを介してtargetSdkVersionをチェックします。これにより、どの互換モードが有効かを動的に判断できます。このヘルパー関数は、呼び出し元アプリケーションのtargetSdkに適応する必要があるライブラリに役立ちます。
動作変更(behavioural changes)は、targetSdkVersion >= 特定のAPI Levelのアプリにのみ適用されるAndroidシステム動作の変更です。新しいメジャーAndroidリリースごとに動作変更が導入され、アプリがtargetSdkを更新しない場合、これらの変更は有効になりません。このメカニズムにより、開発者は新しいOSリリースと同期するのではなく、自分のペースでアプリを更新できます。
Scoped Storage(API 29)は最も重要な動作変更の1つです。targetSdk 29+のアプリは、共有ディレクトリ(Pictures、Downloads、Music、Documents)に直接ファイルアクセスできません。代わりに、マルチメディアにはMediaStore、任意のファイルにはSAF(Storage Access Framework)、プライベートストレージにはgetExternalFilesDir()が使用されます。targetSdk 28以下の古いアプリはレガシーのFull Storage Accessで引き続き動作しますが、これはセキュリティリスクを生み出します。
POST_NOTIFICATIONS(API 33)は通知送信のための実行時権限です。targetSdk 33+のアプリは、標準ダイアログを介してユーザーにManifest.permission.POST_NOTIFICATIONS権限を要求する必要があります。権限が付与されない場合、NotificationManager.silent()はユーザーに通知を表示しません。Android 13+でこの権限がないと、プッシュ通知やローカル通知が単に表示されず、ユーザーエンゲージメントが大幅に低下する可能性があります。
| API Level | 動作変更 | 更新時の必要な対応 |
|---|---|---|
| 29 | Scoped Storage | サンドボックス外のファイルはMediaStoreとSAFに移行 |
| 30 | Package Visibility | パッケージ連携のためマニフェストに<queries>を追加 |
| 31 | Foreground Service Notification | サービス開始後10秒以内に通知を表示 |
| 33 | POST_NOTIFICATIONS | 通知送信の実行時権限リクエスト |
| 34 | Foreground Service Types | マニフェストでフォアグラウンドサービスタイプを宣言 |
| 35 | Privacy Sandbox | 広告識別子(Advertising ID)の制限 |
targetSdkVersionの値はADBで取得できます:adb shell dumpsys package com.example.myapp | grep targetSdkコマンドでtargetSdk=34と表示されます。コードではcontext.getApplicationInfo().targetSdkVersionが整数を返します。分析のためには、各セッションでどの動作変更が実際にアクティブかを理解するために、targetSdkをandroid.os.Build.VERSION.SDK_INTと一緒にログに記録すると便利です。
Google Playは公開されるすべてのアプリにtargetSdkVersionの必須要件を設定しています。2024年8月以降、最小targetSdk = 33(Android 13)です。2025年8月以降はtargetSdk = 34です。2026年8月以降、GoogleはtargetSdk = 35(Android 15)を要求すると予想されています。新しいアプリと既存アプリのアップデートはこれらの要件に準拠する必要があり、そうでなければコンソールが公開をブロックします。これはGoogle Playのポリシーであり、Android Runtimeの制限ではありません。targetSdk 34のアプリはAndroid 16で実行できますが、Play Storeには公開できません。
Android App Bundle(AAB)は2021年8月以降、必須の公開形式です。APKはGoogle Playで受け入れられなくなりました(150 MBを超えるアプリといくつかのレガシープロジェクトを除く)。AAB形式により、Googleは各API Levelと画面密度に最適化されたAPKを生成でき、ダウンロードサイズを15〜30%削減できます。targetSdkを確認するために、Google PlayはAABマニフェストを分析し、準拠していない場合は最小必要値とともにエラーを発行します。
| 期間 | 最小targetSdk | Androidバージョン | 備考 |
|---|---|---|---|
| 2024年8月 | 33 | Android 13 | Tiramisu — POST_NOTIFICATIONS必須 |
| 2025年8月 | 34 | Android 14 | Upside Down Cake — フォアグラウンドサービスタイプ |
| 2026年8月 | 35 | Android 15 | Vanilla Ice Cream — Privacy Sandbox |
| 2027年8月(計画) | 36 | Android 16 | Baklava — T+ |
Google Play Consoleは、新しいAABをアップロードするときだけでなく、既存のアプリを更新するときにもtargetSdkVersionをチェックします。アプリのtargetSdkが33で、Googleが最小しきい値を34に引き上げた場合、targetSdkを引き上げるまでアップデートをリリースできません。長期間更新されていないアプリは、Google Playによって自動的に公開停止(unpublish)される場合があります。
targetSdkVersionの更新は、build.gradleの数値を変更するだけではありません。コードを事前に準備しないと、各動作変更が既存の機能を壊す可能性があります。特にアプリが大きく、多くのシステムAPIを使用している場合は、Google Playの期限の3〜6ヶ月前に準備を開始することをお勧めします。
ステップバイステップのプロセス:ステップ1 — Android Developersのドキュメント(「Behavioural Changes by API Level」ページ)で新しいAPI Levelの動作変更を調査します。ステップ2 — targetSdk-updateブランチを作成し、targetSdkを新しい値に変更します。ステップ3 — 新しいAPI Levelのエミュレーターまたはデバイスでアプリを実行し、変更に関連するすべての機能を確認します。ステップ4 — エラーを修正します:権限を追加し、ファイル処理を変更し、マニフェストを更新します。
ステップ5 — 古いデバイスでテストします。targetSdkを引き上げても、新しいtargetSdkより低いAPI Levelのデバイスには影響しませんが、動作変更はAPI Level >= targetSdkのすべてのデバイスに適用されます。targetSdkを33から34に引き上げた場合、API 34+のデバイスではAPI 34の動作変更が有効になります。API 33のデバイスでは何も変わりません。
// targetSdk 35の準備:Privacy Sandbox
import android.os.Build
import android.os.Build.VERSION_CODES
import com.google.android.gms.ads.identifier.AdvertisingIdClient
class AdsManager {
fun getAdvertisingId(context: android.content.Context): String? {
// Privacy SandboxはAPI 35からAdvertising IDを制限する
if (Build.VERSION.SDK_INT >= VERSION_CODES.VANILLA_ICE_CREAM) {
// API 35+ — 識別子が利用不可、MeasurementManagerを使用
return null
}
return try {
val adInfo = AdvertisingIdClient.getAdvertisingIdInfo(context)
adInfo.getId()
} catch (e: Exception) {
null
}
}
// 確認:どの動作変更がアクティブか
fun getActiveChanges(context: android.content.Context): List<String> {
val sdkInt = Build.VERSION.SDK_INT
val targetSdk = context.applicationInfo.targetSdkVersion
return buildList {
if (sdkInt >= VERSION_CODES.Q && targetSdk >= VERSION_CODES.Q)
add("ScopedStorage")
if (sdkInt >= VERSION_CODES.TIRAMISU && targetSdk >= VERSION_CODES.TIRAMISU)
add("PostNotifications")
if (sdkInt >= VERSION_CODES.UPSIDE_DOWN_CAKE && targetSdk >= VERSION_CODES.UPSIDE_DOWN_CAKE)
add("FgsTypes")
}
}
}AdsManagerクラスはPrivacy Sandbox(API 35)への準備を示しています。Advertising IDはAPI 35からtargetSdk 35+で利用できなくなります。getActiveChanges関数は動作変更をチェックする正しいパターンを示しています:デバイスのSDK_INTとアプリのtargetSdkの両方をチェックする必要があります。両方の条件が一致した場合のみ、変更が実際にアクティブになります。
Android 15(API 35、Vanilla Ice Cream)は、targetSdkを35に更新する際に開発者が考慮すべきいくつかの重要な動作変更を導入しています。1つ目 — Privacy Sandbox for Android。これはAdvertising IDをよりプライベートなAPIに置き換えるGoogleのイニシアチブです:Topics API(ユーザーの興味)、Protected Audience(リターゲティング)、Attribution Reporting(コンバージョン)。API 35以降、Advertising IDは安定した識別子ではなくなり、null値を返す可能性があります。
2つ目の変更 — Foreground Service Types(API 34、API 35でも継続)。API 34以降、targetSdk 34+のすべてのアプリはマニフェストでフォアグラウンドサービスタイプを指定する必要があります:dataSync、systemExempted、shortService、location、mediaPlaybackなど。これがないと、システムはForegroundServiceTypeNotAllowedExceptionをスローします。API 35では、新しいhealthタイプが追加され、既存のタイプの検証が強化されました。すべてのフォアグラウンドサービスを見直す必要があります。
3つ目の変更 — SCHEDULE_EXACT_ALARMの制限。API 35以降、targetSdk 35+のアプリは明示的なユーザー許可なしにSCHEDULE_EXACT_ALARMを使用できません。システムがダイアログを表示し、ユーザーが正確なスケジューリングを承認する必要があります。アラームやタイマーの場合、UXの追加ステップを意味します。代替案としては、10分のバッファを持つ不正確なアラームを使用することです。
// Android 15(API 35):SCHEDULE_EXACT_ALARMの確認
import android.app.AlarmManager
import android.os.Build
import android.provider.Settings
class AlarmScheduler {
fun canScheduleExactAlarms(context: android.content.Context): Boolean {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
// API 35+:ユーザー権限が必要
val alarmManager = context.getSystemService(
android.content.Context.ALARM_SERVICE
) as AlarmManager
return alarmManager.canScheduleExactAlarms()
}
// API 35未満 — 権限なしで正確なアラームが利用可能
return true
}
fun requestExactAlarmPermission(activity: android.app.Activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
val intent = android.content.Intent(
Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM
).apply {
data = android.net.Uri.fromParts(
"package", activity.packageName, null
)
}
activity.startActivity(intent)
}
}
}Privacy Sandboxとアラーム制限は、API 35の最も重要な2つの動作変更です。広告SDKはTopics APIとAttribution Reportingに移行する必要があります。アラームやリマインダーがあるアプリの場合は、許可ダイアログのUX適応が必要です。これらの変更を無視すると、Android 15での実行時クラッシュや広告収益の喪失につながります。
targetSdkVersionとcompileSdkVersionの違いは、Android開発者の間で最も一般的な混乱の原因の1つです。compileSdkVersionはコードがコンパイルされるSDKのバージョンです。コンパイル時にどのAPIが利用可能かを決定しますが、実行時動作には影響しません。targetSdkVersionはアプリがテストされるバージョンであり、実行時にどの動作変更が適用されるかを決定します。compileSdkはtargetSdk以上である必要があり、そうあるべきです。
ルールはシンプルです:compileSdk >= targetSdk >= minSdk。compileSdkは通常、最新の安定したAPI Level(2026年では36)と等しいです。targetSdkはテストしたバージョンの中で可能な限り高くする必要があります。minSdkは最大のリーチのために可能な限り低くする必要があります。compileSdkを上げても動作変更のテストは不要です — コンパイラが新しいAPIにアクセスできるようになるだけです。targetSdkを上げるには、すべての動作変更の完全なテストサイクルが必要です。
| パラメーター | 作用時期 | 影響 | 他より高くできるか |
|---|---|---|---|
| compileSdkVersion | コンパイル時 | コードのAPI利用可能性 | はい、常にtargetSdkより高い |
| targetSdkVersion | 実行時 | 動作変更 | はい、ただしcompileSdkより低い |
| minSdkVersion | インストール時 | デバイスの互換性 | いいえ、常に最も低い |
実際には:Android 16(API 36)の新しいAPIを使用したいが、API 36の動作変更をまだテストしていない場合は、compileSdk = 36、targetSdk = 35を設定します。コードは新しいAPIでコンパイルされますが、API 36の動作変更は適用されません。すべての変更をテストしたら、targetSdkを36に引き上げます。
よくある質問
targetSdkVersionはアプリがテストされるAPI Levelです。Androidはそれを使用して動作変更(そのバージョンで導入された動作の変更)を適用します。targetSdkがデバイスのAPI Levelより低い場合、動作変更は適用されません。Google Playは新しいバージョンとアップデートの公開のために、targetSdkが現在のAPI Levelから1年以内であることを要求します。
targetSdkVersionは実行時動作に影響します:特定のAPI Levelの動作変更を有効にします。compileSdkVersionはコンパイルのみに影響します:コンパイラが利用できるAPIを決定します。compileSdkはtargetSdkより高くできますが、その逆はできません。compileSdkを上げてもテストは不要です;targetSdkを上げるにはすべての動作変更の確認が必要です。
Android 15(API 35)は主要な動作変更を導入します:Advertising ID制限付きのPrivacy Sandbox、必須宣言付きのForeground Service Types、許可ダイアログ付きのSCHEDULE_EXACT_ALARM制限、Scoped Storageの強化、クレデンシャルレス認証への自動移行。targetSdk 35+のアプリはAPI 35での完全なテストサイクルを経る必要があります。
targetSdkVersionを更新しない場合、Google Playはアプリの新しいバージョンの公開をブロックします。Googleは毎年最小targetSdkを引き上げます:2025年8月からはtargetSdk 34+、2026年8月からはtargetSdk 35+が予想されます。要件を満たさないアプリはストアから削除されます。さらに、セキュリティ動作変更が適用されず、アプリが脆弱になります。
targetSdkVersionを確認するには、ADBを使用します:adb shell dumpsys package com.example.myapp | grep targetSdk。Android StudioではAPK Analyzerを開きます:Build → Analyze APK → AndroidManifest.xml → uses-sdk。コードでは:context.applicationInfo.targetSdkVersion。Google Play Consoleでは、targetSdkはリリースページのArtifact Detailsセクションに表示されます。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。