Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions UI/AndroidUpdate/AndroidUpdate.slnx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<Solution>
<Project Path="src/AndroidUpdate.Android/AndroidUpdate.Android.csproj" />
</Solution>
33 changes: 33 additions & 0 deletions UI/AndroidUpdate/src/AndroidUpdate.Android/AndroidApp.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using Android.App;
using Android.Runtime;
using AndroidUpdate.ViewModels;
using Avalonia;
using Avalonia.Android;

namespace AndroidUpdate.Android;

[global::Android.App.Application]
public class AndroidApp : AvaloniaAndroidApplication<App>
{
protected AndroidApp(nint javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
{
// Read real app version from package manager as early as possible
try
{
var pkgInfo = PackageManager?.GetPackageInfo(PackageName!, 0);
if (pkgInfo?.VersionName != null)
App.DeviceVersion = pkgInfo.VersionName;
}
catch { /* fallback to default "1.0.0.0" */ }
}

protected override AppBuilder CustomizeAppBuilder(AppBuilder builder)
{
// Register the Android-specific handler factory before Avalonia starts
App.HandlerFactory = (packageInfo, currentVersion) =>
new Services.AndroidUpdateHandler(packageInfo, currentVersion);

return base.CustomizeAppBuilder(builder)
.WithInterFont();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0-android</TargetFramework>
<SupportedOSPlatformVersion>23</SupportedOSPlatformVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<LangVersion>latest</LangVersion>
<ApplicationId>com.generalupdate.androidupdate</ApplicationId>
<ApplicationVersion>7</ApplicationVersion>
<ApplicationDisplayVersion>1.0.0.0</ApplicationDisplayVersion>
<ApplicationTitle>AndroidUpdate</ApplicationTitle>
<AndroidPackageFormat>apk</AndroidPackageFormat>
<AndroidEnableProfiledAot>false</AndroidEnableProfiledAot>
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Avalonia" Version="12.0.3" />
<PackageReference Include="Avalonia.Android" Version="12.0.3" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="12.0.3" />
<PackageReference Include="Avalonia.Fonts.Inter" Version="12.0.3" />
<PackageReference Include="AvaloniaUI.DiagnosticsSupport" Version="2.2.1">
<IncludeAssets Condition="'$(Configuration)' != 'Debug'">None</IncludeAssets>
<PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets>
</PackageReference>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageReference Include="Xamarin.AndroidX.Core.SplashScreen" Version="1.0.1.15" />
<AndroidResource Include="Icon.png">
<Link>Resources\drawable\Icon.png</Link>
</AndroidResource>
<AndroidResource Include="Resources\xml\file_paths.xml" />
<AndroidResource Include="Resources\xml\network_security_config.xml" />
</ItemGroup>

<!-- Reference the compiled GeneralUpdate.Avalonia.Android DLL -->
<ItemGroup>
<Reference Include="GeneralUpdate.Avalonia.Android">
<HintPath>libs\GeneralUpdate.Avalonia.Android.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
14 changes: 14 additions & 0 deletions UI/AndroidUpdate/src/AndroidUpdate.Android/App.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:AndroidUpdate"
x:Class="AndroidUpdate.App"
RequestedThemeVariant="Default">

<Application.DataTemplates>
<local:ViewLocator/>
</Application.DataTemplates>

<Application.Styles>
<FluentTheme />
</Application.Styles>
</Application>
59 changes: 59 additions & 0 deletions UI/AndroidUpdate/src/AndroidUpdate.Android/App.axaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using System;
using System.Net.Http;
using AndroidUpdate.ViewModels;
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;

namespace AndroidUpdate;

public partial class App : Avalonia.Application
{
/// <summary>
/// Static factory for creating platform-specific update handlers.
/// Set by the Android project (or other platform projects) during startup.
/// </summary>
public static Func<PackageInfo, string, IAndroidUpdateHandler>? HandlerFactory { get; set; }

/// <summary>
/// The device's currently installed app version.
/// Set by the platform project on startup; falls back to "1.0.0.0".
/// </summary>
public static string DeviceVersion { get; set; } = "1.0.0.0";

public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
}

public override void OnFrameworkInitializationCompleted()
{
var httpClient = new HttpClient();
httpClient.Timeout = TimeSpan.FromSeconds(30);

MainViewViewModel CreateViewModel() =>
new(httpClient, (pkg, ver) =>
{
if (HandlerFactory == null)
throw new InvalidOperationException(
"HandlerFactory not set. Ensure the platform project initializes it.");
return HandlerFactory(pkg, ver);
});

if (ApplicationLifetime is IActivityApplicationLifetime singleViewFactory)
{
// Android: use MainViewFactory for Activity-based lifetime
singleViewFactory.MainViewFactory = () =>
new Views.MainView { DataContext = CreateViewModel() };
}
else if (ApplicationLifetime is ISingleViewApplicationLifetime singleViewPlatform)
{
singleViewPlatform.MainView = new Views.MainView
{
DataContext = CreateViewModel()
};
}

base.OnFrameworkInitializationCompleted();
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions UI/AndroidUpdate/src/AndroidUpdate.Android/MainActivity.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using Android.App;
using Android.Content.PM;
using Avalonia;
using Avalonia.Android;

namespace AndroidUpdate.Android;

[Activity(
Label = "AndroidUpdate",
Theme = "@style/MyTheme.NoActionBar",
MainLauncher = true,
ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize | ConfigChanges.UiMode)]
public class MainActivity : AvaloniaMainActivity
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.generalupdate.androidupdate"
android:versionCode="7"
android:versionName="1.0.0.0">
<uses-sdk android:minSdkVersion="23" android:targetSdkVersion="36" />
<application android:label="AndroidUpdate"
android:theme="@style/MyTheme.NoActionBar"
android:usesCleartextTraffic="true">
Comment thread
Copilot marked this conversation as resolved.
Outdated
<!-- FileProvider for APK installation -->
<provider android:name="androidx.core.content.FileProvider"
android:authorities="com.generalupdate.androidupdate.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>
<!-- Required for APK installation on Android 8+ -->
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<!-- Internet access for downloading updates -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- Write external storage for download directory -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28" />
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<animated-vector
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt">
<aapt:attr name="android:drawable">
<vector
android:name="vector"
android:width="128dp"
android:height="128dp"
android:viewportWidth="128"
android:viewportHeight="128">
<group
android:name="wrapper"
android:translateX="21"
android:translateY="21">
<group android:name="group">
<path
android:name="path"
android:pathData="M 74.853 85.823 L 75.368 85.823 C 80.735 85.823 85.144 81.803 85.761 76.602 L 85.836 41.76 C 85.225 18.593 66.254 0 42.939 0 C 19.24 0 0.028 19.212 0.028 42.912 C 0.028 66.357 18.831 85.418 42.18 85.823 L 74.853 85.823 Z"
android:strokeWidth="1"/>
<path
android:name="path_1"
android:pathData="M 43.059 14.614 C 29.551 14.614 18.256 24.082 15.445 36.743 C 18.136 37.498 20.109 39.968 20.109 42.899 C 20.109 45.831 18.136 48.301 15.445 49.055 C 18.256 61.716 29.551 71.184 43.059 71.184 C 47.975 71.184 52.599 69.93 56.628 67.723 L 56.628 70.993 L 71.344 70.993 L 71.344 44.072 C 71.357 43.714 71.344 43.26 71.344 42.899 C 71.344 27.278 58.68 14.614 43.059 14.614 Z M 29.51 42.899 C 29.51 35.416 35.576 29.35 43.059 29.35 C 50.541 29.35 56.607 35.416 56.607 42.899 C 56.607 50.382 50.541 56.448 43.059 56.448 C 35.576 56.448 29.51 50.382 29.51 42.899 Z"
android:strokeWidth="1"
android:fillType="evenOdd"/>
<path
android:name="path_2"
android:pathData="M 18.105 42.88 C 18.105 45.38 16.078 47.407 13.579 47.407 C 11.079 47.407 9.052 45.38 9.052 42.88 C 9.052 40.381 11.079 38.354 13.579 38.354 C 16.078 38.354 18.105 40.381 18.105 42.88 Z"
android:strokeWidth="1"/>
</group>
</group>
</vector>
</aapt:attr>
<target android:name="path">
<aapt:attr name="android:animation">
<objectAnimator
android:propertyName="fillColor"
android:duration="1000"
android:valueFrom="#00ffffff"
android:valueTo="#161c2d"
android:valueType="colorType"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
</aapt:attr>
</target>
<target android:name="path_1">
<aapt:attr name="android:animation">
<objectAnimator
android:propertyName="fillColor"
android:duration="1000"
android:valueFrom="#00ffffff"
android:valueTo="#f9f9fb"
android:valueType="colorType"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
</aapt:attr>
</target>
<target android:name="path_2">
<aapt:attr name="android:animation">
<objectAnimator
android:propertyName="fillColor"
android:duration="1000"
android:valueFrom="#00ffffff"
android:valueTo="#f9f9fb"
android:valueType="colorType"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
</aapt:attr>
</target>
</animated-vector>
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<animated-vector
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt">
<aapt:attr name="android:drawable">
<vector
android:name="vector"
android:width="128dp"
android:height="128dp"
android:viewportWidth="128"
android:viewportHeight="128">
<group
android:name="wrapper"
android:translateX="21"
android:translateY="21">
<group android:name="group">
<path
android:name="path"
android:pathData="M 74.853 85.823 L 75.368 85.823 C 80.735 85.823 85.144 81.803 85.761 76.602 L 85.836 41.76 C 85.225 18.593 66.254 0 42.939 0 C 19.24 0 0.028 19.212 0.028 42.912 C 0.028 66.357 18.831 85.418 42.18 85.823 L 74.853 85.823 Z"
android:fillColor="#00ffffff"
android:strokeWidth="1"/>
<path
android:name="path_1"
android:pathData="M 43.059 14.614 C 29.551 14.614 18.256 24.082 15.445 36.743 C 18.136 37.498 20.109 39.968 20.109 42.899 C 20.109 45.831 18.136 48.301 15.445 49.055 C 18.256 61.716 29.551 71.184 43.059 71.184 C 47.975 71.184 52.599 69.93 56.628 67.723 L 56.628 70.993 L 71.344 70.993 L 71.344 44.072 C 71.357 43.714 71.344 43.26 71.344 42.899 C 71.344 27.278 58.68 14.614 43.059 14.614 Z M 29.51 42.899 C 29.51 35.416 35.576 29.35 43.059 29.35 C 50.541 29.35 56.607 35.416 56.607 42.899 C 56.607 50.382 50.541 56.448 43.059 56.448 C 35.576 56.448 29.51 50.382 29.51 42.899 Z"
android:fillColor="#00ffffff"
android:strokeWidth="1"
android:fillType="evenOdd"/>
<path
android:name="path_2"
android:pathData="M 18.105 42.88 C 18.105 45.38 16.078 47.407 13.579 47.407 C 11.079 47.407 9.052 45.38 9.052 42.88 C 9.052 40.381 11.079 38.354 13.579 38.354 C 16.078 38.354 18.105 40.381 18.105 42.88 Z"
android:fillColor="#00ffffff"
android:strokeWidth="1"/>
</group>
</group>
</vector>
</aapt:attr>
<target android:name="path_2">
<aapt:attr name="android:animation">
<objectAnimator
android:propertyName="fillColor"
android:startOffset="100"
android:duration="900"
android:valueFrom="#00ffffff"
android:valueTo="#161c2d"
android:valueType="colorType"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
</aapt:attr>
</target>
<target android:name="path">
<aapt:attr name="android:animation">
<objectAnimator
android:propertyName="fillColor"
android:duration="500"
android:valueFrom="#00ffffff"
android:valueTo="#f9f9fb"
android:valueType="colorType"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
</aapt:attr>
</target>
<target android:name="path_1">
<aapt:attr name="android:animation">
<objectAnimator
android:propertyName="fillColor"
android:startOffset="100"
android:duration="900"
android:valueFrom="#00ffffff"
android:valueTo="#161c2d"
android:valueType="colorType"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
</aapt:attr>
</target>
</animated-vector>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

<item>
<color android:color="@color/splash_background"/>
</item>

<item android:drawable="@drawable/icon"
android:width="120dp"
android:height="120dp"
android:gravity="center" />

</layer-list>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="splash_background">#212121</color>
</resources>
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8" ?>
<resources>

<style name="MyTheme">
</style>

<style name="MyTheme.NoActionBar" parent="@style/Theme.AppCompat.NoActionBar">
<item name="android:windowActionBar">false</item>
<item name="android:windowBackground">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowSplashScreenBackground">@color/splash_background</item>
<item name="android:windowSplashScreenAnimatedIcon">@drawable/avalonia_anim</item>
<item name="android:windowSplashScreenAnimationDuration">1000</item>
<item name="postSplashScreenTheme">@style/MyTheme.Main</item>

</style>
<style name="MyTheme.Main"
parent ="MyTheme.NoActionBar">
<item name="android:windowIsTranslucent">true</item>
</style>
</resources>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="splash_background">#FFFFFF</color>
</resources>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8" ?>
<resources>

<style name="MyTheme">
</style>

<style name="MyTheme.NoActionBar" parent="@style/Theme.AppCompat.DayNight.NoActionBar">
<item name="android:windowActionBar">false</item>
<item name="android:windowBackground">@drawable/splash_screen</item>
<item name="android:windowNoTitle">true</item>
</style>
</resources>
Loading
Loading