SFMCSDK.Net.Android 3.1.1.1

dotnet add package SFMCSDK.Net.Android --version 3.1.1.1
                    
NuGet\Install-Package SFMCSDK.Net.Android -Version 3.1.1.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SFMCSDK.Net.Android" Version="3.1.1.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SFMCSDK.Net.Android" Version="3.1.1.1" />
                    
Directory.Packages.props
<PackageReference Include="SFMCSDK.Net.Android" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SFMCSDK.Net.Android --version 3.1.1.1
                    
#r "nuget: SFMCSDK.Net.Android, 3.1.1.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package SFMCSDK.Net.Android@3.1.1.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=SFMCSDK.Net.Android&version=3.1.1.1
                    
Install as a Cake Addin
#tool nuget:?package=SFMCSDK.Net.Android&version=3.1.1.1
                    
Install as a Cake Tool

SFMCSDK.Net.Android

NuGet release Targets: net8.0 | net9.0 | net10.0 sfmcsdk 3.1.1 Licence: MIT AND BSD-3-Clause

.NET for Android bindings for the Salesforce Marketing Cloud SFMC SDK core module (com.salesforce.marketingcloud:sfmcsdk) — identity, event tracking, logging, and the module plumbing the MobilePush module plugs into.

dotnet add package SFMCSDK.Net.Android
using Com.Salesforce.Marketingcloud.Sfmcsdk;

var config = new SFMCSdkModuleConfig.Builder().Build();

// The Action overload is this package's addition - natively this takes a Kotlin Function1.
SFMCSdk.Configure(Android.App.Application.Context, config, status =>
    Console.WriteLine($"SFMC SDK initialization: {status}"));

SFMCSdk.RequestSdk(sdk =>
    sdk.Identity = sdk.Identity.NewBuilder().SetProfileId("contact-key").Build());

Push notifications live in the sibling MarketingCloudSDK.Net.Android, which depends on this package the same way the native MobilePush module depends on sfmcsdk. A cross-platform ergonomic layer lives in SFMCSDK.Net.


Contents

Packages

Package Wraps Depends on What it is for
SFMCSDK.Net.Android sfmcsdk 3.1.1 (+ common-internal 1.0.0, unbound) Xamarin.Kotlin.StdLib, AndroidX, Play services basement The SFMC SDK core: SFMCSdk.Configure, identity, custom events, logging

Versions are <sfmcsdk version>.<binding revision>3.1.1.1 is sfmcsdk 3.1.1, binding revision 1. The fourth component belongs to this repository and moves when the binding or packaging changes over an unchanged native SDK.

What is bound

The whole public surface of sfmcsdk, generated by class-parse with Java-package-derived namespaces (com.salesforce.marketingcloud.sfmcsdkCom.Salesforce.Marketingcloud.Sfmcsdk), so a type's C# name can always be derived from its Kotlin one. On top of the generated tier, Additions/ supplies the pieces raw JNI makes painful:

Instead of Write
a Java.Lang.Object, IFunction1 subclass per callback SFMCSdk.Configure(context, config, status => …)
a Java.Lang.Object, ISFMCSdkReadyListener subclass SFMCSdk.RequestSdk(sdk => …)

common-internal ships inside this package as an unbound .aar — it is Salesforce-internal plumbing the SDK needs on the classpath, with no public API worth a projection. The deliberately-unbound roster, with reasons, lives in build/packages.tsv.

Installing

<PackageReference Include="SFMCSDK.Net.Android" Version="3.1.1.1" />

Target frameworks: net8.0-android34.0, net9.0-android35.0, net10.0-android36.0. The SFMC SDK's own floor is Android 8.0 (API 26).

net8 note. The AndroidX generation sfmcsdk 3.x depends on has partially dropped net8 assets; the net8 head pins Xamarin.AndroidX.Lifecycle.Process one minor below the .pom (2.9.4 vs 2.10.0), which is API-stable for what the SDK reaches. The net9/net10 heads carry the .pom-exact versions and are the ones Java dependency verification runs on.

Usage

Everything is the raw binding, in the same shapes Salesforce's Kotlin documentation uses. Initialize once, early — Application.OnCreate in a plain app, MauiProgram in MAUI:

SFMCSdk.SetLogging(LogLevel.Debug!, myListener);          // optional, before Configure
SFMCSdk.Configure(context, new SFMCSdkModuleConfig.Builder().Build(), status => { });

Identity (v3 is an immutable record — rebuild and assign):

SFMCSdk.RequestSdk(sdk =>
    sdk.Identity = sdk.Identity.NewBuilder()
        .SetProfileId("contact-key")
        .PutAttribute("tier", "gold")
        .Build());

Custom events:

var checkout = EventManager.CustomEvent(
    "checkout_completed",
    new Dictionary<string, Java.Lang.Object> { ["total"] = 42.50 });
SFMCSdk.Track(checkout);

Reach for the generated namespaces directly when you need something these snippets do not show — nothing is hidden.

How this repository works

Nothing native is committed. @(AndroidMavenLibrary) resolves sfmcsdk and common-internal straight from Salesforce's own Maven repository (salesforce-marketingcloud.github.io — the group is not on Maven Central), feeds the SDK's Java dependency verification, and every resolved byte is checked against the SHA-256 pins in build/maven-checksums.txt. The net8 head predates @(AndroidMavenLibrary) and takes a DownloadFile fallback with the same pins.

Each .NET SDK's Android workload builds two target frameworks, so build/BuildNugets.sh packs twice (net9 band, then net10 from a scratch global.json) and build/merge-packages.py grafts the net10 assets into one package.

Layout

Path What
src/Sfmc.Binding.props Everything the binding project(s) share: TFM bands, Maven resolution, checksum verification, packaging
src/SFMCSDK.Net.Android/ The binding: Transforms/, Additions/, consumer R8 rules under buildTransitive/
build/ Pack, checksum, R8-rule and upgrade scripts; packages.tsv is the package roster
tests/ PackageTests (nupkg shape, no workloads needed) and DeviceTests (a bare Activity driving the real SDK on an emulator)
samples/ A MAUI app driving initialization, identity and events
.github/workflows/ pr (beta to nuget.org), release (tag → nuget.org + GitHub release), auto-release (merged release note → tag), upstream-drift/upstream-watch

Building locally

./build/BuildNugets.sh                  # packs 3.1.1.1 into ./artifacts
dotnet test tests/SFMCSDK.Net.Android.PackageTests

The sample needs the .NET 10 SDK (MAUI 9 cannot build against this AndroidX generation):

cd "$(mktemp -d)" && dotnet new globaljson --sdk-version 10.0.100 --roll-forward latestFeature
dotnet build <repo>/samples/SFMCSDK.Net.Android.Example -c Debug

Tests

dotnet test tests/SFMCSDK.Net.Android.PackageTests    # nupkg layout, deps, checks the merge
./.github/scripts/run-emulator-tests.sh 3.1.1.1 net9.0-android35.0        # needs a running emulator
./.github/scripts/run-emulator-tests.sh 3.1.1.1 net9.0-android35.0 r8    # the shrunk leg

The device tests run without credentials on purpose: they prove the native classes are present, the JNI surface works and the Kotlin callback bridges fire — not that a tenant accepts the traffic.

Upgrading the SFMC SDK

./build/BumpNativeVersion.sh 3.2.0

which pins, re-checksums, regenerates R8 rules, packs and tests — then review what it prints that it does not automate (checksum diff review, Transforms re-validation, README pins, release notes). The upstream-watch workflow files an issue when Salesforce ships a version this repository does not bind.

Releasing

Merging a file named docs/release-notes/<four-part-version>.md to main is the release: auto-release tags it, release packs with verification off (the PR that merged it already verified), pushes to nuget.org via trusted publishing (OIDC — no stored API key) and creates the GitHub release with those notes. Every PR also publishes a -beta.<pr>.<run> prerelease of the full set.

Troubleshooting

ClassNotFoundException in Release builds only. Your app shrinks with R8 and something stripped the SDK. The package ships consumer keep-rules under buildTransitive/ that attach automatically; if you maintain your own -keep configuration make sure it does not override them.

XA4241: Java dependency ... is not satisfied. A .pom dependency has no NuGet binding in your app's graph. The package declares everything sfmcsdk 3.1.1 needs; if you see this after adding other Android bindings, your graph resolved an AndroidX version below the .pom's floor.

Restore fails with NU1301 about a missing artifacts source. The repository's NuGet.config declares ./artifacts as a local feed for samples and device tests. Run ./build/BuildNugets.sh once, or build your own project outside this repository.

Licence

The binding code in this repository is MIT. The native SFMC SDK artifacts inside the package are © Salesforce, BSD-3-Clause. The package licence expression is MIT AND BSD-3-Clause and both texts ship in every package under licenses/.

Product Compatible and additional computed target framework versions.
.NET net8.0-android34.0 is compatible.  net9.0-android was computed.  net9.0-android35.0 is compatible.  net10.0-android was computed.  net10.0-android36.0 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on SFMCSDK.Net.Android:

Package Downloads
MarketingCloudSDK.Net.Android

.NET for Android bindings for the Salesforce Marketing Cloud MobilePush module (com.salesforce.marketingcloud:marketingcloudsdk) - push registration, inbox, in-app messages, geofence and beacon messaging - plus the modular feature .aars of the Unified SDK architecture. Successor to the sfmc-net-bindings-mobile packages, at the v11 generation.

SFMCSDK.Net

One cross-platform API for the Salesforce Marketing Cloud SFMC SDK core: awaitable initialization, identity (contact key and attributes) and custom event tracking on Android and iOS from shared code, over the SFMCSDK.Net.Android and SFMCSDK.Net.iOS bindings. Restores on plain target frameworks too, so shared class libraries and unit tests need no platform conditionals.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
3.1.1.1 0 7/30/2026
3.1.1.1-beta.5.7 0 7/30/2026
3.1.1.1-beta.5.6 0 7/30/2026
3.1.1.1-beta.4.8 0 7/30/2026
3.1.1.1-beta.4.5 0 7/30/2026
3.1.1.1-beta.2.4 0 7/30/2026
3.1.1.1-beta.1.3 0 7/30/2026
1.0.5.8 8,319 10/30/2024
1.0.5.6 219 10/7/2024
1.0.3.10 716 7/12/2024
1.0.3.4 177 7/12/2024
1.0.3.3 293 5/20/2024
1.0.3.2 199 5/17/2024

## What's changed

First release of the rebuilt binding, at the Unified SDK generation.

- Binds **sfmcsdk 3.1.1** (was 1.x in the retired `sfmc-net-bindings-mobile` packages), ships
 `common-internal` 1.0.0 alongside it, resolved from Salesforce's own Maven repository and
 SHA-256-pinned on every build.
- Target frameworks `net8.0-android34.0`, `net9.0-android35.0`, `net10.0-android36.0` — real
 multi-targeting; the old net7-era `sed`-the-TFM packaging is gone, as is the `.targets` hack
 that copied natives inside the restored package folder.
- New `Additions/`: `SFMCSdk.Configure(..., Action<IInitializationStatus>)` and
 `SFMCSdk.RequestSdk(Action<SFMCSdk>)`, replacing the hand-rolled Kotlin `Function1`
 boilerplate every consumer previously carried.
- Consumer R8 keep-rules ship under `buildTransitive/` — Release builds that shrink no longer
 lose the SDK's JNI-only entry points.
- Migrating from `1.x`: the identity API is now an immutable record
 (`sdk.Identity = sdk.Identity.NewBuilder()...Build()`), logging takes an `ILogListener`, and
 the SDK's floor is Android 8.0 (API 26). Kotlin-derived namespaces are unchanged.