ExzileGames.AndroidAppUpdateBridge
1.0.25
dotnet add package ExzileGames.AndroidAppUpdateBridge --version 1.0.25
NuGet\Install-Package ExzileGames.AndroidAppUpdateBridge -Version 1.0.25
<PackageReference Include="ExzileGames.AndroidAppUpdateBridge" Version="1.0.25" />
<PackageVersion Include="ExzileGames.AndroidAppUpdateBridge" Version="1.0.25" />
<PackageReference Include="ExzileGames.AndroidAppUpdateBridge" />
paket add ExzileGames.AndroidAppUpdateBridge --version 1.0.25
#r "nuget: ExzileGames.AndroidAppUpdateBridge, 1.0.25"
#:package ExzileGames.AndroidAppUpdateBridge@1.0.25
#addin nuget:?package=ExzileGames.AndroidAppUpdateBridge&version=1.0.25
#tool nuget:?package=ExzileGames.AndroidAppUpdateBridge&version=1.0.25
AndroidAppUpdateBridge
A Java bridge + C# interop library for the Google Play In-App Updates API on .NET Android. Supports both immediate and flexible update flows with clean async C# wrappers.
Problem
The Xamarin binding for com.google.android.play:app-update has a GC lifetime bug: InstallStateUpdatedListener instances created in C# can be collected by the Mono GC mid-update because nothing on the managed heap holds a strong reference once the call site returns. This causes silent failures during flexible update downloads.
Solution
A compiled Java class (AppUpdateBridge) holds a strong reference to the InstallStateUpdatedListener as a Java field, keeping it alive for the entire download lifecycle. C# communicates with it via auto-generated JNI bindings — no reflection needed.
Setup
1. Add NuGet package
dotnet add package ExzileGames.AndroidAppUpdateBridge
2. Initialize in your Activity
using AndroidAppUpdateBridge.Interop;
protected override void OnCreate(Bundle? savedInstanceState)
{
base.OnCreate(savedInstanceState);
AppUpdateBridgeManager.SetImplementation(new AndroidAppUpdateBridgeImpl(this));
}
3. Use from shared code
using AndroidAppUpdateBridge.Interop;
var info = await AppUpdateBridgeManager.CheckForUpdateAsync();
if (info.Availability == UpdateAvailability.UpdateAvailable)
{
if (info.ImmediateAllowed)
{
// Blocks the user until the update is installed
var result = await AppUpdateBridgeManager.StartImmediateUpdateAsync();
}
else if (info.FlexibleAllowed)
{
// Downloads in the background; prompt user to restart when ready
var progress = new Progress<FlexibleUpdateProgress>(p =>
{
if (p.IsDownloaded)
AppUpdateBridgeManager.CompleteFlexibleUpdate();
});
var result = await AppUpdateBridgeManager.StartFlexibleUpdateAsync(progress);
}
}
Update Types
| Type | Behaviour |
|---|---|
| Immediate | Full-screen UI blocks the app until the update is installed. Best for critical updates. |
| Flexible | Downloads in the background while the user continues using the app. Call CompleteFlexibleUpdate() once IsDownloaded is true to trigger installation. |
License
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-android36.0 is compatible. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- No dependencies.
-
net10.0-android36.0
- Xamarin.Google.Android.Play.App.Update (>= 2.1.0.18)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.