using Android.App; using Android.Content; using Android.Content.PM; using Android.Database; using Android.OS; using Android.Provider; using Android.Views; using AndroidX.Core.View; using LMEMappeCatastaliApp.Services; namespace LMEMappeCatastaliApp; [Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, LaunchMode = LaunchMode.SingleTop, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)] [IntentFilter([Intent.ActionView], Categories = [Intent.CategoryDefault, Intent.CategoryBrowsable], DataMimeType = "application/json")] [IntentFilter([Intent.ActionView], Categories = [Intent.CategoryDefault, Intent.CategoryBrowsable], DataMimeType = "application/geo+json")] [IntentFilter([Intent.ActionView], Categories = [Intent.CategoryDefault, Intent.CategoryBrowsable], DataMimeType = "application/geojson")] [IntentFilter([Intent.ActionView], Categories = [Intent.CategoryDefault, Intent.CategoryBrowsable], DataMimeType = "application/vnd.google-earth.kml+xml")] [IntentFilter([Intent.ActionView], Categories = [Intent.CategoryDefault, Intent.CategoryBrowsable], DataMimeType = "application/vnd.google-earth.kmz")] [IntentFilter([Intent.ActionView], Categories = [Intent.CategoryDefault, Intent.CategoryBrowsable], DataMimeType = "application/xml")] [IntentFilter([Intent.ActionView], Categories = [Intent.CategoryDefault, Intent.CategoryBrowsable], DataMimeType = "text/xml")] [IntentFilter([Intent.ActionView], Categories = [Intent.CategoryDefault, Intent.CategoryBrowsable], DataMimeType = "application/zip")] [IntentFilter([Intent.ActionView], Categories = [Intent.CategoryDefault, Intent.CategoryBrowsable], DataMimeType = "application/x-zip-compressed")] [IntentFilter([Intent.ActionView], Categories = [Intent.CategoryDefault, Intent.CategoryBrowsable], DataMimeType = "application/octet-stream")] public class MainActivity : MauiAppCompatActivity { protected override void OnCreate(Bundle? savedInstanceState) { base.OnCreate(savedInstanceState); ApplySystemBarInsets(); QueueViewedFile(Intent); } private void ApplySystemBarInsets() { var content = FindViewById(Android.Resource.Id.Content); if (content is null) return; ViewCompat.SetOnApplyWindowInsetsListener(content, new SystemBarInsetsListener(content)); ViewCompat.RequestApplyInsets(content); } protected override void OnNewIntent(Intent? intent) { base.OnNewIntent(intent); Intent = intent; QueueViewedFile(intent); } private void QueueViewedFile(Intent? intent) { if (intent?.Action == Intent.ActionView && intent.Data is not null) { _ = CopyViewedFileAsync(intent); } } private async Task CopyViewedFileAsync(Intent intent) { try { var uri = intent.Data!; var fileName = ReadDisplayName(uri) ?? $"file-{Guid.NewGuid():N}"; fileName = string.Concat(fileName.Select(character => Path.GetInvalidFileNameChars().Contains(character) ? '_' : character)); var directory = Path.Combine(FileSystem.CacheDirectory, "Incoming"); Directory.CreateDirectory(directory); var path = Path.Combine(directory, $"{Guid.NewGuid():N}-{fileName}"); await using var input = ContentResolver!.OpenInputStream(uri) ?? throw new IOException("Impossibile leggere il file selezionato."); await using var output = File.Create(path); await input.CopyToAsync(output); IncomingFileService.Shared.Enqueue(new IncomingFile(path, fileName, intent.Type)); } catch (Exception error) { System.Diagnostics.Debug.WriteLine($"Apertura file LME non riuscita: {error}"); } } private string? ReadDisplayName(Android.Net.Uri uri) { if (uri.Scheme == ContentResolver.SchemeFile) { return Path.GetFileName(uri.Path); } using ICursor? cursor = ContentResolver?.Query(uri, [IOpenableColumns.DisplayName], null, null, null); if (cursor is null || !cursor.MoveToFirst()) { return null; } var index = cursor.GetColumnIndex(IOpenableColumns.DisplayName); return index >= 0 ? cursor.GetString(index) : null; } private sealed class SystemBarInsetsListener(Android.Views.View content) : Java.Lang.Object, IOnApplyWindowInsetsListener { private readonly int _left = content.PaddingLeft; private readonly int _top = content.PaddingTop; private readonly int _right = content.PaddingRight; public WindowInsetsCompat? OnApplyWindowInsets(Android.Views.View? view, WindowInsetsCompat? insets) { if (view is null || insets is null) return insets; var systemBars = insets.GetInsets(WindowInsetsCompat.Type.SystemBars()); view.SetPadding( _left, systemBars?.Top ?? _top, _right, systemBars?.Bottom ?? 0); return insets; } } }