開発者コンソール

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

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

Fire OS 7はAndroid 9 Pieをベースにしています。以下のガイドラインを読んで、アプリとFire OS 7の互換性を確認してください。

Fire OS 7搭載デバイスと旧Fire OS搭載デバイス

Android 9 Pie(APIレベル28)をベースにしたFire OS 7は、2019年に一部のFire TVデバイス向けに初めてリリースされました。

2018年に発売されたAmazon Fire TVデバイスのほとんどは、Android Nougat(Android 7.1.2、レベル25)をベースにしたFire OS 6を採用しています。それ以前のFire TVデバイスは、Fire OS 5(Android 5.1、レベル22)を搭載しています。通常、旧型デバイスのFire OSバージョンはアップグレードされません。

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

Fire OS 7におけるAndroidの変更点

Fire OS 6からFire OS 7にアップグレードするには、Nougat(Android 7.1.2)からOreo(Android 8.0)またはPie(Android 9)への移行が必要です。

Android 8.0とAndroid 9で導入された変更点のため、アプリをFire OS 7デバイスで正常に動作させるにはコードを変更する必要があります。

Android 8.0の変更点

Android 8.0における主な変更点は以下のとおりです。

  • 通知チャネル: すべての通知(「おすすめ」パートナーが管理する「おすすめ」を含む)をチャネルに割り当てる必要があります。チャネルについて詳しくは、Androidドキュメントの通知チャネルを作成して管理するを参照してください。サンプルコードと追加情報については、後述のFire OS 7における通知セクションを参照してください。

  • バックグラウンドサービス: Android 8.0では、バックグラウンドサービスの実行が制限されています。そのため、Fire OS 7ではアプリがバックグラウンドサービスを使用しておすすめを更新することができません。このバックグラウンドサービスの制限を回避する方法として、AndroidではJobSchedulersの使用が推奨されています。詳細については、Androidドキュメントのバックグラウンド実行制限を参照してください。

  • ネイティブライブラリ: 書き込みと実行の両方が可能なロードセグメントが含まれているネイティブライブラリはロードされません。

  • パーミッション: 同じグループに属しているパーミッションでも、各パーミッションをアプリから明示的に要求する必要があります。

  • MediaSessionイベント: アプリでオーディオを処理するには、MediaSessionを適切に使用する必要があります。詳細については、Android 8.0ドキュメントのメディアセッションの検索を参照してください。Androidがイベントを処理する際、イベントを処理するためのアクティブなメディアセッションがフォアグラウンドアクティビティになければ、Androidはほかのメディアセッションを探します。マルチメディアアプリの要件も参照してください。

上記の変更点については、Android 8.0での動作変更点を参照してください。

Android 9の変更点

Android 9における主な変更点は以下のとおりです。

  • プライバシーに関する変更点: アプリからWi-Fiへのアクセスが制限されます。バックグラウンドで実行中のアプリからユーザー入力やセンサーデータにアクセスする機能が制限されています。

上記の変更点については、動作の変更点:すべてのアプリを参照してください。

Fire OS 7とAndroid 9の互換性

Fire OS 7で実装されたすべての機能は、Android 9と互換性があります。Android 9のすべての機能がFire OS 7で利用可能なわけではありませんが、Fire OS 7で実装された機能についてはAndroid 9でも同等に使用可能です。Android 9の一部の機能(分割画面、通知ドット、アダプティブアイコンなど)は、Fire OS 7ではサポートされていません。

また、Fire OS 7の機能とAndroid 9は互換性がありますが、Amazon FireデバイスでGoogleのサービスを使用することはできません。代わりに、必要なサービス(アプリ内課金など)に対応するAmazon SDKを使用する必要があります。詳細については、Fire TVとAndroid TVにおける開発の違いを参照してください。

Fire OS 7デバイスをアプリの対象に指定

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

Fire OS 7デバイスを対象に指定するには、コードでBuild.VERSION.SDK_INT28(Android 9のAPIレベル)以上であることを確認してください。

詳細については、Fire TVデバイスの識別を参照してください。詳細については、Androidドキュメントの各種のプラットフォームバージョンをサポートするも参照してください。

Fire OS 7デバイスにおけるアプリの互換性テスト

アプリとFire OS 7の互換性は、実際のデバイスに接続することでテストが可能です。

minSdkVersionとtargetSdkVersionの設定

minSdkVersionは、該当するFire OSバージョンの最小APIレベルに設定します。

Fire OSのバージョン minSdkVersion
Fire OS 5 22
Fire OS 6 25
Fire OS 7 28

targetSdkVersionは、アプリのテストに使用した最も高いAPIレベルに設定します。

最小APIレベル要件の詳細については、デバイスフィルタリングと互換性に記載の「Fire OSとAndroidのAPIレベル」を参照してください。

minSdkVersionがサポート対象デバイスに与える影響

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

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

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

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

targetSdkVersion

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

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

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

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

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

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

Fire OS 7における通知

Android 8.0(APIレベル26)では、アプリが送信する通知をチャネルに割り当てる必要があります(「おすすめ」は通知の一種です)。 アプリが通知またはおすすめを送信する場合、チャネルを作成し、そのチャネルを通知に関連付ける必要があります。チャネルIDがない通知は破棄されます。

通知にチャネルを追加する手順の概要は、以下のとおりです。

  1. 手順1: 通知チャネルを作成し、通知マネージャーに渡して登録する
  2. 手順2: 通知のチャネルIDを設定する(次のいずれかの方法を使用します)

以下のセクションでは、上記の内容について詳しく説明すると共に、コードサンプルを示します。

手順1: 通知チャネルを作成し、通知マネージャーに渡して登録する

以下は、Androidドキュメントの通知チャネルを作成するからの抜粋です。

通知チャネルを作成する

通知チャネルを作成する手順は次のとおりです。

  1. 固有のチャネルID、ユーザーに表示される名前、重要度を指定して、NotificationChannelオブジェクトを作成します。
  2. 必要であれば、システム設定でユーザーに表示される説明をsetDescriptionで指定します。
  3. createNotificationChannelに通知チャネルを渡して登録します。

    private void createNotificationChannel() {
        //NotificationChannelを作成しますが、API 26以降でのみ使用します。
        //これは、NotificationChannelクラスが新しく、サポートライブラリにないためです
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            CharSequence name = getString(R.string.channel_name);
            String description = getString(R.string.channel_description);
            int importance = NotificationManager.IMPORTANCE_DEFAULT;
            NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
            channel.setDescription(description);
            //チャネルをシステムに登録します。この後で重要度や
            //通知動作を変更することはできません
            NotificationManager notificationManager = getSystemService(NotificationManager.class);
            notificationManager.createNotificationChannel(channel);
        }
    }
    

手順2: 通知のチャネルIDを設定する

通知のチャネルIDを設定する方法には、2つのオプションがあります。ContentRecommendationとリフレクションを使用するオプションと、Notification.Builderを使用するオプションです。

オプション1: createContentRecommendationとリフレクションを使用してチャネルIDを設定する

Notification notification = createContentRecommendation(largeIcon, notificationId);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    Log.d(TAG, "SDKバージョンはAndroid O以上です");

    try {
        Field channel = notification.getClass().getDeclaredField("mChannelId");
        channel.setAccessible(true);
        channel.set(notification, StringTerms.CHANNEL_ID);
    }
    catch (Exception e) {
        Log.d(TAG, "チャネルIDを設定できません", e);
    }
}

オプション2: Notification.BuilderとチャネルIDを使用する

以下のコードは、Google Gitに記載されたAndroidオープンソースプロジェクトのコードを適宜変更したものです。

public Notification getNotificationObject(Context context) {
    Notification.Builder builder = new Notification.Builder(context, "channelId");
    RecommendationExtender recExtender = new RecommendationExtender();

    //通知オブジェクト内にあるすべてのおすすめコンテンツデータをエンコードします

    builder.setCategory(Notification.CATEGORY_RECOMMENDATION);
    builder.setContentTitle(mTitle);
    builder.setContentText(mText);
    builder.setContentInfo(mSourceName);
    builder.setLargeIcon(mContentImage);
    builder.setSmallIcon(mBadgeIconId);
    if (mBackgroundImageUri != null) {
        builder.getExtras().putString(Notification.EXTRA_BACKGROUND_IMAGE_URI, mBackgroundImageUri);
    }
    builder.setColor(mColor);
    builder.setGroup(mGroup);
    builder.setSortKey(mSortKey);
    builder.setProgress(mProgressMax, mProgressAmount, false);
    builder.setAutoCancel(mAutoDismiss);

    if (mContentIntentData != null) {
        PendingIntent contentPending;
        if (mContentIntentData.mType == INTENT_TYPE_ACTIVITY) {
            contentPending = PendingIntent.getActivity(context, mContentIntentData.mRequestCode,
            mContentIntentData.mIntent, PendingIntent.FLAG_UPDATE_CURRENT,
            mContentIntentData.mOptions);
        }
        else if (mContentIntentData.mType == INTENT_TYPE_SERVICE) {
            contentPending = PendingIntent.getService(context, mContentIntentData.mRequestCode,
            mContentIntentData.mIntent, PendingIntent.FLAG_UPDATE_CURRENT);
            }
            else { // Default:INTENT_TYPE_BROADCAST{
            contentPending = PendingIntent.getBroadcast(context,
            mContentIntentData.mRequestCode,
            mContentIntentData.mIntent, PendingIntent.FLAG_UPDATE_CURRENT);
            }
        builder.setContentIntent(contentPending);
    }

    if (mDismissIntentData != null) {
        PendingIntent dismissPending;
        if (mDismissIntentData.mType == INTENT_TYPE_ACTIVITY) {
            dismissPending = PendingIntent.getActivity(context, mDismissIntentData.mRequestCode,
            mDismissIntentData.mIntent, PendingIntent.FLAG_UPDATE_CURRENT,
            mDismissIntentData.mOptions);
        }
        else if (mDismissIntentData.mType == INTENT_TYPE_SERVICE) {
            dismissPending = PendingIntent.getService(context, mDismissIntentData.mRequestCode,
            mDismissIntentData.mIntent, PendingIntent.FLAG_UPDATE_CURRENT);
            }
            else { // Default:INTENT_TYPE_BROADCAST{
                dismissPending = PendingIntent.getBroadcast(context,
                mDismissIntentData.mRequestCode,
                mDismissIntentData.mIntent, PendingIntent.FLAG_UPDATE_CURRENT);
            }
        builder.setDeleteIntent(dismissPending);
    }

    recExtender.setContentTypes(mContentTypes);
    recExtender.setGenres(mContentGenres);
    recExtender.setPricingInformation(mPriceType, mPriceValue);
    recExtender.setStatus(mStatus);
    recExtender.setMaturityRating(mMaturityRating);
    recExtender.setRunningTime(mRunningTime);

    builder.extend(recExtender);
    Notification notif = builder.build();
    return notif;
}

詳細については、Androidドキュメントの通知チャネルを作成して管理するを参照してください。

Amazon Device Messaging(ADM)の互換性

アプリでADMを使用している場合は、Fire OS 7でクラッシュが発生しないように、SDKを更新する必要があります。以前のリリースでは、ADMはIntentServiceを使用して、バックグラウンドで実行中のクライアントアプリにメッセージを送信していました。Fire OS 7では、IntentServiceはAndroid 8.0(APIレベル26)で課されるすべてのバックグラウンド実行制限の対象となります。たとえば、Androidドキュメントのバックグラウンドサービスの制限事項によれば、以下のような制限があります。

IntentServiceはサービスであるため、バックグラウンドサービスに対する新しい制限事項の対象になります。そのため、IntentServiceに依存する多くのアプリは、Android 8.0以降を対象にすると正常に動作しません。こうした理由から、Androidサポートライブラリ26.0.0に新しいJobIntentServiceクラスが導入されました。このクラスはIntentServiceと同じ機能を提供しますが、Android 8.0以降で実行されるときにサービスではなくジョブを使用します。

アプリがバックグラウンドで実行中にADMメッセージを受信できるようにするには、JobIntentServiceを使用する必要があります。この新しいクラスは、Android 8.0以降で実行される場合、サービスの代わりにジョブを使用します。

ADMMessageHandlerJobBaseは、JobIntentServiceを使用してバックグラウンドでメッセージを配信する新しいクラスです。これまでのADMMessageHandlerBaseに置き換えて、このクラスを使用してください。ADMとやり取りを行うアプリを作成する場合は、ハンドラーでADMMessageHandlerJobBaseを拡張する必要があります。実装例については、登録とメッセージの処理を実装するを参照してください。また、リリースの一環として更新されたAmazon Device Messaging(ADM)のセットアップ方法およびアプリのマニフェストを更新するも参照してください。

更新されたADM SDKは、こちらからダウンロードできます。

WakeLockの変更点

フォーカスされている起動状態のアプリをユーザーが4時間操作しなかった場合、「まだ視聴していますか?」という確認メッセージが表示されます。ユーザーが確認しなかった場合は、ホーム画面に戻ります。詳細については、WakeLockの要件を参照してください。

この機能は [設定] でオフにできます。アプリがサイネージアプリの場合、この機能が適用されないようにするには、Amazonにお問い合わせください

サポート

Fire OS 7でアプリに問題が見つかった場合は、Amazon Fire TVとFire TV Stickに関するフォーラムでその問題を報告してください。