> For the complete documentation index, see [llms.txt](https://docs.licensespring.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.licensespring.com/sdks/tutorials/getting-started/.net-c/.net-maui.md).

# .NET MAUI

### Requirements

* **LicenseSpring.NetSDK 8.2.0 or later.**
* **.NET MAUI workloads.** `dotnet workload install maui` from an elevated prompt. `dotnet workload list` then shows `android`, `ios` and `maui-windows`.
* **For the Android head**, a JDK 17 or newer, the Android build needs `jar`, so a JRE is not enough
  * and an Android SDK platform matching your target framework, plus `platform-tools`.
* **For the iOS head**, a Mac to link and package a runnable app.

### Adding the SDK

Add the package to your MAUI project:

```xml
<ItemGroup>
  <PackageReference Include="LicenseSpring.NetSDK" Version="8.2.0" />
</ItemGroup>
```

Or from the CLI:

```
dotnet add package LicenseSpring.NetSDK
```

The package supplies the native hardware-ID library for the platform being built and deploys it alongside your app. On iOS it links the library slice matching what you are building, for both device and simulator builds.

### Target frameworks

Each MAUI target framework uses the SDK assembly for its base .NET version:

<table><thead><tr><th width="500">MAUI target framework</th><th width="178">SDK assembly</th></tr></thead><tbody><tr><td><code>net8.0-android</code>, <code>net8.0-ios</code>, <code>net8.0-windows10.0.19041.0</code></td><td><code>net8.0</code></td></tr><tr><td><code>net9.0-android</code>, <code>net9.0-ios</code>, <code>net9.0-windows10.0.19041.0</code></td><td><code>net9.0</code></td></tr><tr><td><code>net10.0-android</code>, <code>net10.0-ios</code>, <code>net10.0-windows10.0.19041.0</code></td><td><code>net10.0</code></td></tr></tbody></table>

Earlier MAUI target frameworks resolve the same way, against the `net6.0` and `net7.0` assemblies.

The sample sets these `SupportedOSPlatformVersion` values, which are a working starting point:

<table data-header-hidden><thead><tr><th width="346"></th><th width="332"></th></tr></thead><tbody><tr><td>Platform</td><td><code>SupportedOSPlatformVersion</code></td></tr><tr><td>iOS</td><td>15.0</td></tr><tr><td>Android</td><td>21.0</td></tr><tr><td>Windows</td><td>10.0.17763.0</td></tr></tbody></table>

### Device ID

An activation is bound to a device ID. Select the algorithm and read `Configuration.HardwareID`; the SDK resolves the value on all three heads and caches it into `ExtendedOptions.HardwareID`.

```csharp
configuration.ExtendedOptions.DeviceIdAlgorithm = DeviceIDAlgorithm.HardwareIdGeneratorDefault;
string deviceId = configuration.HardwareID;
```

What `DeviceIDAlgorithm.HardwareIdGeneratorDefault` resolves per head:

<table><thead><tr><th width="218">Head</th><th width="514">Device ID</th></tr></thead><tbody><tr><td>Windows</td><td>Computer System Product ID (SMBIOS UUID)</td></tr><tr><td>Android</td><td>Derived from <code>Settings.Secure.ANDROID_ID</code></td></tr><tr><td>iOS</td><td>Resolved through the native library included in the package</td></tr></tbody></table>

On Android, plan for one platform behaviour before you ship: since Android 8.0, `ANDROID_ID` is scoped to your app's signing key, and it is reset by a factory reset. Changing signing keys (debug to release, or a Play App Signing key rotation) therefore changes the device ID, and licenses activated under the previous key have to be reactivated. For the same reason, the value your app sees differs from the one `adb shell settings get secure android_id` reports.

### Activating a license

Initialize the license manager once, then activate:

```csharp
ExtendedOptions options = new ExtendedOptions();
options.DeviceIdAlgorithm = DeviceIDAlgorithm.HardwareIdGeneratorDefault;

Configuration configuration = new Configuration(
    apiKey: apiKey,
    sharedKey: sharedKey,
    productCode: productCode,
    appName: appName,
    appVersion: appVersion,
    extendedOptions: options );

ILicenseManager licenseManager = LicenseManager.GetInstance();
licenseManager.Initialize( configuration );

// Network calls belong on a worker thread, keeping the UI thread free.
await Task.Run( () => licenseManager.ActivateLicense( LicenseID.FromKey( licenseKey ) ) );

ILicense license = licenseManager.CurrentLicense();
if ( license.IsValid() )
{
    // The app is licensed.
}
```

On later runs, the license already on the device is available from `CurrentLicense()`. A local check validates it without a network call, which suits app start-up on a mobile device; `Check()` re-validates it against the LicenseSpring platform.

```csharp
ILicense license = licenseManager.CurrentLicense();
if ( license != null )
{
    license.LocalCheck();

    // Online, when you want the platform's current answer.
    await Task.Run( () => license.Check() );
}
```

### Sample application

The distribution zip contains **`samples/MauiSample`** - a MAUI app covering configuration, activation, license check, consumption and deactivation on Android, iOS and Windows, with its own README for building and running each head.

### Coming from Xamarin.Forms

.NET MAUI is the successor to Xamarin.Forms, which Microsoft stopped supporting in May 2024. Start new cross-platform work from `samples/MauiSample`; it keeps the page decomposition of `samples/XamarinSample`: a tabbed activation screen, plus separate license-info, settings and product-details pages, so the two line up screen for screen while you migrate.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.licensespring.com/sdks/tutorials/getting-started/.net-c/.net-maui.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
