2.26.3.2
What's changed
Same native SDK — dd-sdk-android 2.26.3
— with a documentation correction that changes which apps can use this line at all, and a set of
convenience overloads for the members that only look awkward from C#.
Package versions are
<dd-sdk-android version>.<binding revision>.2.26.3.2is
dd-sdk-android2.26.3, binding revision2. Nothing about the native artifacts changed.
Every one of these came out of building
DatadogNet, a cross-platform façade over these packages
and the iOS ones. Calling both SDKs through the same shape is what surfaced them.
⚠️ The minimum API level is 23, not 21
This corrects the 2.26.3.1 release notes and the README, and it removes one of the two reasons
those gave for choosing the 2.x line over 3.x.
The .aar manifests do declare minSdkVersion 21, and that is where the figure came from. It is
not reachable. Those .aars depend on an AndroidX generation in which androidx.savedstate 1.4.0
declares minSdkVersion 23, and the Android manifest merger takes the maximum across the whole
dependency graph rather than trusting the direct dependency. An app declaring 21 does not merely
misbehave on Android 5 — it fails to build:
uses-sdk:minSdkVersion 21 cannot be smaller than version 23 declared in library
… androidx.savedstate.savedstate-android.aar
Suggestion: use a compatible library with a minSdk of at most 21,
or increase this project's minSdk version to at least 23,
or use tools:overrideLibrary="androidx.savedstate" to force usage
(may lead to runtime failures)
So an app that still supports Android 5 or 5.1 cannot use these packages, and switching to the
3.x line costs it nothing on that count.
The tools:overrideLibrary escape is not recommended. It forces the library in and, as the error
itself says, may fail at runtime instead — a worse trade for the two API levels it buys.
The other reason to prefer 2.x is unaffected: tracing is still OpenTracing-based, and 3.0
removed it. That remains the deciding difference between the lines.
Nothing in the packages changed for this. It is a documentation fix, and it is here rather than in a
quiet README edit because an app on minSdk 21 will have discovered it as a build failure.
Added
DatadogAttributes.ToJava is public
The per-value converter behind DatadogAttributes.From. Several members take a bare value rather
than a map — RumMonitor.addAttribute, addFeatureFlagEvaluation, Logs.addAttribute,
Logger.addAttribute — and until now reaching them meant either hand-wrapping the value, which is
what DatadogAttributes exists to avoid, or round-tripping a one-element dictionary through
From to get at the result.
monitor.AddAttribute("build.channel", DatadogAttributes.ToJava("beta", "build.channel"));Or, better, through the new overloads below, which do it for you.
RUM convenience overloads
monitor.AddAttribute("build.channel", "beta");
monitor.AddFeatureFlagEvaluation("new-checkout", true);
monitor.StartResource("checkout", RumResourceMethod.Post, "https://api.example.com/orders");
monitor.StopResource("checkout", statusCode: 200, size: 1024, RumResourceKind.Native);
monitor.StopResourceWithError("checkout", exception);
var sessionId = await monitor.GetCurrentSessionIdAsync();StopResource takes int? and long? rather than Java.Lang.Integer and Java.Lang.Long. The
generated overload uses the Java boxes because both are nullable in Kotlin, so a C# caller has to
box through ValueOf and remember that null means "not known" rather than zero. Nullable value
types say the same thing in the language you are already writing.
GetCurrentSessionIdAsync is the one worth having. The generated GetCurrentSessionId takes a
kotlin.jvm.functions.Function1, which C# cannot express as a lambda at all — it binds as an
interface, so calling it means declaring a Java.Lang.Object subclass that implements IFunction1
and returns null for Kotlin's Unit. That is a lot of ceremony for a value most apps want in
order to paste it into a support ticket.
StopResourceWithError guards a non-null Kotlin parameter
RumMonitor.stopResourceWithError declares stackTrace: String — not String? — while
errorType beside it is nullable and addErrorWithStacktrace takes a nullable stack. The generated
C# signature shows all three as plain string, so nothing distinguishes them, and passing null for
the wrong one throws at runtime:
NullPointerException: Parameter specified as non-null is null: method
DatadogRumMonitor.stopResourceWithError, parameter stackTrace
The new overload takes string? and substitutes empty, so the C# signature says what Kotlin meant.
This is not a binding defect — the projection is faithful — but being faithful to Kotlin loses
information a C# caller needs, and the convenience layer is the right place to put it back.
Tracing convenience overloads
New in DatadogNet.Trace.Android, as Com.Datadog.Android.Trace.TracingExtensions:
using Com.Datadog.Android.Trace;
span.SetError(exception);
span.SetError("CheckoutError", "declined", stack);
span.Log(new Dictionary<string, object?> { ["event"] = "checkout.started" });
var headers = GlobalTracer.Get().InjectHeaders(span);SetError has no counterpart in io.opentracing.Span — dd-sdk-ios's OTSpan has one, this
does not. The Datadog convention on the Java side is an error tag plus four specific log fields,
which dd-trace turns into the span's error facets, and getting the field names wrong produces a span
that looks fine and is never counted as an error.
InjectHeaders exists because the obvious way silently produces nothing.
new TextMapInjectAdapter(myDictionary) compiles, runs, and gives you an empty dictionary: the
adapter's constructor takes an IDictionary<string, string>, which the binding marshals by
copying into a fresh java.util.HashMap. The SDK writes the headers into the copy, the managed
dictionary never sees them, and the request goes out untraced with no error anywhere.
InjectHeaders implements ITextMapInject instead, so the SDK calls back into managed code.
Log(IReadOnlyDictionary<string, object?>) is here because io.opentracing.Span.log takes
Map<String, ?>, which the binding projects as IDictionary<string, object> — a different
dictionary type from the IDictionary<string, Java.Lang.Object> every Datadog member takes, so
DatadogAttributes.From's output cannot be passed to it directly.
Logger.AddAttribute taking a plain value
logger.AddAttribute("session.kind", "e2e");Compatibility
No breaking changes. Every generated member is still there and every existing call still
compiles; the additions sit alongside them. Upgrading from 2.26.3.1 is a version bump.
Verified
All twelve packages pack across net8.0-android34.0, net9.0-android35.0 and
net10.0-android36.0 — except DatadogNet.SessionReplayCompose.Android, which is net9/net10 only.
The package-layout tests and the on-emulator smoke checks pass against the packed packages.
The new members are additionally exercised on an emulator by
DatadogNet's device checks, which drive them through a
cross-platform façade alongside the iOS equivalents.
Full changelog: v2.26.3.1...v2.26.3.2
Packages
Bound against dd-sdk-android 2.26.3, targeting net8.0-android34.0, net9.0-android35.0 and net10.0-android36.0.
The first three components of
2.26.3.2are the dd-sdk-android version; the fourth is this
repository's binding revision, which advances when the bindings or packaging change while
the native binaries stay put.
| Package | Wraps | NuGet |
|---|---|---|
DatadogNet.Internal.Android |
dd-sdk-android-internal |
2.26.3.2 |
DatadogNet.Core.Android |
dd-sdk-android-core |
2.26.3.2 |
DatadogNet.Logs.Android |
dd-sdk-android-logs |
2.26.3.2 |
DatadogNet.OpenTracing.Android |
opentracing-api |
2.26.3.2 |
DatadogNet.Trace.Android |
dd-sdk-android-trace |
2.26.3.2 |
DatadogNet.RUM.Android |
dd-sdk-android-rum |
2.26.3.2 |
DatadogNet.SessionReplay.Android |
dd-sdk-android-session-replay |
2.26.3.2 |
DatadogNet.SessionReplayMaterial.Android |
dd-sdk-android-session-replay-material |
2.26.3.2 |
DatadogNet.SessionReplayCompose.Android |
dd-sdk-android-session-replay-compose |
2.26.3.2 |
DatadogNet.Ndk.Android |
dd-sdk-android-ndk |
2.26.3.2 |
DatadogNet.WebView.Android |
dd-sdk-android-webview |
2.26.3.2 |
DatadogNet.OkHttp.Android |
dd-sdk-android-okhttp |
2.26.3.2 |
dotnet add package DatadogNet.RUM.Android --version 2.26.3.2
Licensing
The binding code is MIT; the bundled native binaries are Apache-2.0, as built and
published by Datadog. Each package ships both texts under licenses/.