Android 8.0(API 级别 26)引入了各种 为用户和开发者提供新功能。 本文重点介绍面向开发者的新变化。
请务必查看 Android 8.0 行为变更,了解平台变更可能影响您的应用的领域。
用户体验
画中画模式
Android 8.0 中的画中画功能。
Android 8.0(API 级别 26)允许 activity 以 画中画 (PIP) 模式。画中画是一种特殊类型的多窗口模式,最常用于视频播放。画中画模式最初适用于 仅限 Android TV;Android 8.0 让该功能 。
当某个 activity 处于 PIP 模式时,它会处于暂停状态,但仍应继续显示内容。因此,您应确保您的应用
不会在 onPause()
中暂停播放
处理程序。相反,您应在 onStop()
中暂停播放视频,并在 onStart()
中继续播放。如需了解详情,请参阅
多窗口模式
Lifecycle。
如需指定您的 activity 可以使用 PIP 模式,请在清单中将 android:supportsPictureInPicture
设置为 true。(从 Android 8.0 开始,画中画不需要 android:resizeableActivity
清单属性。但是,您必须设置
将 android:resizeableActivity
设为 `true`(如果您的 activity 支持其他
多窗口模式)。
Android 8.0(API 级别 26)引入了新对象 PictureInPictureParams
,您可以将该对象传递给 PIP 方法来指定某个 activity 在其处于 PIP 模式时的行为。此对象还指定了各种属性,例如 activity 的首选纵横比。
现在,在添加画中画中介绍的现有 PIP 方法可用于所有 Android 设备,而不仅限于 Android TV。此外,Android 8.0 还提供以下方法来支持 PIP 模式:
Activity.enterPictureInPictureMode(PictureInPictureParams args)
:将 activity 置于画中画模式。activity 的纵横比和其他配置设置均由 args 指定。如果 args 中的任何字段为空,系统将使用您上次调用Activity.setPictureInPictureParams()
时所设置的值。指定的 activity 放置在屏幕的一角;其余的 屏幕会用其显示上一个 activity。 进入画中画模式的 activity 会进入暂停状态,但会保留 。如果用户点按此 PIP activity,系统将显示一个菜单供用户操作,而在 activity 处于 PIP 状态期间,不会理会任何触摸事件。
-
Activity.setPictureInPictureParams()
: 更新 activity 的画中画配置设置。如果 activity 目前处于 PIP 模式,则会更新此设置;如果 activity 的纵横比发生变化,这非常有用。如果 activity 不处于画中画模式,则会使用这些配置设置,而不会考虑您调用的enterPictureInPictureMode()
方法。
通知
在 Android 8.0(API 级别 26)中,我们对通知进行了重新设计, 提供了一种更简单、更一致的方法来管理通知行为 和设置。这些更改包括:
- 通知渠道:Android 8.0 中引入了 可让您创建用户可自定义的渠道的通知渠道 为每个您想要显示的通知类型界面是指 作为通知类别添加到通知渠道。了解 实现通知渠道的方法,请参阅 管理 通知渠道。
- 通知圆点:Android 8.0 引入了对在应用启动器图标上显示圆点或标志的支持。通知圆点反映 显示用户尚未关闭或未处理的通知。 如需了解如何使用通知圆点,请参阅通知标志。
- 休眠:用户可以将通知置于休眠状态,这会导致通知在消失一段时间后重新显示。重新显示时通知的重要程度与首次显示时相同。应用可以移除或更新 更新已延后的通知, 让它重新出现
- 通知超时:您可以在使用
setTimeoutAfter()
创建通知时设置超时。 您可以使用此方法指定通知持续时长 。如果需要,您可以在指定的超时持续时间过去之前取消通知。 - 通知设置:您可以拨打
setSettingsText()
设置在创建指向应用 使用Notification.INTENT_CATEGORY_NOTIFICATION_PREFERENCES
intent。 系统可能会提供以下 extra,以便过滤 您的应用必须向用户显示的设置:EXTRA_CHANNEL_ID
、NOTIFICATION_TAG
和NOTIFICATION_ID
。 - 通知关闭:用户可以自行关闭通知,并且
应用可以通过编程方式将其移除。您可以通过实现
NotificationListenerService
类中的onNotificationRemoved()
方法来确定通知何时关闭以及关闭的原因。 - 背景颜色:您可以为通知设置和启用背景颜色。您仅应在通知中使用此功能:
对用户而言至关重要的持续性任务例如,您可以为与驾车路线或正在进行的通话有关的通知设置背景颜色。您还可以使用
setColor()
设置所需的背景颜色。这样做将允许您使用setColorized()
启用通知的背景颜色设置。 - 消息样式:在 Android 8.0 中,使用
MessagingStyle
类显示屏 展开前即可看到更多内容。对于与消息有关的通知,您应使用MessagingStyle
类。您还可以使用addHistoricMessage()
方法通过添加 历史消息发送到消息相关通知。

用户可以长按应用启动器图标进行查看 通知。
自动填充框架
账号创建、登录和信用卡交易需要时间并且容易出错。用户很容易对需要这些类型的应用感到不满 重复性任务。
Android 8.0(API 级别 26)支持填写表单(例如登录) 和信用卡表单,可以更轻松地实现。 在用户选择接受自动填充之后,新老应用都可使用自动填充框架。
您可以采取某些措施,优化您的应用使用此框架的方式。如需了解详情,请参阅自动填充框架概览。
可下载字体
Android 8.0(API 级别 26)和 Android 支持库 26 允许您从提供程序应用请求字体,而无需将字体绑定到 APK 中或让 APK 下载字体。此功能可缩减 APK 大小,增加应用大小 安装成功率,并让多个应用共用同一种字体。
如需详细了解如何下载字体,请参阅 可下载字体。
XML 中的字体
Android 8.0(API 级别 26)引入了一项新功能,即 XML 中的字体,
您可以将字体用作资源。这意味着,不再需要将字体捆绑为资源。字体在 R
文件中编译,并且会自动
作为资源在系统中提供然后,您可以使用
一种新的资源类型 font
的帮助。
支持库 26 在设备上完全支持此功能 运行 API 版本 14 及更高版本。
如需详细了解如何将字体用作资源以及如何检索系统字体,请参阅 XML 中的字体。
自动调整 TextView 的大小
Android 8.0(API 级别 26)允许您根据 TextView 的大小自动设置文本展开或收缩的大小。这意味着,在不同屏幕上优化文本大小或者优化包含动态内容的文本大小比以往简单多了。如需详细了解如何在 Android 8.0 中自动调整 TextView 的大小, 请参阅自动调整 TextView 的大小。
自适应图标
Android 8.0(API 级别 26)引入了自适应启动器图标。自适应图标支持视觉元素 并能在不同设备型号上显示各种形状如需了解如何创建自适应图标,请参阅自适应图标指南。
颜色管理
成像应用的 Android 开发者现在可以充分利用新设备 具有支持广色域色彩的显示器如需显示广色域图片,应用需要在其清单(每个 activity)中启用一个标志,并加载具有嵌入的广色域配置文件(AdobeRGB、Pro Photo RGB、DCI-P3 等)的位图。
WebView API
Android 8.0 提供了一些 API 来帮助您管理
在应用中显示 Web 内容的 WebView
对象。
这些 API 可提高应用的稳定性和安全性,包括
以下:
- Version API
- Google SafeBrowsing API
- Termination Handle API
- Renderer Importance API
如需详细了解如何使用这些 API,请参阅 管理 WebView。
WebView
类现在添加了一个 Safe Browsing API 来增强网络浏览的安全性。如需了解详情,请参阅
Google Safe Browsing API。
固定快捷方式和微件
Android 8.0(API 级别 26)引入了快捷方式和微件的应用内固定功能。在应用中,您可为 Android Studio 中的 支持的启动器。
如需了解详情,请参阅固定快捷方式和微件功能指南。
最大屏幕纵横比
Android 8.0(API 级别 26)对应用的最大宽高比配置方式做出了更改。
首先,Android 8.0 引入了 maxAspectRatio 属性,也就是 可用于设置应用的最大宽高比。此外,在 Android 8.0 及更高版本中,应用的默认最大宽高比为运行应用的设备的原生宽高比。
如需详细了解如何声明最大宽高比,请参阅支持多种屏幕。
多显示屏支持
从 Android 8.0(API 级别 26)开始,此平台为多显示屏提供增强的支持。如果 activity 支持多窗口模式,并且在具有多显示屏的设备上运行,则用户可以将 activity 从一个显示屏移动到另一个显示屏。当应用启动一个 activity 时, 可指定 activity 应在哪个显示屏上运行。
注意 :如果某个 activity 支持 多窗口模式,则 Android 8.0 会自动启用 因此该 activity 支持多显示屏。您应测试您的应用,确保它在多显示器环境下可正常运行。
每次只有一个 activity 可以处于已恢复状态,即使 应用具有多个显示屏获得焦点的 activity 处于已恢复状态; 所有其他可见的 activity 都会暂停,但不会停止。如需详细了解当多个 activity 可见时 activity 生命周期,请参阅多窗口生命周期。
当用户将 activity 从一个显示屏移到另一个显示屏时,系统会调整 activity 大小,并根据需要发起运行时变更。您的 activity 可以自行处理配置变更,或允许系统销毁包含该 activity 的进程,并以新的尺寸重新创建它。如需了解详情,请参阅处理配置变更。
ActivityOptions
提供了两种新方法来支持
多个显示屏:
setLaunchDisplayId()
- 指定 activity 在启动后应显示在哪个显示屏上。
getLaunchDisplayId()
- 返回 activity 的当前启动显示屏。
adb shell 进行了扩展,以支持多个显示屏。
shell start
命令现在可用于启动 activity,并指定 activity 的目标显示屏:
adb shell start <activity_name> --display <display_id>
统一的布局外边距和内边距
Android 8.0(API 级别 26)让您可以更轻松地指定 View
元素的对边使用相同外边距和内边距的情形。具体来说,您现在可以在布局 XML 文件中使用以下属性:
- <ph type="x-smartling-placeholder"></ph>
layout_marginVertical
,用于定义layout_marginTop
和layout_marginBottom
。 layout_marginHorizontal
,同时定义layout_marginLeft
和layout_marginRight
。paddingVertical
,同时定义paddingTop
和paddingBottom
。paddingHorizontal
,同时定义paddingLeft
和paddingRight
。
注意:如果您自定义应用逻辑以支持不同语言和文化(包括文本方向),请记住,这些属性不会影响 layout_marginStart
、layout_marginEnd
、paddingStart
或 paddingEnd
的值。您可以自行设置这些值和新的垂直与水平布局属性来创建取决于文本方向的布局行为。
指针捕获
某些应用(例如游戏、远程桌面和虚拟化客户端)大大受益于对鼠标指针的控制。指针捕获是一项新功能 Android 8.0(API 级别 26)中的功能,通过传递所有鼠标事件来提供此类控制 传递到应用中的聚焦视图
从 Android 8.0 开始,应用中的 View
可以请求
指针捕获并定义一个监听器来处理捕获的指针事件。鼠标指针在此模式下将隐藏。如果不再需要鼠标信息,该视图可以释放指针捕获。系统也可以在视图丢失焦点时(例如,当用户打开另一个应用时)释放指针捕获。
如需了解如何在应用中使用此功能,请参阅 指针捕获。
应用类别
在适当的情况下,Android 8.0(API 级别 26)允许每个应用声明其所属的类别。这些类别用于将应用呈现给用户的用途或功能类似的应用归类在一起,例如按流量消耗、电池消耗和存储消耗将应用归类。您可以在 <application>
manifest 标记中设置 android:appCategory
属性,定义应用的类别。
Android TV 启动器
Android 8.0(API 级别 26)包含以内容为中心的全新 Android TV 主屏幕体验,可与 Android TV 模拟器和 Android 8.0 的 Nexus Player 设备映像搭配使用。新版主屏幕会将视频内容按与频道对应的行进行整理,每个频道由系统上的应用填充节目。应用可以发布多个频道,用户可以配置他们希望在主屏幕上看到哪些频道。Android TV 主屏幕还包含一个“接下来观看”行,此行根据用户的观看习惯从应用填充节目。应用也可以提供视频预览,这些预览会在用户聚焦到节目时自动播放。用于填充频道和节目的 API 属于 TvProvider API,这些 API 以 Android 支持库模块的形式随 Android 8.0 分发。
AnimatorSet
从 Android 8.0(API 级别 26)开始,AnimatorSet
API 现在支持寻道和播放
反向排序。跳转功能可让您将动画位置设为
。如果您的应用包含动画,反向播放非常有用
执行可撤消的操作无需定义两个单独的动画
您可以反向播放相同的这一段
输入和导航
键盘导航键区
如果应用中的 activity 使用复杂的视图层次结构,例如 图 2,考虑将界面元素组整理为聚类,以简化操作 通过键盘进行导航。用户可以按 Meta+Tab 或搜索键 + Tab Chromebook 设备,以从一个集群导航到另一个集群。好的 元素集包括:侧边栏、导航栏、主要内容区域和元素 并可能包含多个子元素

如需将 View
或 ViewGroup
元素设置为一个键区,请在元素的布局 XML 文件中将 android:keyboardNavigationCluster
属性设置为 true
,或者将 true
传递到应用界面逻辑中的 setKeyboardNavigationCluster()
。
注意:虽然集群是非嵌套的,但其无法嵌套
集群可能出现在层次结构的不同级别。如果您尝试
嵌套集群,框架只会处理最顶层
ViewGroup
元素作为聚类。
在具有触摸屏的设备中,您可以将某个键区指定的 ViewGroup
对象的 android:touchscreenBlocksFocus
元素设置为 true
,仅允许从键区导航进入和离开此键区。如果您应用此方法
配置,则用户无法使用 Tab 键或箭头键
进入或离开集群他们必须按仪表板导航
组合键。
视图默认焦点
在 Android 8.0(API 级别 26)中,您可以分配 View
会在(重新)创建的 Activity 恢复且用户按下
键盘导航键,例如 Tab 键。如需应用此“设为默认焦点”设置,请在包含界面元素的布局 XML 文件中将 View
元素的 android:focusedByDefault
属性设置为 true
,或者将 true
传递至应用界面逻辑中的 setFocusedByDefault()
。
语音输出
activity 和服务可以使用 TextToSpeech
的实例来口述和读出内容。从 Android 8.0(API 级别 26)开始,只要文本到语音转换引擎提供此信息,您的应用便可以获取有关文本到语音转换引擎何时开始朗读单个合成字词的更精确时间信息。您可以使用此功能在文本转语音引擎读出特定字词时引起注意。
如需在应用中使用这些文本转语音引擎改进功能,请注册 UtteranceProgressListener
的实例。在注册过程中,添加 onRangeStart()
方法的处理程序。
文字转语音引擎调用
rangeStart()
即可录制
预计播放特定范围文本的时间点
。当该文本范围的音频开始播放时,应用的
onRangeStart()
方法执行。然后,您的应用可以响应此回调,例如,通过
突出显示与话语关联的文本范围。
详细了解如何跟踪文字转语音的播放进度
引擎,请参阅 UtteranceProgressListener
类
参考。
系统
新的 StrictMode 检测程序
Android 8.0(API 级别 26)添加了三个新的 StrictMode 检测程序,帮助识别应用可能出现的错误:
detectUnbufferedIo()
将检测 您的应用会在不缓冲的情况下读写数据,这可能会极大影响 性能detectContentUriWithoutPermission()
将会 检测到您的应用何时意外忘记向其他应用授予权限 在应用外启动 activity。detectUntaggedSockets()
将检测 您的应用无需使用setThreadStatsTag(int)
,用于标记流量以进行调试 目的。
缓存的数据
Android 8.0(API 级别 26)优化了缓存数据的导航和行为。每个
现在,系统会为应用提供用于缓存数据的磁盘空间配额,该配额由
getCacheQuotaBytes(UUID)
。
当系统需要释放磁盘空间时,会先从应用中删除缓存文件 超出其所分配的配额的那些客户。因此,如果您将缓存数据保留在 分配配额时,在上传资源时,您的缓存文件将是系统中最后要清除的文件之一 。系统在决定删除您的应用中的哪些缓存文件时,将首先考虑删除最旧的文件(由修改时间确定)。
您还可以针对每个目录启用两种新行为,以控制系统如何释放缓存数据:
StorageManager.setCacheBehaviorAtomic()
可用于指示 指定目录及其所有内容应作为一个原子单元进行删除。setCacheBehaviorTombstone(File, boolean)
可用于指示 应将其截断为 0 个字节,而不是删除目录中的 保留空文件不变。
最后,当需要为大型文件分配磁盘空间时,可以考虑使用新版
allocateBytes(FileDescriptor, long)
API,这会自动清除
属于其他应用的缓存文件(如果需要),以满足您的请求。在确定
设备有足够的磁盘空间来保存新数据,
getAllocatableBytes(UUID)
,而不使用
getUsableSpace()
,因为前者将将所有缓存内容视为
系统愿意代您清除的数据。
内容提供程序分页
我们已更新内容提供程序以支持加载大型数据集,每次加载一页。例如,一个具有大量图像的照片应用可查询要在页面中显示的数据的子集。每个页面 content provider 返回的结果由单个游标表示 对象。客户端和提供程序都必须实现分页才能利用 。
如需详细了解内容提供程序的变更,请参阅
ContentProvider
和
ContentProviderClient
。
内容刷新请求
ContentProvider
和
ContentResolver
类现在每个都包含一个
refresh()
方法,以便客户端更轻松地了解
请求的信息都是最新的。
您可以通过扩展
ContentProvider
。请务必重写 refresh()
方法以返回 true
,告知提供程序的客户端您已尝试自行刷新数据。
您的客户端应用可通过调用另一个函数(也称为 refresh()
),显式请求已刷新的内容。调用此方法时,请传入要刷新的数据的 URI。
注意:由于您可能通过网络不断请求数据,您应仅在有明显迹象表明内容确已过时时才从客户端调用 refresh()
。执行此类内容刷新最常见的原因是响应滑动刷新手势,该手势显式请求当前界面显示最新内容。
JobScheduler 改进
Android 8.0(API 级别 26)引入了对 JobScheduler
的多项改进。由于您通常可以使用定时任务替代现在受限的后台服务或隐式 broadcast receiver,这些改进可以让您的应用更轻松地符合新的后台执行限制。
JobScheduler
的更新包括:
-
您现在可以将工作队列与定时任务关联。将工作项添加到
调用
JobScheduler.enqueue()
。 当任务运行时,它可以将待处理的工作从队列中剥离并进行处理。这项功能可处理很多以前需要 调用后台服务,特别是实现IntentService
。 -
Android 支持库 26.0.0 引入了新的
JobIntentService
类,该类提供与IntentService
相同的功能,但在 Android 8.0(API 级别 26)或更高版本上运行时使用作业而非服务。 -
您现在可以调用
JobInfo.Builder.setClipData()
将ClipData
与任务相关联。利用此选项,您可以将 URI 权限授予与任务关联,类似于这些权限传递到Context.startService()
的方式。您也可以将 URI 权限授予用于工作队列上的 intent。 -
定时任务现在支持多个新的约束条件:
JobInfo.isRequireStorageNotLow()
- 如果设备的可用存储空间不足,作业不会运行。
JobInfo.isRequireBatteryNotLow()
- 如果电池电量等于或低于临界水平,作业不会运行 阈值;当电池电量不足时,设备会显示“电量不足”。 警告系统对话框。
NETWORK_TYPE_METERED
- 任务需要一个按流量计费的网络连接,比如大多数移动数据网络数据套餐。
自定义数据存储
Android 8.0(API 级别 26)支持您根据自己的偏好设置提供自定义的数据存储区, 如果您的应用将偏好设置存储在云端或本地数据库中,则相应选项会非常有用;或者 。如需详细了解 实现数据存储区,请参阅 自定义数据存储区。
媒体增强功能
VolumeShaper
有一个新的 VolumeShaper
类。您可以用它来执行简短的自动音量转换,例如淡入、淡出和交叉淡入淡出。如需了解详情,请参阅使用 VolumeShaper 控制振幅。
音频焦点增强功能
音频应用通过请求和舍弃音频焦点的方式在设备上共享音频输出。应用通过启动或停止播放或者降低音量的方式处理焦点变化。有一个新的 AudioFocusRequest
类。使用此类作为 requestAudioFocus()
的参数,应用在处理音频焦点变化时会使用新功能:自动闪避和延迟聚焦。
媒体指标
新的 getMetrics()
方法会返回 PersistableBundle
包含配置的对象
和性能信息,表示为属性和值的对应关系。
可以为以下媒体类定义 getMetrics()
方法:
MediaPlayer.getMetrics()
MediaRecorder.getMetrics()
MediaCodec.getMetrics()
MediaExtractor.getMetrics()
系统会为每个实例分别收集相关指标,并在实例的整个生命周期内保留这些指标。如果没有任何可用指标,则该方法会返回 null。返回的实际指标取决于类。
MediaPlayer
从 Android 8.0(API 级别 26)开始,MediaPlayer 可以播放受 DRM 保护的资料和 HLS 样本级加密媒体。
Android 8.0 引入了一个新的重载 seekTo()
命令,用于在跳转到帧时提供精细控制。它包含一个用于指定跳转模式的第二个参数:
SEEK_PREVIOUS_SYNC
会将媒体位置移至与位于给定时间之前或给定时间的数据源关联的同步(或关键)帧。SEEK_NEXT_SYNC
将媒体位置移至关联的同步(或关键帧)帧 且数据源位于指定时间之后或指定的时间SEEK_CLOSEST_SYNC
会将媒体位置移至与最接近给定时间或在给定时间的数据源关联的同步(或关键)帧。SEEK_CLOSEST
将媒体位置移至帧(不一定是同步操作) 或关键帧) 指定的时间
连续跳转时,应用应使用任意 SEEK_
模式,而不是 SEEK_CLOSEST
,后者运行速度相对较慢,但可能更精确。
MediaRecorder
- MediaRecorder 现在支持 MPEG2_TS 格式,
在线播放:
Kotlin
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_2_TS)
Java
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_2_TS);
MediaMuxer
现在可以处理任意数量的音频和视频流。你已解除受限状态 一个音轨和/或一个视频轨道。使用addTrack()
可混录所需的任意数量的曲目。MediaMuxer
还可以添加一个或多个包含用户定义的每帧信息的元数据轨道。元数据的格式由您的应用定义。通过 只有 MP4 容器支持元数据轨道。
元数据对于离线处理非常有用。例如,传感器的陀螺仪信号可以用于执行视频稳定操作。
添加元数据轨道时,轨道的 MIME 格式必须以前缀开头
"application/"。写入元数据的方式与写入视频/音频数据相同,但以下情况除外:
数据并非来自 MediaCodec
。相反,应用会将
将 ByteBuffer
替换为
writeSampleData()
方法。
时间戳必须与视频和音频轨道处于相同的时基。
生成的 MP4 文件使用 ISOBMFF 的 12.3.3.2 部分定义的 TextMetaDataSampleEntry
来指示元数据的 MIME 格式。使用 MediaExtractor
提取包含元数据轨道的文件时,MIME 是
格式的元数据会提取到MediaFormat
中。
增强的媒体文件访问功能
存储访问框架 (SAF) 允许应用公开自定义 DocumentsProvider
,后者可以为其他应用提供访问数据源中文件的权限。事实上,文档提供程序甚至可以提供驻留在网络存储区或使用媒体传输协议 (MTP) 等协议的文件的访问权限。
但是,从远程数据源访问大型媒体文件 挑战:
- 媒体播放器需要以可跳转的方式访问来自文档提供程序的文件。 当大媒体文件驻留在远程数据源上时,文档提供程序必须事先提取所有数据,并创建快照文件描述符。没有文件,媒体播放器无法播放文件 描述符,因此在文档提供程序完成之前,无法开始播放 下载该文件。
- 照片应用等媒体集合管理器必须通过作用域文件夹遍历一系列访问 URI 才能访问存储在外部 SD 卡上的媒体。这种访问模式可对媒体执行批量操作,例如 移动、复制和删除,速度都很慢。
- 媒体集合管理器无法确定文档的位置,因为它 URI这使得这类应用的用户难以选择 媒体文件的保存位置
Android 8.0 通过改进存储访问能力来应对上述挑战 框架。
自定义文档提供程序
从 Android 8.0 开始,存储访问框架允许 自定义文档 provider 为本地存储器中的文件创建可寻址的文件描述符, 远程数据源。SAF 可打开文件,获取原生可寻址的文件描述符。然后,SAF 向文档提供程序提交离散字节请求。通过此功能,文档提供程序可以返回 而不是缓存整个 文件。
如需使用此功能,您需要调用新的 StorageManager.openProxyFileDescriptor()
方法。通过
openProxyFileDescriptor()
方法接受 ProxyFileDescriptorCallback
对象作为回调。任何时候,当客户端应用对文档提供程序返回的文件描述符执行文件操作时,SAF 都会调用回调。
直接文档访问
从 Android 8.0(API 级别 26)开始,您可以使用
getDocumentUri()
方法
获取引用了与给定 mediaUri
相同的文档的 URI。
不过,由于返回的 URI 由
DocumentsProvider
,媒体集合管理员可以访问
而无需遍历分区目录树。
因此,媒体管理器能够以明显加快的速度对文档执行文件操作。
注意:getDocumentUri()
方法仅定位媒体文件;它不向应用授予
访问这些文件的权限。如需详细了解如何获取媒体文件的访问权限,请参阅参考文档。
文档路径
在 Android 8.0(API 级别 26)中使用存储访问框架时,您可以使用
findDocumentPath()
方法,在
DocumentsContract
和
DocumentsProvider
类,在给定文档的
ID。该方法会在 DocumentsContract.Path
对象中返回此路径。如果文件系统对相同文档有多个定义的路径,该函数将返回访问具有给定 ID 的文档时最常使用的路径。
此功能尤其适用于以下情况:
- 您的应用使用可以显示特定文档位置的“另存为”对话框。
- 您的应用在搜索结果视图中显示文件夹,并且如果用户选择某个文件夹,应用必须加载此特定文件夹内的子文档。
注意:如果您的应用仅具有路径中某些文档的访问权限,那么 findDocumentPath()
的返回值将仅包含您的应用可以访问的文件夹和文档。
监控音频播放
AudioManager
系统服务会维护
活跃的 AudioPlaybackConfiguration
对象,每个
包含有关特定音频播放会话的信息。您的应用可以
通过调用
getActivePlaybackConfigurations()
。
从 Android 8.0(API 级别 26)开始,您可以注册一个回调,以便在一个或多个 AudioPlaybackConfiguration
对象发生变化时通知您的应用。为此,请调用 registerAudioPlaybackCallback()
,并传入 AudioManager.AudioPlaybackCallback
的实例。通过
AudioManager.AudioPlaybackCallback
类包含
onPlaybackConfigChanged()
方法,系统会在音频播放时调用该方法
播放配置更改。
连接
Wi-Fi 感知
Android 8.0(API 级别 26)新增了对 WLAN 感知的支持,此技术基于周边感知联网 (NAN) 规范。在具有相应 WLAN 感知硬件的设备上,应用和附近设备可以通过 WLAN 进行搜索和通信,而无需依赖互联网接入点。我们正在与硬件合作伙伴合作,以尽快将 WLAN 感知技术应用于设备。如需了解如何将 Wi-Fi 感知集成到您的应用中,请参阅 Wi-Fi 感知。
蓝牙
Android 8.0(API 级别 26)通过添加以下 功能:
- 支持 AVRCP 1.4 标准,该标准支持音乐库浏览。
- 支持蓝牙低功耗 (BLE) 5.0 标准。
- 将 Sony LDAC 编解码器集成到蓝牙堆叠中。
配套设备配对
在尝试通过蓝牙、BLE 和 WLAN 与配套设备配对时,Android 8.0(API 级别 26)提供的 API 允许您自定义配对请求对话框。如需了解详情,请参阅 配套设备 配对。
如需详细了解如何在 Android 上使用蓝牙,请参阅蓝牙指南。对于 特定于 Android 8.0(API 级别 26)的蓝牙变更,请参阅 蓝牙部分 Android 8.0 行为变更页面。
分享
智能共享
Android 8.0(API 级别 26)会了解用户的个性化分享偏好设置,并更好地了解哪些应用适合分享哪些类型的内容。例如,如果用户为一张收据拍照,Android 8.0 可以建议费用跟踪应用;如果用户自拍,一款社交媒体应用可以更好地处理图像。Android 8.0 可以根据用户的个性化首选项自动学习所有这些模式。
智能分享功能适用于 image
之外的内容类型,例如
audio
、video
、text
、URL
、
等等
要启用智能分享功能,请添加 ArrayList
(最多三个)
字符串注释添加到分享内容的 intent。这些注释应说明内容中的主要部分或主题。以下代码示例展示了如何向 intent 添加注解:
Kotlin
val annotations: ArrayList<String> = arrayListOf( "topic1", "topic2", "topic3" ) intent.putStringArrayListExtra( Intent.EXTRA_CONTENT_ANNOTATIONS, annotations )
Java
ArrayList<String> annotations = new ArrayList<>(); annotations.add("topic1"); annotations.add("topic2"); annotations.add("topic3"); intent.putStringArrayListExtra( Intent.EXTRA_CONTENT_ANNOTATIONS, annotations );
如需详细了解智能分享注释,请参阅
EXTRA_CONTENT_ANNOTATIONS
。
文本分类器
在兼容的设备上,应用可以使用新的文本分类器检查字符串是否与已知分类器实体类型匹配,并获取建议的选择替代项。系统识别的实体包括地址、网址、
电话号码和电子邮件地址如需了解详情,请参阅 TextClassifier
。
无障碍
Android 8.0(API 级别 26)支持开发者使用多项新的无障碍功能创建自己的无障碍服务:
- 新增了用于调整的音量类别 无障碍设施 数据量。
- 指纹 手势作为输入机制。
- 多语言文字转语音功能。
- 基于硬件的 无障碍设施 快捷方式,以便快速访问首选无障碍服务。
- 支持 (续) 手势,即由编程方式进行的笔触序列。
- 一个 无障碍设施 按钮,用于调用若干已启用的无障碍功能之一 (仅适用于使用软件渲染的导航区域的设备)。
- 标准化的单向范围值。
- 一些适用于 文字,包括提示文字和屏幕上文字的位置 字符。
安全和隐私保护
权限
Android 8.0(API 级别 26)引入了多个与电话有关的新权限:
-
ANSWER_PHONE_CALLS
权限允许您的应用回答问题 以编程方式进行来电。如要在以下位置处理来电: 使用acceptRingingCall()
方法。 READ_PHONE_NUMBERS
权限允许您的应用读取设备中存储的电话号码。
新的账号访问和 Discovery API
Android 8.0(API 级别 26)对应用访问用户账号的方式引入多项改进。对于他们管理的账号 身份验证器可以使用自己的政策来决定是否隐藏账号、 或向应用显示账号。Android 系统会跟踪 访问特定的账号。
在以前的 Android 版本中,想要跟踪用户账号列表的应用必须获取有关所有账号的更新,包括具有不相关类型的账号。Android 8.0 新增了
addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean, java.lang.String[])
方法,可让应用指定账号类型列表
接收哪些账号更改
API 变更
AccountManager 提供六个新方法来帮助身份验证器管理 以下应用可以查看某个账号:
setAccountVisibility(android.accounts.Account, java.lang.String, int)
:针对特定用户账号和软件包组合设置可见性级别。-
getAccountVisibility(android.accounts.Account, java.lang.String)
:获取特定用户账号和软件包组合的可见性级别。 -
getAccountsAndVisibilityForPackage(java.lang.String, java.lang.String)
: 允许身份验证器获取账号及其公开范围级别 指定的软件包。 -
getPackagesAndVisibilityForAccount(android.accounts.Account)
:允许身份验证器获取存储的给定账号的可见性值。 -
addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle, java.util.Map<java.lang.String, java.lang.Integer>)
:允许身份验证器初始化账号的可见性值。 -
addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean, java.lang.String[])
: 将OnAccountsUpdateListener
监听器添加到AccountManager
对象。系统会调用此监听器 每当设备上的账号列表发生变化时。
Android 8.0(API 级别 26)引入了两个特殊的软件包名称值来指定可见性
未使用
setAccountVisibility(android.accounts.Account, java.lang.String, int)
方法。通过
PACKAGE_NAME_KEY_LEGACY_VISIBLE
可见性值会应用于
GET_ACCOUNTS
权限以及
Android 版本低于 Android 8.0,或
签名与针对任何 Android 版本的身份验证器匹配。
PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE
提供默认的可见性值
之前未设置的应用
“PACKAGE_NAME_KEY_LEGACY_VISIBLE
”不是
。
如需详细了解新的账号访问和发现 API,请参阅 AccountManager
和 OnAccountsUpdateListener
参考文档。
测试
仪器测试
Android 8.0(API 级别 26)为应用的插桩测试提供了以下几项额外支持。
针对非默认应用进程运行
现在,您可以指定针对应用的默认进程以外的进程运行特定插桩测试。如果您的应用包含多个在不同进程中运行的 activity,此配置非常有用。
如需定义非默认进程插桩,请前往您的清单
文件,然后在该文件中
<ph type="x-smartling-placeholder"></ph>
<instrumentation>
元素。添加 android:targetProcess
属性,并将其值设置为以下值之一:
- 特定进程的名称。
- 以逗号分隔的进程名称列表。
- 通配符 (
"*"
),允许针对任何执行android:targetPackage
属性中指定的软件包中的代码的已启动进程运行插桩测试。
在执行插桩测试时,您可以查看哪个进程
它正通过调用 getProcessName()
进行测试。
在测试过程中报告结果
现在,你可以在执行插桩测试时报告结果,
而不是之后调用 addResults()
。
用于测试的模拟 Intent
为了更轻松地为您应用的 activity 创建隔离、独立的界面测试,Android 8.0(API 级别 26)引入了 onStartActivity()
方法。您可以在
Instrumentation.ActivityMonitor
类用于处理特定的
intent。
当您的测试类调用 intent 时,该方法将返回一个存根 Instrumentation.ActivityResult
对象,而不是执行 intent 本身。通过在测试中使用此模拟 intent 逻辑,您可以集中精力
activity 如何准备和处理传递给
不同的活动或完全不同的应用。
运行时和工具
平台优化
Android 8.0(API 级别 26)为平台带来了运行时优化和其他优化, 大幅提升性能 这些优化包括并发压缩垃圾回收、更有效的内存利用和代码区域。
这些优化可以缩短启动时间, 操作系统和应用。
更新了 Java 语言支持
Android 8.0(API 级别 26)添加了对几个其他 OpenJDK Java API 的支持:
- OpenJDK 8 中的
java.time
。 - OpenJDK 7 中的
java.nio.file
和java.lang.invoke
。
如需详细了解这些新添加的类和方法, 请参阅 API 参考文档。
如果您希望 使用 Java 8 语言功能时,您应该 下载最新的预览版。
更新的 ICU4J Android Framework API
Android 8.0(API 级别 26)扩展了 ICU4J Android 框架 API(它是 ICU4J API 的子集),供应用开发者在 android.icu
软件包下使用。这些 API 使用本地化数据
因此,您无需编译
APK 中的 ICU4J 库。
表 1. 使用的 ICU、CLDR 和 Unicode 版本 。
Android API 级别 | ICU 版本 | CLDR 版本 | Unicode 版本 |
---|---|---|---|
Android 7.0(API 级别 24),Android 7.1(API 级别 25) | 56 | 28 | 8.0 |
Android 8.0(API 级别 26) | 58.2 | 30.0.3 | 9.0 |
如需详细了解 Android 上的国际化(包括 ICU4J 支持),请参阅 Android 上的国际化。
Android 企业版
我们针对运行 Android 8.0(API 级别 26)。亮点包括:
- 完全托管的设备中的工作资料使企业可以在管理工作数据与个人数据的同时,将它们分离开来。
- API 委派允许设备所有者和资料所有者分配应用 对其他应用的管理
- 配置流程中的用户体验改进措施(包含新的自定义选项)缩短了设置时间。
- 蓝牙、WLAN、备份和安全性方面的新增控制选项使企业可以更精细地管理设备。网络活动日志记录可帮助企业跟踪 问题。
如需详细了解上述及其他新的 Android Enterprise API 和功能, 请参阅企业中的 Android。