LoginSignup
57
46

More than 5 years have passed since last update.

minSdkVersionとtargetSdkVersionの関係

Last updated at Posted at 2015-08-08

Androidでアプリ開発をする際に、minSdkVersionとtargetSdkVersionの関係性がいまいち理解できていなかったので、
実際にコード書いて検証してみた話。

まとめ

  • 下位互換性を保証するためにminSdkVersionを指定する場合は、minSdkVersion以降で追加されたAPIはそのまま使ってはならない
  • minSdkVersionを指定しつつも、より最新の機種では新しいAPIを使いたい場合は、実行時のAPIレベルを見て処理を分ける
  • (Support Libraryが使えそうであれば使う)

準備

build.gradle

  • コンパイルはAPIレベル22で行う
  • 最低動作保証APIレベルは15とする
build.gradle
minSdkVersion 15
targetSdkVersion 22

検証コード

以下のようなNotificationを実装する。

MainActivity.java
Notification notification = new Notification.Builder(context)
    .setSmallIcon(R.mipmap.ic_launcher)
    .setContentTitle("test title")
    .setContentText("test content")
    .setContentIntent(pendingIntent)
    .setColor(Color.RED) // API level 21 から追加されたAPI
    .build(); // API level 16 から追加されたAPI

Androidエミュレータ

以下のバージョンを準備。

  • Android 4.0.3 (API level 15)
  • Android 5.1 (API level 22)

1.検証

1) まずは何も考えずに実装してみる

最低動作保証APIレベルを15と指定しているのにもかかわらず、
APIレベル16以降で追加されたメソッドを実行しようとしているので、
APIレベル16以降から追加されたメソッド部分で警告が出る。
ただしコンパイルはAPIレベル22で行われるので、apk自体は作成できる。

01.png

このコードは、Android 4.0.3のエミュレータでは動かない。
(当該APIが存在しないため)

android4.0.3.png

08-08 10:29:09.807    1558-1558/org.tksmaru.sandbox.android.sdkversion E/AndroidRuntime﹕ FATAL EXCEPTION: main
    java.lang.NoSuchMethodError: android.app.Notification$Builder.setColor
            at org.tksmaru.sandbox.android.sdkversion.MainActivity$1.onClick(MainActivity.java:38)
            at android.view.View.performClick(View.java:4084)
            at android.view.View$PerformClick.run(View.java:16966)
            at android.os.Handler.handleCallback(Handler.java:615)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:4745)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
            at dalvik.system.NativeStart.main(Native Method)

Android 5.1では動く。

android5.1.png

2) 動作保証したい全てバージョンで動かすには

minSdkVersion以降で追加されたAPIは使わない

MainActivity.java
Notification notification = new Notification.Builder(context)
    .setSmallIcon(R.mipmap.ic_launcher)
    .setContentTitle("test title")
    .setContentText("test content")
    .setContentIntent(pendingIntent)
    .getNotification(); // API level 16 以降はdeprecatedだが、22時点では動く

実行時のAPIレベルごとに処理を分ける

特定の実行時APIレベル以上のときだけ新規追加されたAPIを利用できるようにする。
このように条件分岐すると、コンパイル時の警告も出なくなる。

ただし、コードが特定のAPIレベルに依存することになるので、メンテナンス性が良いとは言いづらい。

MainActivity.java
Notification notification;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    // API level 21 以上
    notification = new Notification.Builder(context)
        .setSmallIcon(R.mipmap.ic_launcher)
        .setContentTitle("test title")
        .setContentText("content is this")
        .setContentIntent(pendingIntent)
        .setColor(Color.RED) // API level 21 から追加
        .build(); // API level 16 から追加
} else {
    // API level 20 以下
    notification = new Notification.Builder(context)
        .setSmallIcon(R.mipmap.ic_launcher)
        .setContentTitle("test title")
        .setContentText("content is this")
        .setContentIntent(pendingIntent)
        .getNotification();
}

Support Libraryを使う

(まだ調べてない)

まとめ

  • 下位互換性を保証するためにminSdkVersionを指定する場合は、minSdkVersion以降で追加されたAPIはそのまま使ってはならない
  • minSdkVersionを指定しつつも、より最新の機種では新しいAPIを使いたい場合は、実行時のAPIレベルを見て処理を分ける
  • (Support Libraryが使えそうであれば使う)

参考

57
46
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
57
46