diff --git a/src/HuaweiHMSInstaller.csproj b/src/HuaweiHMSInstaller.csproj index 11b477e..d87e5d0 100644 --- a/src/HuaweiHMSInstaller.csproj +++ b/src/HuaweiHMSInstaller.csproj @@ -117,6 +117,8 @@ + + @@ -136,6 +138,9 @@ + + + diff --git a/src/MauiProgram.cs b/src/MauiProgram.cs index 7051ab0..5992e31 100644 --- a/src/MauiProgram.cs +++ b/src/MauiProgram.cs @@ -8,6 +8,7 @@ using HuaweiHMSInstaller.Services; using HuaweiHMSInstaller.ViewModels; using LocalizationResourceManager.Maui; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using Syncfusion.Maui.Core.Hosting; @@ -62,6 +63,7 @@ public static MauiApp CreateMauiApp() builder.Services.ConfigureServices(); // builder.Services.RegisterAnalyticsObservers(); // 👈 this is where we register the observers builder.RegisterViews(); + builder.RegisterConfiguration(); var app = builder.Build(); // app.Services.ConfigureAnalyticsSubject(); // 👈 this is where we configure the subject @@ -126,4 +128,27 @@ private static void RegisterAnalyticsObservers(this IServiceCollection services) services.AddSingleton(typeof(IAnalyticsObserver), type); } } + private static void RegisterConfiguration(this MauiAppBuilder appBuilder) + { + const string resourceName = "HuaweiHMSInstaller.appsettings.json"; + + var assembly = Assembly.GetExecutingAssembly(); + using var stream = assembly.GetManifestResourceStream(resourceName); + + if (stream != null) + { + var configuration = new ConfigurationBuilder() + .AddJsonStream(stream) + .Build(); + + configuration["Settings:ProjectOperationPath"] = Path.Combine(Path.GetTempPath(), "HuaweiHMSInstaller"); //add data to configuration + + appBuilder.Configuration.AddConfiguration(configuration); + + } + else + { + throw new FileNotFoundException($"Resource {resourceName} not found."); + } + } } \ No newline at end of file diff --git a/src/Models/AppSettings.cs b/src/Models/AppSettings.cs new file mode 100644 index 0000000..8c03dee --- /dev/null +++ b/src/Models/AppSettings.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuaweiHMSInstaller.Models +{ + public class AppSettings + { + public string ProjectOperationPath { get; set; } + public string VersionNumber { get; set; } + public string SponsorGameAppId { get; set; } = "C106234721"; //C104193349 + public string YoutuberChanneName { get; set; } + } +} diff --git a/src/Pages/DownloadandInstallPage.xaml.cs b/src/Pages/DownloadandInstallPage.xaml.cs index 922c18e..75292bf 100644 --- a/src/Pages/DownloadandInstallPage.xaml.cs +++ b/src/Pages/DownloadandInstallPage.xaml.cs @@ -5,6 +5,7 @@ using HuaweiHMSInstaller.Services; using HuaweiHMSInstaller.ViewModels; using LocalizationResourceManager.Maui; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Options; using System.Diagnostics; using System.Text; @@ -51,14 +52,17 @@ public partial class DownloadandInstallPage : ContentPage, IQueryAttributable private readonly IAdbOperationService _adbOperationService; private readonly IAppGalleryService _appGalleryService; - private readonly GlobalOptions _options; + private readonly AppSettings _settings; private readonly ILocalizationResourceManager _localizationResourceManager; - private readonly IHttpClientFactory _httpClient; private readonly DownloadAndInstallPageViewModel _viewModel; private readonly AnalyticsSubject _analyticsSubject; - public DownloadandInstallPage(DownloadAndInstallPageViewModel viewModel, AnalyticsSubject analyticsSubject) + + public DownloadandInstallPage( + DownloadAndInstallPageViewModel viewModel, + AnalyticsSubject analyticsSubject, + IConfiguration configuration) { Connectivity.ConnectivityChanged += Connectivity_ConnectivityChanged; @@ -66,8 +70,7 @@ public DownloadandInstallPage(DownloadAndInstallPageViewModel viewModel, Analyti _adbOperationService = ServiceProvider.GetService(); _appGalleryService = ServiceProvider.GetService(); _localizationResourceManager = ServiceProvider.GetService(); - _options = ServiceProvider.GetService>().Value; - _httpClient = ServiceProvider.GetService(); + _settings = configuration.GetSection("Settings").Get(); _analyticsSubject = analyticsSubject; _viewModel = viewModel; this.NavigatedTo += (s, e) => Initialize(); @@ -208,7 +211,7 @@ private async Task ResettingDownloadApkOperationAsync() this.timerReconnect.IsVisible = false; var totalApp = AdbProgressMessages.Where(x => x.Value).ToDictionary(x => x.Key, x => x.Value).Keys.Count; //7 - var files = Directory.GetFiles(_options.ProjectOperationPath); + var files = Directory.GetFiles(_settings.ProjectOperationPath); foreach (var record in apkRecords) { @@ -386,7 +389,7 @@ private void CheckInternetAccess(object sender, bool result) ///TODO If lost internet connection when download apk, try again connecting it automaticaLly one time but can't connect show an error popup. private async ValueTask DownloadHMSAppsAsync() { - Directory.CreateDirectory(_options.ProjectOperationPath); + Directory.CreateDirectory(_settings.ProjectOperationPath); apkRecords = new List { new($"{nameof(HmsCore)}.apk", HmsCore, AdbMessagesConst.DownloadingHMSCore), @@ -432,7 +435,7 @@ await Parallel.ForEachAsync(apkRecords, parallelOptions, async (model, i) => } private async Task CheckApkFileSizeAsync(InstallApkModel model) { - var filePath = Path.Combine(_options.ProjectOperationPath, model.Name); + var filePath = Path.Combine(_settings.ProjectOperationPath, model.Name); var exist = File.Exists(filePath); if (exist) { @@ -451,7 +454,7 @@ private async Task CheckApkFileSizeAsync(InstallApkModel model) } private void CheckApkFileExist(InstallApkModel model) { - var filePath = Path.Combine(_options.ProjectOperationPath, model.Name); + var filePath = Path.Combine(_settings.ProjectOperationPath, model.Name); var exist = File.Exists(filePath); if (exist) { @@ -510,7 +513,7 @@ private async Task InstallHmsAppsAsync(DeviceData device) UpdateHMSInfoLabel(); }; //var p = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), apkPaths[i]); - apkPaths[i] = Path.Combine(_options.ProjectOperationPath, apkPaths[i]); + apkPaths[i] = Path.Combine(_settings.ProjectOperationPath, apkPaths[i]); await InstallApkToDeviceAsync(apkPaths[i], progressHMSApps, device); } diff --git a/src/Pages/MainPage.xaml.cs b/src/Pages/MainPage.xaml.cs index da596cf..cb1d36d 100644 --- a/src/Pages/MainPage.xaml.cs +++ b/src/Pages/MainPage.xaml.cs @@ -5,6 +5,7 @@ using HuaweiHMSInstaller.Services; using HuaweiHMSInstaller.ViewModels; using LocalizationResourceManager.Maui; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Options; using Microsoft.Maui.Controls.Shapes; using Syncfusion.Maui.Popup; @@ -23,7 +24,7 @@ public partial class MainPage : ContentPage private SearchListItem SelectedItem { get; set; } private Frame SearchListFrame; private readonly ILocalizationResourceManager _localizationResourceManager; - private readonly GlobalOptions _options; + private readonly AppSettings _settings; private readonly MainViewModel _mainViewModel; private readonly AnalyticsSubject _analyticsSubject; @@ -33,14 +34,14 @@ public MainPage( IAppGalleryService appGalleryService, ILocalizationResourceManager localizationResourceManager, AnalyticsSubject analyticsSubject, - IOptions options) + IConfiguration configuration) { Connectivity.ConnectivityChanged += Connectivity_ConnectivityChanged; InitializeComponent(); _appGalleryService = appGalleryService; _localizationResourceManager = localizationResourceManager; - _options = options.Value; + _settings = configuration.GetSection("Settings").Get(); _mainViewModel = mainViewModel; _analyticsSubject = analyticsSubject; Init(); @@ -50,7 +51,7 @@ private void Init() this.langPicker.SelectedItem = _localizationResourceManager.CurrentCulture.TwoLetterISOLanguageName.ToUpper(); this.searchBar.BackgroundColor = Color.FromRgba(255, 255, 255, 0.1); this.SearchListFrameGrid.BackgroundColor = Color.FromRgba(255, 255, 255, 0.05); - this.VersionNum.Text = $"{_localizationResourceManager.GetValue("version")}: {_options.VersionNumber}"; + this.VersionNum.Text = $"{_localizationResourceManager.GetValue("version")}: {_settings.VersionNumber}"; _mainViewModel.Init(CheckInternetConnectionAction); _mainViewModel.AfterEventInternetAndHuaweiServiceCheck = AfterEventInternetAndHuaweiServiceCheck; @@ -134,7 +135,7 @@ private void Button_Retry_Clicked(object sender, EventArgs e) private async Task GetSponsorGameInfo() { - var gameAppId = _options.SponsorGameAppId; + var gameAppId = _settings.SponsorGameAppId; if (gameAppId != null) { this.selectedGameFrame.IsVisible = true; @@ -663,7 +664,7 @@ private void langPicker_SelectedIndexChanged(object sender, EventArgs e) _localizationResourceManager.CurrentCulture = new CultureInfo(picker.SelectedItem.ToString()); - this.VersionNum.Text = $"{_localizationResourceManager.GetValue("version")}: {_options.VersionNumber}"; + this.VersionNum.Text = $"{_localizationResourceManager.GetValue("version")}: {_settings.VersionNumber}"; this.sponsorGameStackLayout.IsVisible = false; this.sponsorGameNotInternetorHuaweiService.IsVisible = false; diff --git a/src/Services/AdbOperationService.cs b/src/Services/AdbOperationService.cs index 9dd7b90..554b09c 100644 --- a/src/Services/AdbOperationService.cs +++ b/src/Services/AdbOperationService.cs @@ -8,6 +8,7 @@ using AdvancedSharpAdbClient.Exceptions; using HuaweiHMSInstaller.Helper; using HuaweiHMSInstaller.Models; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Options; using static AdvancedSharpAdbClient.DeviceCommands.PackageManager; @@ -25,16 +26,16 @@ public class AdbOperationService : IAdbOperationService // Dependency injection to create HttpClient, AdbClient, Options instances private readonly IHttpClientFactory _httpClient; private AdbClient _adbClient; - private readonly GlobalOptions _options; + private readonly AppSettings _settings; public AdbOperationService( - IHttpClientFactory httpClient, - IOptions options) + IHttpClientFactory httpClient, + IConfiguration configuration) { - _options = options.Value; + _settings = configuration.GetSection("AppSettings").Get(); _httpClient = httpClient; NetworkChange.NetworkAvailabilityChanged += OnNetworkAvailabilityChanged; - adbPath = Path.Combine(_options.ProjectOperationPath, AdbFolder, "platform-tools", "adb.exe"); + adbPath = Path.Combine(_settings.ProjectOperationPath, AdbFolder, "platform-tools", "adb.exe"); } public async Task CreateAdbClient() { @@ -85,19 +86,19 @@ public async Task DownloadAdbFromInternetAsync(IProgress progress = null) string fileName = Path.GetFileName(AdbUrl); //if folder not exist create folder - Directory.CreateDirectory(_options.ProjectOperationPath); + Directory.CreateDirectory(_settings.ProjectOperationPath); // Create a file stream to store the downloaded data - using (var file = new FileStream(Path.Combine(_options.ProjectOperationPath, fileName), FileMode.Create, FileAccess.Write, FileShare.None, 8192, true)) + using (var file = new FileStream(Path.Combine(_settings.ProjectOperationPath, fileName), FileMode.Create, FileAccess.Write, FileShare.None, 8192, true)) { // Download the file using the custom extension method await _httpClient.DownloadAsync(AdbUrl, file, progress); } // Extract the file to the destination folder - ZipFile.ExtractToDirectory(Path.Combine(_options.ProjectOperationPath, fileName), Path.Combine(_options.ProjectOperationPath, AdbFolder),true); + ZipFile.ExtractToDirectory(Path.Combine(_settings.ProjectOperationPath, fileName), Path.Combine(_settings.ProjectOperationPath, AdbFolder),true); // Delete the file - File.Delete(Path.Combine(_options.ProjectOperationPath, fileName)); + File.Delete(Path.Combine(_settings.ProjectOperationPath, fileName)); } public async Task> GetDevices() { @@ -112,7 +113,7 @@ public async Task DownloadApkFromInternetAsync(string apkUrl, string apkName, IP try { // Create a file stream to store the downloaded data - using (var file = new FileStream(Path.Combine(_options.ProjectOperationPath, apkName), FileMode.Create, FileAccess.Write, FileShare.None, 8192, true)) + using (var file = new FileStream(Path.Combine(_settings.ProjectOperationPath, apkName), FileMode.Create, FileAccess.Write, FileShare.None, 8192, true)) { // Add try-catch block to handle NetworkErrorException try diff --git a/src/ViewModels/DownloadAndInstallPageViewModel.cs b/src/ViewModels/DownloadAndInstallPageViewModel.cs index c7b2eca..5f1d5b4 100644 --- a/src/ViewModels/DownloadAndInstallPageViewModel.cs +++ b/src/ViewModels/DownloadAndInstallPageViewModel.cs @@ -5,6 +5,7 @@ using HuaweiHMSInstaller.Models; using HuaweiHMSInstaller.Pages; using HuaweiHMSInstaller.Services; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Options; using System.Diagnostics; using System.Text; @@ -14,7 +15,7 @@ namespace HuaweiHMSInstaller.ViewModels public sealed partial class DownloadAndInstallPageViewModel : BaseViewModel, IQueryAttributable { private readonly IAdbOperationService _adbOperationService; - private readonly GlobalOptions _options; + private readonly AppSettings _settings; private readonly AnalyticsSubject _analyticsSubject; private readonly IHttpClientFactory _httpClient; @@ -40,14 +41,14 @@ public sealed partial class DownloadAndInstallPageViewModel : BaseViewModel, IQu public DownloadAndInstallPageViewModel( INavigationService navigationService, IAdbOperationService adbOperationService, - IOptions options, AnalyticsSubject analyticsSubject, - IHttpClientFactory httpClient) + IHttpClientFactory httpClient, + IConfiguration configuration) : base(navigationService) { Debug.WriteLine($"**** {this.GetType().Name}.{nameof(DownloadAndInstallPageViewModel)}: ctor"); _adbOperationService = adbOperationService; - _options = options.Value; + _settings = configuration.GetSection("Settings").Get(); _httpClient = httpClient; _analyticsSubject = analyticsSubject; _analyticsSubject.Notify("Download and Install Page Loaded"); @@ -71,8 +72,8 @@ public void ApplyQueryAttributes(IDictionary query) private void Init() { AdbProgressMessages = AdbMessagesConst.InitializeMessages(); - adbPath = Path.Combine(_options.ProjectOperationPath, AdbFolder, "platform-tools", "adb.exe"); - adbFolderPath = Path.Combine(_options.ProjectOperationPath, AdbFolder); + adbPath = Path.Combine(_settings.ProjectOperationPath, AdbFolder, "platform-tools", "adb.exe"); + adbFolderPath = Path.Combine(_settings.ProjectOperationPath, AdbFolder); } public async void NavigateToThanksPage() diff --git a/src/ViewModels/MainViewModel.cs b/src/ViewModels/MainViewModel.cs index f90b063..192f76e 100644 --- a/src/ViewModels/MainViewModel.cs +++ b/src/ViewModels/MainViewModel.cs @@ -3,7 +3,6 @@ using HuaweiHMSInstaller.Models; using HuaweiHMSInstaller.Pages; using HuaweiHMSInstaller.Services; -using System.Text; namespace HuaweiHMSInstaller.ViewModels { @@ -11,7 +10,6 @@ public class MainViewModel : BaseViewModel { private readonly AnalyticsSubject _analyticsSubject; private readonly IAppGalleryService _appGalleryService; - public SearchListItem SearchListItem { get; set; } public Worker.WorkCompletedEventHandler AfterEventInternetAndHuaweiServiceCheck { get; set; } diff --git a/src/appsettings.json b/src/appsettings.json new file mode 100644 index 0000000..c270953 --- /dev/null +++ b/src/appsettings.json @@ -0,0 +1,7 @@ +{ + "Settings": { + "VersionNumber": "0.0.0.1", + "SponsorGameAppId": "C106234721", + "YoutuberChanneName": "Huawei" + } +} \ No newline at end of file