開発者コンソール

Android 14搭載Fire TV対応アプリの開発について

Android 14搭載Fire TV対応アプリの開発について

Android 14搭載Fire TVは、APIレベル34をベースにしています。以下のセクションでは、Android 14搭載Fire TV向けにアプリを開発するうえで考慮すべき重要な変更点について説明します。以下のように標準のAndroidコンポーネントへの移行を行うと、互換性の問題が発生するリスクが軽減され、アプリを簡単に管理できるようになります。

Android 14搭載Fire TVデバイスと旧Fire OS搭載デバイス

Android 14搭載Fire TVには、Android 12(APIレベル31)、Android 12L(APIレベル32)、Android 13(APIレベル33)、Android 14(APIレベル34)のアップデート内容が組み込まれています。古いバージョンのFire TVデバイスの中には、まだ以前のバージョンのFire OSで動作するものもあります。

Fire TVデバイスおよびバージョンの詳細については、Fire OSのバージョンを参照してください。

Androidのアップデート内容

Android 14の重要なアップデートについては、以下のトピックを参照してください。

PendingIntent可変性フラグ

Android 12より前のリリースでは、FLAG_IMMUTABLEが設定されていない限り、PendingIntentは可変であると想定できました。Android 12以降では、PendingIntentの作成時に、FLAG_IMMUTABLEまたはFLAG_MUTABLEを使用して可変性を明示的に指定する必要があります。

解決策

PendingIntentを作成する場合は、FLAG_IMMUTABLEを使用します。FLAG_MUTABLEは、一部の機能が基となるインテントの変更に依存している場合にのみ使用します。次の例は、インライン返信やバブルで使用する必要があるPendingIntentFLAG_MUTABLEを適用する方法を示しています。

クリップボードにコピーしました。


PendingIntent pendingIntent = PendingIntent.getBroadcast(context, requestCode, intent, PendingIntent.FLAG_MUTABLE);

クリップボードにコピーしました。


val pendingIntent = PendingIntent.getBroadcast(context, requestCode, intent, PendingIntent.FLAG_MUTABLE)


以下に可変性フラグのサンプルコードを示します。

これまで使用していた可能性があるのは次のようなものです。

クリップボードにコピーしました。

PendingIntent pendingIntent =
        PendingIntent.getBroadcast(
            context,
            requestCode,
            intent, 
            /* フラグ= */ 0);

クリップボードにコピーしました。

val pendingIntent =
      PendingIntent.getBroadcast(
          context,
          requestCode,
          intent,
          /* フラグ= */ 0)

アップデート後のコードサンプルは次のようになります。

クリップボードにコピーしました。

PendingIntent pendingIntent =
        PendingIntent.getBroadcast(
            context,
            requestCode,
            intent, 
            /* フラグ= */ PendingIntent.FLAG_MUTABLE);

クリップボードにコピーしました。

val pendingIntent =
      PendingIntent.getBroadcast(
          context,
          requestCode,
          intent,
          /* フラグ= */ PendingIntent.FLAG_MUTABLE)

詳細については、FLAG_IMMUTABLEおよびPendingIntentを参照してください。

より安全なコンポーネントのエクスポートインテント

Android 12以降では、アプリがアクティビティ、サービス、ブロードキャストレシーバーで<intent-filter>要素を使用する場合、マニフェストファイルで明示的な属性宣言(android:exported)を行って、どのアプリからでもアクティビティにアクセスできることを宣言する必要があります。アプリにandroid:exportedの値が設定されていない場合、アプリをAndroid 14搭載Fire TVデバイスにインストールすることはできません。これらの新しいガイドラインに準拠するには、アプリのAndroidManifest.xmlファイルを更新して、次の属性宣言を追加します。

クリップボードにコピーしました。

<activity android:name="ShareActivity" android:exported="false">

宣言をtrueに設定すると、どのアプリからでもアクティビティにアクセスして、正確なクラス名で起動できるようになります。宣言をfalseに設定すると、同じアプリのコンポーネント、同じユーザーIDのアプリ、権限のあるシステムコンポーネントからのみアクティビティを起動できます。

また、Android 14以降では、APIレベル34をターゲットとするアプリの場合、コンテキスト登録されたレシーバーにRECEIVER_EXPORTEDフラグまたはRECEIVER_NOT_EXPORTEDフラグを指定する必要もあります。RECEIVER_EXPORTEDフラグまたはRECEIVER_NOT_EXPORTEDフラグが指定されていない場合は、実行時にアプリがクラッシュします。

解決策

Context.registerReceiverへのすべての呼び出しを更新して上記のフラグを指定することで、実行時のクラッシュを防ぐことができます。

詳細については、Receiving an implicit intentおよびRuntime-registered broadcasts receivers must specify export behaviorを参照してください。

targetSdkVersionの制約

targetSdkVersionが23~27のアプリでは、互換性に関する警告がユーザーに1回だけ表示されます。ユーザーは警告を無視してアプリを引き続き実行できますが、結果としてユーザーエクスペリエンスが低下します。2022年4月1日以降に申請または更新したアプリの場合、Fire OS 7(またはそれ以降)で利用可能になっていれば、targetSdkVersionは既に27より大きくなっています。

Android 14以降では、targetSdkVersionが23未満のアプリはインストールできません。アプリでこの対象APIレベルの最小要件を満たすことを必須とすることにより、ユーザーのセキュリティとプライバシーが強化されます。

詳細については、Ensure compatibility with Android 14を参照してください。

DEXファイル - アップレベル

Androidアプリの開発中に「Writable dex file is not allowed」というエラーが発生する場合は、最新バージョンのAndroidオペレーティングシステムとの互換性の問題が原因である可能性があります。

このエラーは通常、DEXファイル(Androidアプリのコンパイルされたコードファイル)のパーミッションが書き込み可能に設定されている場合に発生します。Android 14では、セキュリティ上のリスクが生じる可能性があるため、より厳格なセキュリティ対策が導入され、書き込み可能なDEXファイルをアプリに含めることが禁止されています。

Androidの推奨事項に準拠してください。この問題は、最新バージョンのAndroid Studioでも検出できます。

エラーログの例

08-21 01:43:58.189  8222  8554 E AndroidRuntime: java.lang.SecurityException: Writable dex file '/data/user/0/com.kptv.ott/cache/1664557424545.jar' is not allowed.

トーストの使用

アプリをAndroid 14に移行する場合、トーストの使用時に次のランタイム例外が発生することがあります。

Caused by: java.lang.IllegalStateException: Text provided for custom toast, remove previous setView() calls if you want a text toast instead.

以前のバージョンのAndroidでは、同じトーストにカスタムビューとテキストの両方を設定することが可能でした。Android 14では、より厳密な区別が必要となり、テキストベースのトーストとカスタムビューをそれぞれ表示することはできますが、両方を同時に表示することはできなくなりました。両方の方法を使用しようとすると、IllegalStateExceptionが発生します。

解決策

Android 14でIllegalStateExceptionの発生を回避するには、テキストのみのトーストを使用します。

Bluetoothのパーミッション

更新されたBluetoothのパーミッションは、ユーザープライバシーを強化し、より合理化されたBluetooth接続エクスペリエンスを提供できるように設計されています。Bluetooth名の取得やBluetooth接続の確立を試行すると問題が発生し、次のエラーログが表示されるようになっています。

java.lang.SecurityException: Settings key: <Bluetooth名> is only readable to apps with targetSdkVersion lower than or equal to: 31
08-20 11:34:26.175 10079 10152 W cr_media: BLUETOOTH_CONNECT permission is missing.08-20 11:34:26.189 10079 10152 W cr_media: registerBluetoothIntentsIfNeeded: Requires BLUETOOTH permission

解決策

この問題に対処するには、マニフェストファイル内で、アプリのBluetoothのパーミッション宣言をAndroidの最新ガイドラインに合わせて更新します。Android 12(APIレベル31)以降をターゲットとするアプリの場合は、次のパーミッションを宣言します。

  1. BLUETOOTH_SCAN: BLE周辺機器などのBluetoothデバイスをアプリで検索する場合。
  2. BLUETOOTH_ADVERTISE: アプリで現在のデバイスをその他のBluetoothデバイスから検出可能にする場合。
  3. BLUETOOTH_CONNECT: 既にペアリングされているBluetoothデバイスとアプリが通信する場合。

詳細については、Bluetooth permissionsを参照してください。

フォアグラウンドサービス

必要なパーミッションがない状態でフォアグラウンドサービスを開始しようとすると、java.lang.SecurityExceptionの問題が発生します。

java.lang.SecurityException: Permission Denial: startForeground from pid=1824, uid=10479 requires android.permission.FOREGROUND_SERVICE

解決策

Android 9で、FOREGROUND_SERVICEパーミッションが導入されました。Android 9以降で動作するアプリでフォアグラウンドサービスを使用する場合は、そのパーミッションを含める必要があります

Android 14をターゲットとするアプリでフォアグラウンドサービスを使用する場合は、フォアグラウンドサービスのタイプに基づいて特定のパーミッションを宣言する必要があります。ユースケースに適したものを選択するには、Foreground service types are requiredを参照してください。

各APIレベルでのフォアグラウンドサービスの変更をすべて確認するには、Changes to foreground servicesを参照してください。

ExoPlayerのバージョンアップ

Exoplayer 2.xバージョンでは、ビデオの滑らかさに問題が生じ、ユーザーエクスペリエンスが低下します。

解決策

AndroidX Media3移行ガイドに記載されている手順に従って、アプリのExoPlayerをMedia3に更新し、DefaultRenderersFactoryコンポーネントをMediaCodecの非同期キューイングに挿入します。

アラームのスケジュール設定

SCHEDULE_EXACT_ALARMパーミッションは、Android 12(APIレベル31)で導入されたセキュリティ上重要なパーミッションで、アプリが正確なアラームをスケジュール設定できるようにするためのものです。このパーミッションはAndroidの最近のバージョンで変更されました。

解決策

アプリのマニフェストファイルで、次のようにパーミッションを宣言します。

<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<uses-permission android:name="android.permission.USE_EXACT_ALARM" />

ただし、Android 14(APIレベル34)では、アプリのマニフェストファイルで宣言している場合でも、SCHEDULE_EXACT_ALARMパーミッションはデフォルトで付与されなくなりました。したがって、実行時にパーミッションが付与されているかどうかを確認し、付与されていない場合はユーザーにリクエストする必要があります。

以下を使用して、アプリでSCHEDULE_EXACT_ALARMパーミッションを確認してリクエストします。

クリップボードにコピーしました。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
    AlarmManager alarmManager = ContextCompat.getSystemService(context, AlarmManager.class);
    if (alarmManager != null && !alarmManager.canScheduleExactAlarms()) {
        Intent intent = new Intent();
        intent.setAction(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM);
        context.startActivity(intent);
    }
}

クリップボードにコピーしました。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
    val alarmManager = ContextCompat.getSystemService(context, AlarmManager::class.java)
    if (alarmManager?.canScheduleExactAlarms() == false) {
        Intent().also { intent ->
            intent.action = Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM
            context.startActivity(intent)
        }
    }
}

ユースケースを評価して、正確なアラームが必要かどうかを判断してください。詳細については、Use cases that might not require exact alarmsを参照してください。

パッケージの公開設定のフィルタリング

Android 11では、ほかのアプリにインテントを発行する際のパッケージの公開設定が変更されました。Android 11(APIレベル30)以降をターゲットとするアプリで、デバイスにインストールされているほかのアプリに関する情報をクエリすると、システムによってこの情報がデフォルトでフィルタリングされます。これにより、エラーが表示されることなく、インテントがそのまま失敗します。

解決策

一部のパッケージは自動で表示されるため、ほかのインストール済みアプリへのクエリで表示可能なパッケージをアプリで自動的に検出できます。ほかのパッケージを表示するには、<queries>要素を使用して、アプリでパッケージの公開設定の必要性を宣言します。詳細については、Package visibility filtering on Androidを参照してください。

Amazon SDK

Amazon SDKに依存している場合は、アプリのAndroidManifest.xmlファイルを更新し、amazon:enable-feature要素をuses-libraryに置き換える必要があります。この変更には、以前のバージョンのFire OSとの下位互換性があります。

Amazon Device Messaging(ADM)の例を以下に示します。

<uses-library
    android:name="com.amazon.device.messaging"
android:required="false"/>

詳細については、アプリの統合方法を参照してください。

64ビット互換性

32ビットアプリで最新バージョンのAndroidとの互換性がないという警告が表示されないようにするには、必ず64ビットサポートを追加してください。

詳細については、Support 64-bit architecturesを参照してください。

Android 14搭載Fire TVデバイスへのアプリのターゲット指定

ユーザーがアプリを実行するデバイスとしては、Fire OS 5、Fire OS 6、Fire OS 7、Fire OS 8、Android 14搭載Fire TVが考えられます。デバイスのFire OSバージョンとアプリの互換性を最大限に高めるため、SDKレベルに基づいてターゲットデバイスを指定することをお勧めします。

Android 14搭載Fire TVデバイスをターゲットに指定するには、コードでBuild.VERSION.SDK_INTが34(Android 14のAPIレベル)以上になっているかどうかを確認してください。

詳細については、Supporting Different Platform Versionsを参照してください。

アプリをテストする

アプリをテストするには、ライブアプリテストについてを参照してください。

minSdkVersionとtargetSdkVersionの設定

targetSdkVersionは、ターゲットとする最も高いAPIレベルに設定します。Android 14搭載Fire TVの場合、targetSdkVersionは34に設定することをお勧めします。minSdkVersionを目的のAPIレベルに設定することで、以前のデバイスを引き続きサポートできます。

Fire OSのバージョンに基づいたAPIレベルを次の表に示します。

Fire OSのバージョン APIレベル
Fire OS 5 22
Fire OS 7 28
Fire OS 8 30
Android 14搭載Fire TV 34

詳細については、デバイスフィルタリングと互換性を参照してください。

minSdkVersionがサポート対象デバイスと下位互換性に与える影響

アプリが正常に動作するために必要な最小SDKレベルは、アプリのマニフェスト(またはbuild.gradleファイル)内のminSdkVersionで設定します。そのAPIレベルをサポートしていないデバイスでは、該当アプリのインストールはできません。詳細については、デバイスフィルタリングと互換性を参照してください。

Fire OS 5デバイスはAPIレベル22(Lollipop 5.1)、Android 14搭載Fire TVデバイスはAPIレベル34(Android 14)をベースにしています。minSdkVersionを22に設定した場合、アプリが正常に動作するにはデバイスのAPIレベルが22以上であることが必要になります。

Androidではレベルに下位互換性があるため、minSdkVersionを22に設定すると、より高いAPIレベル(34など)のデバイスにもアプリがインストール可能になります。APIレベル34には、通常、レベル1~34のすべてのAPIが含まれます。リリースのたびに、前回のAPIレベルにレベルが追加されます。

しかし、Android 14(APIレベル34)のAPIを利用する場合、minSdkVersionを22に設定すると、APIレベルが34ではないFire OS 5デバイスにアプリがインストールされてしまいます。そのため、防御的なコーディングを行う必要があります。デバイスのAPIレベルを確認して、そのAPIレベルがサポートされていない場合は別のレベルにフォールバックするようなコード作成が必須となります。たとえば、以下のようなコードが考えられます。

if (Build.VERSION.SDK_INT >= 34) {
 Log.v(TAG, "はい、これはAPIレベル34以上のデバイスです");
} else {
 Log.v(TAG, "いいえ、これはAPIレベル34以上のデバイスではありません");
}

上のコード例では、デバイスのAPIレベルが34以上であるかどうかを確認しています。APIレベルが34以上の場合、コードが実行されます。それ以外の場合は、elseロジックでフォールバックします。

デフォルトでは、targetSdkVersionが指定されていない場合、minSdkVersionと同じ値がAndroidで使用されます。targetSdkVersionには、具体的にはアプリのテストに使用した最も高いAPIレベルを設定することができます。Androidは、アプリがこの値に基づいてデバイスで適切に動作するようにします。

たとえば、targetSdkVersionを25以上(Nougatのリリース)に設定すると、AndroidはNougatに含まれる実行時パーミッション確認機能を適用します。しかし、targetSdkVersionが25未満(Nougatに実行時パーミッション確認機能が導入される前)の場合、Androidはこの動作をアプリに適用しません。

推奨はしませんが、Android 14搭載Fire TVデバイスに古いアプリが表示されないようにする必要がある場合は、maxSdkVersionをFire OS 8(APIレベル30)に設定することもできます。

詳細については、以下のリソースを参照してください。

サポート

Android 14搭載Fire TVでアプリに問題が見つかった場合は、Amazon Fire TVとFire TV Stickに関するフォーラム(英語のみ)でその問題を報告してください。


Last updated: 2025年1月28日