通话要求 API 等级 26(当前最低等级为 23):java.time.Instant#now

Call requires API level 26 (current min is 23): java.time.Instant#now

我正在实施 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();

错误:

Call requires API level 26 (current min is 23): java.time.Instant#now less... (Ctrl+F1) Inspection info:This check scans through all the Android API calls in the application and warns about any calls that are not available on all versions targeted by this application (according to its minimum SDK attribute in the manifest). If you really want to use this API and don't need to support older devices just set the minSdkVersion in your build.gradle or AndroidManifest.xml files. If your code is deliberately accessing newer APIs, and you have ensured (e.g. with conditional execution) that this code will only ever be called on a supported platform, then you can annotate your class or method with the @TargetApi annotation specifying the local minimum SDK to apply, such as @TargetApi(11), such that this check considers 11 rather than your manifest file's minimum SDK as the required API level. If you are deliberately setting android: attributes in style definitions, make sure you place this in a values-vNN folder in order to avoid running into runtime conflicts on certain devices where manufacturers have added custom attributes whose ids conflict with the new ones on later platforms. Similarly, you can use tools:targetApi="11" in an XML file to indicate that the element will only be inflated in an adequate context. Issue id: NewApi

没有其他方法可以做到这一点。您不能使用需要较高 SDK 版本和较低版本的 API。

您应该将应用级别 build.gradle 中的 minSdkVersion 属性 从 23 文件更改为 26。

看了developer guide后发现,Stringnow

以及常见的 int UNIX 纪元时间戳,都是可接受的值:

departure_time — Specifies the desired time of departure. You can specify the time as an integer in seconds since midnight, January 1, 1970 UTC. Alternatively, you can specify a value of now, which sets the departure time to the current time (correct to the nearest second).

检查Java客户端的source code时,有一个方便的方法:

public DirectionsApiRequest departureTimeNow() {
    return param("departure_time", "now");
}

因此java.time.Instant可以绕过,为了向后兼容。


我已经提交 issue #559...分叉库似乎是设置其他时间戳的唯一方法。

您可以在 Android API 级别 23

上使用来自 java.time 的 Instant class 和其他 classes

java.time 在新旧 Android 设备上都能很好地工作。它只需要至少 Java 6.

  • 在 Java 8 和更新的 Android 设备上(从 API 级别 26)内置现代 API。
  • 在非Android Java 6 和 7 中获取 ThreeTen Backport,现代 classes 的 backport(ThreeTen 用于 JSR 310;请参阅底部的链接) .
  • 在(较旧的)Android 使用 ThreeTen Backport 的 Android 版本。它叫做 ThreeTenABP。并确保使用子包从 org.threeten.bp 导入日期和时间 classes。

链接

如果您使用的是 Gradle 插件 4.0 或更高版本(使用 Android Studio 4.0 或更高版本),您可以利用 D8 核心库脱糖。这包括 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'
}

您现在应该可以使用此 class 错误。

一些来源:

我在这里写了解决这个问题的推荐方法:https://dev.to/cicerohellmann/what-is-desugaring-and-why-would-i-need-it-2bo0

但简而言之,你应该使用脱糖,它允许你在较低级别使用一些高级 api。值得检查。我还添加了所有链接以找到 ho 来实现它以及它的一些优点和缺点