Android Q功能和API
Android Q为用户和开发人员引入了强大的新功能。本文档重点介绍了开发人员的新功能。
要了解新API,请阅读 API差异报告或访问 Android API参考 - 突出显示新API以便于查看。另外,请务必查看Android Q行为更改(针对针对Q和 所有应用的应用)以及隐私更改,以了解平台更改可能会影响您的应用的区域。
安全性增强
Android Q引入了许多安全功能,以下各节总结。
改进的生物识别认证对话框
Android Q 为Android 9中添加的统一生物识别身份验证对话框引入了以下改进 :
指定用户确认要求
您现在可以提供一个提示,告诉系统在用户使用隐式生物识别模式进行身份验证后不要求用户确认。例如,您可以告诉系统在用户使用Face身份验证进行身份验证后,不需要进一步确认。
默认情况下,系统需要用户确认。通常,用户希望确认敏感或高风险的操作(例如,进行购买)。但是,如果您的应用具有某些低风险操作,则可以通过传递false
给该 setConfirmationRequired()
方法提供不需要用户确认的提示。由于此标志作为提示传递给系统,因此如果用户更改了生物识别身份验证的系统设置,系统可能会忽略该值。
图1.没有用户确认的面部认证
图2.需要用户确认的面部身份验证
改进了对设备凭据的后备支持
您现在可以告诉系统允许用户使用他们的设备PIN,模式或密码进行身份验证,如果他们由于某种原因无法使用他们的生物识别输入进行身份验证。要启用此回退支持,请使用该 setDeviceCredentialAllowed()
方法。
如果您的应用当前用于 createConfirmDeviceCredentialIntent()
回退到设备凭据,请切换为使用新方法。
检查设备的生物识别能力
现在,您可以 在使用 类中BiometricPrompt
的canAuthenticate()
方法调用之前检查设备是否支持生物识别身份验证BiometricManager
。
直接从APK运行嵌入式DEX代码
您现在可以告诉平台直接从您应用的APK文件中运行嵌入式DEX代码。如果攻击者曾设法篡改设备上本地编译的代码,则此选项可以帮助防止攻击。
注意:启用此功能可能会影响应用程序的性能,因为ART必须在应用程序启动时使用JIT编译器(而不是读取提前编译的本机代码)。在您决定是否在已发布的应用中启用此功能之前,我们建议您测试应用的性能。
要启用此功能, 请在应用清单文件的元素中设置android:useEmbeddedDex
属性的值。您还必须构建一个包含ART可以直接访问的未压缩DEX代码的APK。将以下选项添加到Gradle或Bazel配置文件以构建具有未压缩DEX代码的APK:true
<application>
Gradle
aaptOptions {
noCompress 'dex'
}
Bazel
android_binary( ..., nocompress_extensions = [“.dex”], )
TLS 1.3支持
该平台的TLS实现现在支持TLS 1.3。TLS 1.3是对TLS标准的重大修订,包括性能优势和增强的安全性。我们的基准测试表明,与TLS 1.2相比,使用TLS 1.3可以将安全连接的速度提高40%。
默认情况下,为所有TLS连接启用TLS 1.3。您可以SSLContext
通过调用获取 禁用TLS 1.3的SSLContext.getInstance("TLSv1.2")
。您还可以通过调用setEnabledProtocols()
适当的对象在每个连接的基础上启用或禁用协议版本。
以下是有关TLS 1.3实施的一些重要细节:
- TLS 1.3密码套件无法自定义。启用TLS 1.3时,始终启用受支持的TLS 1.3密码套件,并
setEnabledCipherSuites()
忽略通过调用禁用它们的任何尝试。 - 协商TLS 1.3时,
HandshakeCompletedListeners
会话被添加到会话缓存之前被调用(这与TLS 1.2和其他先前版本相反)。 SSLEngine
SSLProtocolException
在某些情况下,实例会抛出一个SSLHandshakeException
先前抛出的实例。- 不支持0-RTT模式。
Public Conscrypt API
Conscrypt安全提供程序现在包含用于TLS功能的公共API。过去,用户可以通过反射访问此功能。但是,由于在P中添加了调用非公共API的限制,这已在Q中进行了灰名单,并将在未来的版本中进一步限制。
此更新添加了一组类,android.net.ssl
其中包含静态方法,以访问通用javax.net.ssl
API 不可用的功能 。可以将这些类的名称推断为关联javax.net.ssl
类的复数。例如,对javax.net.ssl.SSLSocket
实例进行操作的代码 可以使用新android.net.ssl.SSLSockets
类中的方法 。
连接功能
Android Q包含一些与网络和连接相关的改进。
Wi-Fi网络连接API
Android Q增加了对点对等连接的支持。此功能使您的应用可以通过使用WifiNetworkSpecifier
描述所请求网络的属性来提示用户更改设备所连接的接入点。对等连接用于非网络提供目的,例如Chromecast和Google Home硬件等辅助设备的引导配置。
使用此API时,您将使用以下流程:
-
使用创建Wi-Fi网络说明符
WifiNetworkSpecifier.Builder
。 -
设置网络过滤器以匹配要连接的网络以及所需的凭据。
-
决定的组合
SSID
,SSID pattern
,BSSID
,和BSSID pattern
设置在每个请求之后,网络过滤器,必须符合以下要求:- 每个请求应当提供的至少一个
SSID
,SSID pattern
,BSSID
,或BSSID pattern
- 每个请求只能设置一个
SSID
或SSID pattern
- 每个请求只能设置一个
BSSID
或BSSID pattern
- 每个请求应当提供的至少一个
-
将说明符与
NetworkCallback
实例一起添加到网络请求中 以跟踪请求的状态。如果用户接受请求并且与网络的连接成功,
NetworkCallback.onAvailable()
则在回调对象上调用。如果用户拒绝请求或者与网络的连接不成功,NetworkCallback.onUnavailable()
则在回调对象上调用。
点对点连接不需要位置或Wi-Fi权限。发起连接到对等设备的请求会在同一设备上启动一个对话框,该设备的用户可以从该对话框接受连接请求。
绕过用户批准
一旦用户批准网络连接以响应来自特定应用的请求,该设备就存储对特定接入点的批准。如果应用程序再次发出连接到该访问点的特定请求,则设备将跳过用户批准阶段并自动连接到网络。如果用户选择在连接到API请求的网络时忘记网络,则会删除此应用程序和网络组合的存储批准,并且应用程序的任何将来请求都需要再次由用户批准。如果应用程序发出非特定(例如使用SSID或BSSID模式)请求,则用户将需要批准该请求。
代码示例
以下代码示例显示如何连接到SSID前缀为“test”且BSSID OUI为“10:03:23”的开放网络:
Kotlin语言写法
val specifier = WifiNetworkSpecifier.Builder()
.setSsidPattern(PatternMatcher("test", PatternMatcher.PATTERN_PREFIX))
.setBssidPattern(MacAddress.fromString("10:03:23:00:00:00"), MacAddress.fromString("ff:ff:ff:00:00:00"))
.build()
val request = NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.setNetworkSpecifier(specifier)
.build()
val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val networkCallback = object : ConnectivityManager.NetworkCallback() {
...
override fun onAvailable(network: Network?) {
// do success processing here..
}
override fun onUnavailable() {
// do failure processing here..
}
...
}
connectivityManager.requestNetwork(request, networkCallback)
...
// Release the request when done.
connectivityManager.unregisterNetworkCallback(networkCallback)
Java写法
final NetworkSpecifier specifier =
new WifiNetworkSpecifier.Builder()
.setSsidPattern(new PatternMatcher("test", PatterMatcher.PATTERN_PREFIX))
.setBssidPattern(MacAddress.fromString("10:03:23:00:00:00"), MacAddress.fromString("ff:ff:ff:00:00:00"))
.build();
final NetworkRequest request =
new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.setNetworkSpecifier(specifier)
.build();
final ConnectivityManager connectivityManager = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
final NetworkCallback networkCallback = new NetworkCallback() {
...
@Override
void onAvailable(...) {
// do success processing here..
}
@Override
void onUnavailable(...) {
// do failure processing here..
}
...
};
connectivityManager.requestNetwork(request, networkCallback);
...
// Release the request when done.
connectivityManager.unregisterNetworkCallback(networkCallback);
Wi-Fi网络建议API
Android Q添加了对您的应用的支持,可为设备添加网络凭据以自动连接到Wi-Fi接入点。您可以提供有关要连接到哪个网络的建议 WifiNetworkSuggestion
。平台最终会根据您的应用和其他人的输入选择接受哪个接入点。
以下代码示例显示如何为一个打开的,一个WPA2和一个WPA3网络提供凭据:
Kotlin语言写法
val suggestion1 = WifiNetworkSuggestion.Builder()
.setSsid("test111111")
.setIsAppInteractionRequired() // Optional (Needs location permission)
.build()
val suggestion2 = WifiNetworkSuggestion.Builder()
.setSsid("test222222")
.setWpa2Passphrase("test123456")
.setIsAppInteractionRequired() // Optional (Needs location permission)
.build()
val suggestion3 = WifiNetworkSuggestion.Builder()
.setSsid("test333333")
.setWpa3Passphrase("test6789")
.setIsAppInteractionRequired() // Optional (Needs location permission)
.build()
val suggestionsList = listOf(suggestion1, suggestion2, suggestion3)
val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
val status = wifiManager.addNetworkSuggestions(suggestionsList);
if (status != WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) {
// do error handling here
}
// Optional (Wait for post connection broadcast to one of your suggestions)
val intentFilter = IntentFilter(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION);
val broadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (!intent.action.equals(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION)) {
return;
}
// do post connect processing here
}
};
context.registerReceiver(broadcastReceiver, intentFilter);
Java语言写法
final WifiNetworkSuggestion suggestion1 =
new WifiNetworkSuggestion.Builder()
.setSsid("test111111")
.setIsAppInteractionRequired() // Optional (Needs location permission)
.build()
final WifiNetworkSuggestion suggestion2 =
new WifiNetworkSuggestion.Builder()
.setSsid("test222222")
.setWpa2Passphrase("test123456")
.setIsAppInteractionRequired() // Optional (Needs location permission)
.build()
final WifiNetworkSuggestion suggestion3 =
new WifiNetworkSuggestion.Builder()
.setSsid("test333333")
.setWpa3Passphrase("test6789")
.setIsAppInteractionRequired() // Optional (Needs location permission)
.build()
final List suggestionsList =
new ArrayList {{
add(suggestion1);
add(suggestion2);
add(suggestion3);
}};
final WifiManager wifiManager =
(WifiManager) context.getSystemService(Context.WIFI_SERVICE);
final int status = wifiManager.addNetworkSuggestions(suggestionsList);
if (status != WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) {
// do error handling here…
}
// Optional (Wait for post connection broadcast to one of your suggestions)
final IntentFilter intentFilter =
new IntentFilter(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION);
final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (!intent.getAction().equals(
WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION)) {
return;
}
// do post connect processing here..
}
};
context.registerReceiver(broadcastReceiver, intentFilter);
在平台启动与他们的连接之前,应用程序的建议必须得到用户的批准。当用户第一次在扫描结果中找到与应用程序中的一个建议匹配的网络时,用户响应通知来提供此批准。当平台连接到其中一个网络建议时,设置将显示将网络连接归属于相应建议器应用程序的文本。
改进了Wi-Fi高性能和低延迟模式
Android Q允许您提供底层调制解调器的提示,以最大限度地减少延迟。
Android Q扩展了Wi-Fi锁定API,以有效支持高性能模式和低延迟模式。高性能和低延迟模式禁用Wi-Fi节能,并且可以在低延迟模式下启用进一步的延迟优化,具体取决于调制解调器支持。
低延迟模式仅在获取锁定的应用程序在前台运行且屏幕打开时启用。低延迟模式对于实时移动游戏应用程序尤其有用。
DNS解析器中的专门查找
Android Q为DNS over TLS和专门的DNS查找添加了原生支持。以前,平台DNS解析器支持A类解析,它可以根据域名解析IP地址,但不具体说明该IP提供的服务。通过此更新,现在还支持SRV
&NAPTR
lookups。
Android Q为开发人员提供标准的明文查找和DNS-over-TLS模式。
Wi-Fi轻松连接
通过Android Q,您可以使用Easy Connect为对等设备配置Wi-Fi凭据,以替代已弃用的WPS。应用可以使用ACTION_PROCESS_WIFI_EASY_CONNECT_URI
intent 将Easy Connect集成到其设置和配置流程中 。此意图需要URI。调用应用程序可以通过各种方法检索URI,包括从贴纸或显示器扫描QR码,或通过扫描蓝牙LE或NFC广告。
URI可用后,您可以使用ACTION_PROCESS_WIFI_EASY_CONNECT_URI
intent 配置对等设备的Wi-Fi凭据。这允许用户选择要共享的Wi-Fi网络并安全地传输凭证。
Easy Connect不需要位置或Wi-Fi权限。
注意:在使用此意图之前,应用程序必须通过调用验证设备是否支持Easy ConnectWifiManager.isEasyConnectSupported()
。
Wi-Fi Direct连接API
在WifiP2pConfig
和WifiP2pManager
API类在Android Q的更新,以支持使用预定信息的快速连接建立功能的Wi-Fi直连。该信息通过侧通道共享,例如蓝牙或NFC。
以下代码示例显示如何使用预定信息创建组:
Kotlin语言写法
val manager = getSystemService(Context.WIFI_P2P_SERVICE) as WifiP2pManager
val channel = manager.initialize(this, mainLooper, null)
// prefer 5G band for this group
val config = WifiP2pConfig.Builder()
.setNetworkName("networkName")
.setPassphrase("passphrase")
.enablePersistentMode(false)
.setGroupOperatingBand(WifiP2pConfig.GROUP_OWNER_BAND_5GHZ)
.build()
// create a non-persistent group on 5GHz
manager.createGroup(channel, config, null)
Java语言写法
WifiP2pManager manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
Channel channel = manager.initialize(this, getMainLooper(), null);
// prefer 5G band for this group
WifiP2pConfig config = new WifiP2pConfig.Builder()
.setNetworkName("networkName")
.setPassphrase("passphrase")
.enablePersistentMode(false)
.setGroupOperatingBand(WifiP2pConfig.GROUP_OWNER_BAND_5GHZ)
.build();
// create a non-persistent group on 5GHz
manager.createGroup(channel, config, null);
要使用凭据加入组,请使用manager.createGroup()
以下内容替换:
Kotlin语言写法
manager.connect(channel, config, null)
Java语言写法
manager.connect(channel, config, null);
蓝牙LE连接定向通道(CoC)
Android Q使您的应用能够使用BLE CoC连接在两个BLE设备之间传输更大的数据流。该接口抽象了蓝牙和连接机制,以简化实施。
电话功能
Android Q包含与电话相关的一些改进。
通话质量改进
Android Q增加了在支持该功能的设备上收集有关正在进行的IP多媒体子系统(IMS)呼叫质量信息的功能,包括进出网络的质量。
呼叫筛选和来电显示
Android Q为您的应用提供了一种方法,可以将不在用户地址簿中的呼叫识别为潜在的垃圾电话,并代表用户静默拒绝垃圾电话。有关这些被阻止呼叫的信息将记录为呼叫日志中的被阻止呼叫,以便在用户丢失呼叫时为其提供更大的透明度。使用此新API消除了READ_CALL_LOG
从用户获取 权限以提供呼叫筛选和呼叫者ID功能的要求。
调用重定向服务API
Android Q改变了调用意图的处理方式。该NEW_OUTGOING_CALL
广播已被废弃,被替换的CallRedirectionService
API。该CallRedirectionService
API提供接口供您通过修改Android平台打出的电话。例如,第三方应用可能会取消呼叫并通过VoIP重新路由它们。
在外部存储上创建文件的改进
除了引入范围存储 隐私行为更改之外,Android Q还提供了更多编写文件的灵活性,并引入了帮助您影响这些文件在外部存储设备上保存的位置的功能。
新媒体文件的待处理状态
Android Q引入了 IS_PENDING
标记,使您的应用可以独占访问媒体文件,因为它已写入磁盘。
以下代码段显示了在应用中IS_PENDING
创建新图片时如何使用该标记:
Kotlin语言写法
val values = ContentValues().apply {
put(MediaStore.Images.Media.DISPLAY_NAME, "IMG1024.JPG")
put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
put(MediaStore.Images.Media.IS_PENDING, 1)
}
val resolver = context.getContentResolver()
val collection = MediaStore.Images.Media
.getContentUri(MediaStore.VOLUME_EXTERNAL)
val item = resolver.insert(collection, values)
resolver.openFileDescriptor(item, "w", null).use { pfd ->
// Write data into the pending image.
}
// Now that we're finished, release the "pending" status, and allow other apps
// to view the image.
values.clear()
values.put(MediaStore.Images.Media.IS_PENDING, 0)
resolver.update(item, values, null, null)
Java语言写法
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DISPLAY_NAME, "IMG1024.JPG");
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
values.put(MediaStore.Images.Media.IS_PENDING, 1);
ContentResolver resolver = context.getContentResolver();
Uri collection = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL);
Uri item = resolver.insert(collection, values);
try (ParcelFileDescriptor pfd = resolver.openFileDescriptor(item, "w", null)) {
// Write data into the pending image.
} catch (IOException e) {
e.printStackTrace();
}
// Now that we're finished, release the "pending" status, and allow other apps
// to view the image.
values.clear();
values.put(MediaStore.Images.Media.IS_PENDING, 0);
resolver.update(item, values, null, null);
对存储位置的影响
Android Q引入了多种功能,可帮助您整理应用为外部存储提供的文件。
目录提示
当您的应用在运行Android Q的设备上提供媒体时,默认情况下会根据媒体类型对媒体进行整理。例如,默认情况下,新图像文件放在“图片”目录中。
如果您的应用程序知道应存储文件的特定位置(例如,)Pictures/MyVacationPictures
,则可以设置MediaColumns.RELATIVE_PATH
为系统提供存储新写入文件的位置的提示。同样,您可以update()
通过更改MediaColumns.RELATIVE_PATH
或 在调用期间移动磁盘上的文件 MediaColumns.DISPLAY_NAME
。
设备选择
在Android 9(API级别28)及更低版本中,保存到外部存储设备的所有文件都显示在一个名为的卷下external
。另一方面,Android Q为每个外部存储设备提供唯一的卷名。这个新的命名系统可以帮助您有效地组织和索引内容,并使您可以控制新内容的存储位置。
始终调用主共享存储设备VOLUME_EXTERNAL
。您可以通过致电发现其他卷 MediaStore.getAllVolumeNames()
。
要查询,插入,更新或删除特定卷,请将卷名称传递给API中getContentUri()
可用的任何方法 MediaStore
,例如,在以下代码段中:
Kotlin语言写法
// Publish an audio file onto a specific external storage device.
val values = ContentValues().apply {
put(MediaStore.Audio.Media.RELATIVE_PATH, "Music/My Album/My Song")
put(MediaStore.Audio.Media.DISPLAY_NAME, "My Song.mp3")
}
// Assumes that the storage device of interest is the 2nd one
// that your app recognizes.
val volumeNames = MediaStore.getAllVolumeNames(context)
val selectedVolumeName = volumeNames[1]
val collection = MediaStore.Audio.Media.getContentUri(selectedVolumeName)
val item = resolver.insert(collection, values)
注意:Android Q中不推荐使用该类中的createAccessIntent()
方法StorageVolume
,因此不应使用此方法浏览外部存储设备。如果您这样做,运行Android Q设备的用户将无法在您的应用中查看保存在外部存储中的文件。
Android Q引入了以下新媒体和图形功能以及API:
音频播放捕获
Android Q为应用程序提供了从其他应用程序捕获音频播放的功能。有关完整信息,请参阅捕获播放
原生MIDI API
Android Native MIDI API (AMidi)使应用程序开发人员能够使用C / C ++代码发送和接收MIDI数据,与C / C ++音频/控制逻辑更紧密地集成,并最大限度地减少对JNI的需求。
有关更多信息,请参阅Android Native MIDI API。
MediaCodecInfo的改进
有一些新的方法 MediaCodecInfo
可以揭示有关编解码器的更多信息:
如果编解码器仅在软件中运行,则返回true。软件编解码器不保证渲染性能。
如果编解码器由硬件加速,则返回true。
如果编解码器由设备供应商提供,则返回true;如果由Android平台提供,则返回false。
MediaCodecList
可以使用备用编解码器名称/ s(别名/ es)包含相同底层编解码器的附加条目。如果此条目中的编解码器是另一个编解码器的别名,则此方法返回true。
此外, MediaCodec.getCanonicalName()
返回通过别名创建的编解码器的基础编解码器名称。
绩效点
甲性能点表示编解码器的在特定的高度,宽度和帧速率来呈现视频的能力。例如,UHD_60
性能点表示以每秒60帧的速度渲染的超高清视频(3840x2160像素)。
该方法 MediaCodecInfo.VideoCapabilities.getSupportedPerformancePoints()
返回PerformancePoint
编解码器可以呈现或捕获的条目列表 。
您可以PerformancePoint
通过呼叫检查给定是否覆盖另一个 PerformancePoint.covers(PerformancePoint)
。例如,UHD_60.covers(UHD_50)
返回true。
为所有硬件加速编解码器提供了性能点列表。如果编解码器甚至不满足最低标准性能点,则这可能是空列表。
请注意,已升级到Q但未更新供应商映像的设备将没有性能点数据,因为此数据来自供应商HAL。在这种情况下,getSupportedPerformancePoints()
返回null。
角度
随着Android Q的发布,Android开发人员和合作伙伴可以选择使用ANGLE运行 ,这是Chrome组织中的一个项目,它将ES层叠在Vulkan之上 ,而不是使用供应商提供的ES驱动程序。
有关详细信息,请参阅ANGLE。
负载发热降频 API
当设备过热时,它们可能会限制CPU和/或GPU,这会以意想不到的方式影响应用和游戏。使用复杂图形,繁重计算或持续网络活动的应用程序更容易遇到问题,并且这些问题可能因芯片组和核心频率,集成级别以及设备封装和外形尺寸而异。
现在,在Android Q中,应用和游戏可以使用热API来监控设备上的更改,并采取措施来维持较低的功耗以恢复正常温度。应用程序 在PowerManager中注册一个监听器,系统通过该监听器报告持续的热状态,包括轻度和中度到严重,关键,紧急和关机。
当设备报告热应力时,应用和游戏可以通过支持正在进行的活动来帮助减少各种方式的电力使用。例如,流媒体应用程序可能会降低分辨率/比特率或网络流量,相机应用程序可能会禁用闪存或密集图像增强,游戏可能会降低帧速率或多边形细分,媒体应用程序可能会降低扬声器音量,地图应用程序可能会转关闭GPS。
热量API需要一个新设备HAL层 - 它目前支持运行Android Q的Pixel设备,我们正在与我们的设备制造商合作伙伴尽快为生态系统提供广泛的支持。
相机和图像
Android Q引入了以下与相机和图像相关的新功能:
单色相机支持
Android 9(API等级28)首次推出了单色相机功能。Android Q为单色相机支持增加了几项增强功能:
- 新的Y8流格式支持,以提高内存效率。
- 支持单色原始DNG捕获。
- 介绍MONO和NIR CFA枚举,以区分常规单色相机和近红外相机。
您可以使用此功能捕获本机单色图像。逻辑多相机设备可以使用单色相机作为物理子相机以实现更好的低光图像质量。
动态深度格式
从Android Q开始,摄像机可以使用称为动态深度格式(DDF)的新模式将图像的深度数据存储在单独的文件中。应用可以请求JPG图像及其深度元数据,使用该信息在后处理中应用他们想要的任何模糊,而无需修改原始图像数据。
要阅读新格式的规范,请参阅 动态深度格式。
高效图像文件格式
高效图像文件(HEIF)格式是一种标准的图像和视频格式,与其他文件格式相比,它引入了更高质量的编码和更小的文件大小。
有关文件格式的更多信息,请参阅 HEIC。
多相机的改进
Android Q改进了将多个摄像头融合到单个逻辑摄像头中,这是Android 9(API级别28)中引入的一项功能。以下内容已添加到 Camera2 API:
-
isSessionConfigurationSupported(SessionConfiguration sessionConfig)
- 您可以查询是否可以使用传递的会话配置来创建摄像头捕获会话。 -
LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID
- 您可以确定支持逻辑摄像机设备的活动物理摄像机的ID。您可以使用返回的ID来请求逻辑流和物理子帧流,以实现更高的功效。
辅助功能服务API
Android Q引入了以下新的辅助功能服务功能和API:
AccessibilityNodeInfo条目键标志
在Android Q中,AccessibilityNodeInfo
增强了一个新的标志,指示它是否代表文本输入键。您可以使用该方法访问此标志AccessibilityNodeInfo.isTextEntryKey()
。
可访问性对话框语音反馈
当辅助功能服务要求用户重复辅助功能快捷方式以启动服务时,如果服务请求,则该对话框现在可以伴随文本到语音提示。
物理键盘的辅助功能快捷方式
在Android Q中,用户现在可以通过按下来触发物理键盘上的辅助功能快捷方式Control+Alt+Z。
软键盘控制器增强
在Android Q中,辅助功能服务现在可以请求即使设备检测到连接的硬键盘也会显示软键盘。用户可以覆盖此行为。
用户定义的可访问性超时
Android Q引入了API方法 AccessibilityManager.getRecommendedTimeoutMillis()
,为交互式和非交互式Accessibility UI元素的用户定义超时提供支持。返回值受用户首选项和可访问性服务API的影响。
自动填充改进
Android Q包含对自动填充服务的以下改进。
与兼容性相关的自动填充请求
您现在可以使用该 FillRequest.FLAG_COMPATIBILITY_MODE_REQUEST
标志来确定是否通过兼容模式生成了自动填充请求。
同时保存用户名和密码
您现在可以通过使用该SaveInfo.FLAG_DELAY_SAVE
标志来支持应用程序使用多个活动来显示用户名,密码和其他字段的情况 。
用户与Save UI的交互
现在,您可以通过在对话框上设置动作侦听器并更改相应密码远程视图的可见性,在保存对话框中显示和隐藏密码字段。
支持更新数据集
自动填充现在可以更新现有密码。例如,如果用户已经存储了密码,并且他们保存了新密码,则自动填充现在会提示用户更新现有密码而不是保存新密码。
现场分类改进
Android Q包含对Field Classification API的以下改进。
UserData.Builder构造函数
该 UserData.Builder
构造发生了变化,更好地协调的Builder
格局。
允许将值映射到多种类别的ID
UserData.Builder
在Android Q中使用 时,您现在可以将值映射到多种类别的ID。在以前的版本中,如果多次添加值,则抛出异常。
改进了对信用卡号码的支持
现场分类现在可以检测四位数字作为信用卡号码的最后四位数字。
支持特定于应用的字段分类
Android Q添加 FillResponse.setUserData()
,允许您在会话期间设置特定于应用程序的用户数据。这有助于自动填充服务检测具有应用程序特定内容的字段的类型。
UI和系统控件
Android Q提供以下用户界面改进:
支持JVMTI PopFrame上限
Android Q增加can_pop_frames
了对Android JVMTI实现功能的支持 。在调试时,此功能允许您在断点处暂停并调整本地,全局变量或函数实现后重新运行函数。有关更多信息,请参阅Oracle的Pop框架参考页面。
表面控制API
Android Q提供了一个 SurfaceControl
API,用于对system-compositor(SurfaceFlinger
)的低级访问。对于大多数用户来说,SurfaceView是利用合成器的正确方法。该 SurfaceControl
API可以是在某些情况下是有用的,例如:
- 多个表面的同步
- 跨进程表面嵌入
- 较低级别的生命周期管理
该SurfaceControl
API是既提供 SDK和NDK绑定。NDK实现包括用于与合成器手动交换缓冲区的API。这为遇到限制的用户提供了另一种选择 BufferQueue
。
WebView挂起渲染器检测
Android Q引入了一个新的 WebViewRenderProcessClient
抽象类,应用程序可以使用它来检测是否 WebView
已经无响应。要使用此类:
- 定义你自己的子类并实现其
onRenderProcessResponsive()
与onRenderProcessUnresponsive()
方法。 - 将您的实例附加
WebViewRenderProcessClient
到一个或多个WebView
对象。 - 如果
WebView
没有响应,系统将调用客户端的onRenderProcessUnresponsive()
方法,并传递WebView
和WebViewRenderProcess
。(如果WebView
是单进程,则WebViewRenderProcess
参数为null。)您的应用程序可以采取适当的操作,例如向用户显示一个对话框,询问他们是否要暂停渲染过程。
如果WebView
仍然没有响应,系统会onRenderProcessUnresponsive()
定期调用(每五秒钟不超过一次),但不采取其他操作。如果WebView
再次响应,系统onRenderProcessResponsive()
只调用一次。
设置面板
Android Q引入了“设置面板”,这是一种API,允许应用在应用环境中向用户显示设置。这可以防止用户进入“设置”以更改NFC或移动数据等内容以便使用该应用。
图1.用户尝试在设备未连接到网络时打开网页。Chrome会弹出Internet连接 设置面板...
图2.用户可以在不离开Chrome应用的情况下打开Wi-Fi并选择网络。
例如,假设用户在其设备处于飞行模式时打开Web浏览器。在Android Q之前,该应用只能显示一条通用消息,要求用户打开“设置”以恢复连接。使用Android Q,浏览器应用程序可以显示一个内联面板,显示关键的连接设置,如飞行模式,Wi-Fi(包括附近的网络)和移动数据。使用此面板,用户无需离开应用即可恢复连接。
要显示设置面板,请使用以下新Settings.Panel
操作之一触发意图 :
Kotlin语言写法
val panelIntent = Intent(Settings.Panel.settings_panel_type)
startActivityForResult(panelIntent)
Java语言写法
Intent panelIntent = new Intent(Settings.Panel.settings_panel_type);
startActivityForResult(panelIntent);
settings_panel_type
可以是以下之一:
显示与互联网连接相关的设置,例如飞行模式,Wi-Fi和移动数据。
显示Wi-Fi设置,但不显示其他连接设置。这对于需要Wi-Fi连接以执行大量上传或下载的应用非常有用。
显示与近场通信(NFC)相关的所有设置。
显示所有音频流的音量设置。
我们计划为此功能引入一个AndroidX包装器。在运行Android 9(API级别28)或更低级别的设备上调用时,包装器将在“ 设置”应用中打开最合适的页面。
分享改进
Android Q为共享提供了许多改进。有关完整信息,请参阅AndroidQ分享改进。
黑暗的主题
Android Q提供了一个新的Dark主题,适用于Android系统UI和设备上运行的应用程序。有关完整信息,请参阅黑暗主题。
科特林
Android Q包含Kotlin开发的以下更新。
libcore API的可空性注释
Android Q改进了SDK中针对libcore API的可空性注释的覆盖范围。这些注释使在Android Studio中使用Kotlin或Java可空性分析的应用程序开发人员在与这些API交互时获取空值信息。
通常,Kotlin中的可空性合同违规会导致编译错误。为确保与现有代码兼容,任何新注释仅限于@RecentlyNullable
和@RecentlyNonNull
。这意味着可空性违规会导致警告而不是错误。
此外,Android 9中添加的任何@RecentlyNullable
或@RecentlyNonNull
注释分别更改为@Nullable
和@NonNull
。这意味着现在违反可空性会导致错误而不是警告。
有关注释更改的更多信息,请参阅 Android开发者博客上的Android Pie SDK现在更加Kotlin友好。
NDK
Android Q包含以下NDK更改。
改进了文件描述符所有权的调试
Android Q添加了fdsan,它可以帮助您更轻松地查找和修复文件描述符所有权问题。
与错误处理文件描述符所有权有关的错误(通常表现为使用后关闭和双关闭)类似于内存分配后 使用后免费和双重免费错误,但往往更难以诊断并修复。fdsan试图通过强制执行文件描述符所有权来检测和/或防止文件描述符管理不善。
有关与这些问题相关的崩溃的详细信息,请参阅 fdsan检测到的错误。有关fdsan的更多信息,请参阅fdsan上的Googlesource页面。
ELF TLS
使用具有最低API级别29的NDK构建的应用程序不再需要使用emutls
,但可以改为使用ELF TLS。添加了动态和静态链接器支持以支持处理线程局部变量的新方法。
对于针对API级别28及更低级别构建的应用程序,已经实施了libgcc/compiler-rt
一些改进以解决某些emutls
问题。
有关更多信息,请参阅 NDK开发人员的Android更改。
运行
Android Q包含以下运行时更改。
基于Mallinfo的垃圾收集触发
当小型平台Java对象引用C ++堆中的大对象时,通常只有在收集Java对象时才能回收C ++对象,例如,最终确定。在以前的版本中,平台估计了与Java对象关联的许多C ++对象的大小。这种估计并不总是准确的,偶尔会导致内存使用量大大增加,因为平台无法进行垃圾收集。
在Q中,垃圾收集器(GC)跟踪系统分配的堆的总大小malloc()
,确保大量malloc()
分配始终包含在GC触发计算中。将大量C ++分配与Java执行交错的应用程序可能会导致垃圾收集频率增加。其他应用可能会出现小幅下降。
测试和调试
Android Q包含以下用于测试和调试的改进。
对设备上系统跟踪的改进
现在,您可以在执行设备上系统跟踪时指定跟踪大小和持续时间的限制。指定任一值时,系统将执行长跟踪,并在记录跟踪时定期将跟踪缓冲区复制到目标文件。当达到您指定的大小或持续时间限制时,跟踪完成。
使用这些附加参数来测试不同的用例,而不是使用标准跟踪进行测试。例如,您可能正在诊断性能错误,该错误仅在您的应用程序长时间运行后才会发生。在这种情况下,您可以记录一整天的长跟踪,然后分析报告中的CPU调度程序,磁盘活动,应用程序线程和其他数据,以帮助您确定错误的原因。
TextClassifier的改进
Android Q在TextClassifier
界面中提供了额外的文本分类功能 。
语言检测
TextClassifier
现在以该detectLanguage()
方法为特色 。该方法与现有分类方法类似地工作,接收TextLanguage.Request
对象并返回 TextLanguage
对象。
新TextLanguage
对象由有序对列表组成。每对包含所请求的文本样本的区域设置和相应的置信度分数。
建议的对话操作
TextClassifier
现在以该suggestConversationActions()
方法为特色 。该方法与现有分类方法类似地工作,接收ConversationActions.Request
对象并返回 ConversationActions
对象。
新ConversationActions
对象由ConversationAction
对象列表组成 。每个ConversationAction
对象包括潜在的建议动作及其置信度分数。
通知中的智能回复/操作
Android 9引入了在通知中显示建议回复的功能。从Android Q开始,通知还可以包括建议的基于意图的操作。此外,系统现在可以自动生成这些建议。应用仍然可以提供自己的建议,或选择退出系统生成的建议。
用于生成这些回复的API是TextClassifier
Android Q的一部分 ,也直接向开发人员展示。请阅读 有关TextClassifier改进的部分以 获取更多信息。
如果您的应用提供了自己的建议,则平台不会生成任何自动建议。如果您不希望应用程序的通知显示任何建议的回复或操作,则可以使用setAllowGeneratedReplies()
和 选择退出系统生成的回复和操作setAllowSystemGeneratedContextualActions()
。