调用需要 API 级别 26(当前最低为 23):java.time.Instant#now
Posted
技术标签:
【中文标题】调用需要 API 级别 26(当前最低为 23):java.time.Instant#now【英文标题】:Call requires API level 26 (current min is 23): java.time.Instant#now 【发布时间】:2019-08-28 06:36:21 【问题描述】:我正在实施Google's Directions API。我的应用支持minSdkVersion 23
,这里不支持java.time.Instant
。
是否有解决方案,或者我应该只检查用户的版本并在其版本受支持时允许此功能?
DirectionsResult directionsResult = DirectionsApi.newRequest(geoApiContext)
.mode(TravelMode.DRIVING)
.origin(new com.google.maps.model.LatLng(mapFragment.getUserCoords().latitude, mapFragment.getUserCoords().longitude))
.destination(tabHandlerCommunication.destinationBarCoords)
.departureTime(Instant.now()) // <-- error here
.await();
错误:
少... (Ctrl+F1) 检查信息:此检查扫描所有 应用程序中的 android API 调用并警告任何调用 不适用于此应用程序所针对的所有版本 (根据清单中的最小 SDK 属性)。如果你 真的很想使用这个 API 并且不需要支持旧设备 只需在 build.gradle 或 AndroidManifest.xml 中设置 minSdkVersion 文件。如果您的代码故意访问较新的 API,并且您 已确保(例如通过条件执行)此代码将 只能在受支持的平台上调用,然后您可以注释 带有 @TargetApi 注释的类或方法指定 要应用的本地最小 SDK,例如 @TargetApi(11),这样 check 将 11 而不是清单文件的最小 SDK 视为 所需的 API 级别。如果你故意设置android: 样式定义中的属性,请确保将其放在 values-vNN 文件夹,以避免遇到运行时冲突 制造商添加了自定义属性的某些设备 id 与后来平台上的新 id 冲突。同样,您可以 在 XML 文件中使用 tools:targetApi="11" 来指示元素 只有在适当的情况下才会膨胀。问题 ID:NewApi
【问题讨论】:
Is there a solution for this
是的。更新minSdk
或使用java.time.Instant
以外的其他东西
@MarcinOrlowski 更好的解决方案是将 ThreeTenABP 库添加到您的 Android 项目中,以获取大部分 java.time 的后向端口功能。请参阅Answer by Ole V.V.。
【参考方案1】:
如果您使用的是 Gradle 插件 4.0 或更高版本(Android Studio 4.0 或更高版本),则可以利用 D8 Core Library Desugaring。这包括java.time
中的部分功能,并允许您在项目中使用java.time.Instant
;即使您需要支持 API 26 之前的版本。
在您模块的build.gradle
文件中:
android
compileOptions
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
coreLibraryDesugaringEnabled true
// If using Kotlin
kotlinOptions
jvmTarget = JavaVersion.VERSION_1_8
dependencies
…
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.5'
您现在应该可以无错误地使用此类。
一些来源:
Styling Android Jake Wharton Android Developers【讨论】:
完美。它还允许使用其他有用的 API,例如流 不适用于 AS 4.2 Beta 6。构建失败,出现以下 Gradle 6.4.1 / AGP 4.0.2 异常:>No signature of method: build_dvug2jv3jezfh5oc48zh5hqe.android() is applicable for argument types: (build_dvug2jv3jezfh5oc48zh5hqe$_run_closure1) values: [build_dvug2jv3jezfh5oc48zh5hqe$_run_closure1@752d785a]
后续问题提交:github.com/StylingAndroid/Time/issues/1
该链接已损坏。
Java 8+ API 脱糖支持:developer.android.com/studio/write/java8-support【参考方案2】:
查看了developer guide,原来是String
now
,
以及常见的int
UNIX 纪元时间戳,都是可接受的值:
departure_time
— 指定所需的出发时间。您可以将时间指定为自世界标准时间 1970 年 1 月 1 日午夜开始的整数秒。或者,您可以指定一个值now
,它将出发时间设置为当前时间(精确到最接近的秒数)。
在检查Java
客户端的source code时,有一个方便的方法:
public DirectionsApiRequest departureTimeNow()
return param("departure_time", "now");
因此可以绕过java.time.Instant
,以实现向后兼容性。
我已经提交了issue #559... 分叉库似乎是设置其他时间戳的唯一方法。
【讨论】:
【参考方案3】:您可以在 Android API 级别 23 上使用 Instant 类和 java.time 中的其他类
java.time 在较旧和较新的 Android 设备上都能很好地工作。它只需要至少 Java 6。
在 Java 8 及更高版本以及更新的 Android 设备(从 API 级别 26 起)中,现代 API 是内置的。 在非 Android 的 Java 6 和 7 中,获取 ThreeTen Backport,这是现代类的后向端口(对于 JSR 310,ThreeTen;请参阅底部的链接)。 在(旧版)Android 上使用 ThreeTen Backport 的 Android 版本。它被称为 ThreeTenABP。并确保从org.threeten.bp
导入日期和时间类以及子包。
链接
Oracle tutorial: Date Time 解释如何使用 java.time。 Java Specification Request (JSR) 310,其中首次描述了java.time
。
ThreeTen Backport project,java.time
的反向移植到 Java 6 和 7(JSR-310 的 ThreeTen)。
ThreeTenABP,Android 版 ThreeTen Backport
Question: How to use ThreeTenABP in Android Project,解释得很透彻。
【讨论】:
【参考方案4】:我在这里写了解决此问题的推荐方法:https://dev.to/cicerohellmann/what-is-desugaring-and-why-would-i-need-it-2bo0
但简单来说,你应该使用脱糖,它允许你在较低级别使用一些高级 API。值得检查。我还添加了所有链接以找到实现它的方法以及关于它的一些优点和缺点
【讨论】:
【参考方案5】:没有其他方法可以做到这一点。您不能使用需要更高 SDK 版本和更低版本的 API。
您应该将应用级别 build.gradle
中的 minSdkVersion
属性从 23 文件更改为 26。
【讨论】:
这样的答案没有考虑到 OP 的约束。更改受支持的minSdkVersion
在技术上“很简单”,但有许多非技术原因可能不那么容易做到。以上是关于调用需要 API 级别 26(当前最低为 23):java.time.Instant#now的主要内容,如果未能解决你的问题,请参考以下文章
调用需要 API 级别 23(当前最低为 14):android.app.Activity#requestPermissions,checkSelfPermission [重复]
调用需要 API 级别 24(当前最低为 8):新的 android.location.GnssStatus.Callback
setAdapter“调用需要 API 级别 11(当前最低为 8):android.widget.AbsListView#setAdapter”?
调用需要 API 级别 21(当前最低为 17):android.hardware.camera2.CameraDevice.StateCallback