开发者控制台

Fire平板电脑上的Fire OS 7


Fire平板电脑上的Fire OS 7

Fire OS 7基于Android 9 Pie。遵从以下指南,确保应用与Fire OS 7兼容。

运行Fire OS 7和之前Fire OS版本的设备

Fire OS 7基于Android 9 Pie(API级别28)。Fire OS 7最初于2019年面向部分Fire平板电脑设备发布。

大多数Fire平板电脑设备运行Fire OS 5(Android 5.1,级别22)。Fire 7 (2019)平板电脑设备运行Fire OS 6,该版本基于Android Nougat(Android 7.1.2,级别25)。部分较早版本的Fire平板电脑设备仍然搭载Fire OS 4或更早版本。

有关Fire平板电脑设备和版本的详细列表,请参阅平板电脑设备规格

Fire OS 7中的Android更改

从Fire OS 6升级到Fire OS 7须通过Oreo(Android 8.0)从Nougat (Android 7.1.2)过渡到Pie (Android 9)。

Android 8.0和Android 9中进行的更改,须相应更改应用中的代码,应用才能在Fire OS 7设备上正常运行。

Android 8.0更改

Android 8.0中的主要更改如下:

  • 通知通道: 所有通知(包括推荐合作伙伴管理的推荐)必须与通道关联。有关通道的信息,请参阅有关通知通道的Android培训。有关示例代码和其他详细信息,请参阅下文的“Fire OS 7中的通知”部分。

  • 后台服务: Android 8.0限制后台服务的使用。因此,使用后台服务刷新其推荐的应用均无法刷新FOS 7上的推荐。Android建议使用JobScheduler来解决后台服务的限制。请参阅“后台服务”

  • 本机库: 若本机库包含既可写入又可执行的加载段,则不再加载本机库。

  • 权限: 应用需明示请求每个权限,即使在同一个权限组中也是如此。

  • MediaSession事件: 应用须正确使用MediaSession处理音频。请参阅有关查找媒体会话的Android 8.0文档。当Android处理事件时,若前台活动缺乏有效的媒体会话来处理事件,则Android将查找其他媒体会话。另请参阅”Fire TV上多媒体应用的要求“

可在Android 8.0行为变化中了解大部分更改情况。

Android 9更改

Android 9中的主要更改仅包括下列各项:

  • 隐私变更: 应用对Wifi的访问将受到限制。在后台运行时,应用对用户输入和传感器数据的访问权限将受到限制。

可在行为变化:所有应用(Pie)中了解更改情况。

Fire OS 7与Android 9的相同功能

FOS 7中的所有功能在Android 9中均能找到。这并不一定意味着Android 9中的所有内容均可在FOS 7中使用,但对于已在FOS 7中实现的功能,与在Android 9中是相同的。FOS 7不支持某些Android 9功能,如分屏、通知点和自适应图标。

另请记住,虽然Fire OS 7与Android 9具有相同功能,但无法在Amazon Fire设备上使用谷歌服务。必须使用相应的应用和游戏服务开发工具包,才能实现所需的服务(例如应用内购买)。

让您的应用适用于Fire OS 7设备

用户可能在Fire OS 5、Fire OS 6或Fire OS 7设备上运行应用。如需最大限度地提高应用与设备上的Fire OS版本的兼容性,建议根据SDK级别确定设备。

在代码中,可检查Build.VERSION.SDK_INT是否大于等于28(Android 9 API级别),以将Fire OS 7设备确定为目标设备。

另请参阅Android文档中的支持不同平台版本

在Fire OS 7设备上测试应用的兼容性

目前,可通过连接到实际设备,测试应用与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级别要求的更多信息。

了解minSdkVersion如何影响支持的设备

在应用清单(或build.gradle文件)中,minSdkVersion属性设置了应用正常运行所需的最低SDK级别。(不支持该API级别的设备将不允许在该设备上安装应用 — 这是应用商店设备筛选和兼容性的工作方式。)

Fire OS 5设备基于API级别22 (Lollipop 5.1)。Fire OS 7设备基于API级别28 (Android 9)。将minSdkVersion设置为22,即表示应用要求设备至少具有API级别22才能正常运行。

minSdkVersion设置为22时,还可在具有更高API级别(例如28)的设备中安装您的应用,因为Android级别向后兼容。API级别28通常包含级别1到级别28的所有API(每个版本均添加到上一个版本中)。

但假设你想利用Android 9中的API(API级别28)。若将minSdkVersion设置为22,则可以在没有API级别28的Fire OS 5设备中安装您的应用。因此,必须以防御方式进行编程,检查设备级别,若设备不支持该API级别,则回退到替代方案。代码可能如下所示:

targetSdkVersion

if (Build.VERSION.SDK_INT >= 28) {
 Log.v(TAG, "Yes, this is an API level 28 or higher device(是,这台设备具备API级别28或更高版本)");
} else {
 Log.v(TAG, "No, this is not an API level 28 or higher device(否,这台设备不具备API级别28或更高版本)");
}

该代码检查设备的API级别是否大于或等于28,若是,则运行代码。如果不是,则回退到else逻辑。

默认情况下,若未指定targetSdkVersion,将使用与minSdkVersion相同的值。targetSdkVersion允许您设置应用测试所依据的最新API级别。基于该值,Android将确保此级别设备的性能正常。

例如,若将targetSdkVersion设置为23或更高版本(Marshmallow的版本),Android将应用Marshmallow中包含的运行时权限检查功能。但是,如果targetSdkVersion低于23(在Marshmallow中推出运行时权限检查之前),Android将不在您的应用中应用此行为。

不推荐使用maxSdkVersion属性,但如需让应用在Fire OS 5设备上可用,则可将maxSdkVersion设置为22。如需让应用在Fire OS 6设备上可用,可将minSdkVersion设置为28。

有关更多信息,请参阅以下内容:

支持

若应用在Fire OS 7上存在问题,请在 Fire平板电脑论坛中报告该问题。

Fire OS 7中的通知

从Android Level 8.0(API级别26)开始,必须为应用发送的通知分配一个通道。(推荐是一种通知。) 若应用发送通知或推荐,必须创建一个通道并将通道与通知关联。没有通道ID的通知将被删除。

从更高层次上说,如需向通知添加通道,需进行以下操作:

  1. 步骤1: 创建通知通道,并在通知管理器中注册
  2. 步骤2: 设置通知的通道ID,使用以下方法之一:

以下章节提供更多详细信息和代码示例。

步骤1: 创建通知通道,并在通知管理器中注册

以下内容来自Android文档中的创建通知通道

创建通知通道

如需创建通知通道,请进行以下步骤:

  1. 构建具有唯一通道ID、用户可见名称和重要性级别的NotificationChannel对象。
  2. 或使用setDescription指定用户在系统设置中看到的描述。
  3. 通过将通知通道传递给createNotificationChannel,注册通知通道。

    private void createNotificationChannel() {
        //创建通知通道,但仅限于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。可使用ContentRecommendation和反射,设置通道ID,也可以使用Notification.Builder

方法1: 通过使用createContentRecommendation和反射,设置通道ID

Notification notification = createContentRecommendation(largeIcon, notificationId);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    Log.d(TAG, "SDK version is >= Android O");

    try {
        Field channel = notification.getClass().getDeclaredField("mChannelId");
        channel.setAccessible(true);
        channel.set(notification, StringTerms.CHANNEL_ID);
    }
    catch (Exception e) {
        Log.d(TAG, "Can't set ChannelId", 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)兼容性

如果您的应用使用Amazon Device Messaging,则需要更新SDK以避免在Fire OS 7上出现崩溃。在之前的版本中,ADM使用IntentService向在后台运行的客户端应用发送消息。在FireOS 7中,Android 8.0(API级别26)的所有后台执行限制适用于IntentService。例如,根据Android文档中的后台服务限制

IntentService是一项服务,因此受后台服务新限制的约束。因此,对于Android 8.0或更高版本而言,许多依赖IntentService的应用无法正常运行。出于这个原因,Android支持库26.0.0引入了一个新的JobIntentService类,该类与 IntentService具有相同功能,但在Android 8.0或更高版本上运行时,使用作业而不是服务。

应用必须使用JobIntentService才能在后台运行时接收ADM消息。在Android 8.0或更高版本上运行时,这个较新的类使用作业而不是服务。

ADMMessageHandlerJobBase是一个新的类,它将使用JobIntentService在后台传递消息。您应该使用此类代替旧的ADMMessageHandlerBase。创建与ADM交互的应用时,您应该在处理程序中扩展ADMMessageHandlerJobBase。关于示例,请参阅处理注册和消息。此外,另请参阅设置Amazon Device Messaging更新您的应用清单,这两项也作为版本的一部分进行了更新。

可以在此处下载更新后的ADM SDK