Per lo sviluppo per Windows Phone, Visual Studio 2010 e l'emulatore sono due ottimi strumenti che permettono un facile debugging e testing delle applicazioni. La maggior parte delle caratteristiche sono simulate, come effettuare chiamate oppure ruotare il dispositivo, ma non è possibile testare il GPS incorporato nel dispositivo.
Questo in realtà non è un problema, perché la soluzione più rapida è sicuramente provare sul dispositivo fisico. Questa pratica però è scomoda e non permette di simulare situazioni o avere dati con un significato valido, perciò è utile poter sviluppare un finto GPS che permetta di testare l'applicazione creando una situazione verosimile.
Tutto questo è possibile grazie all'interfaccia IGeoPositionWatcher
IGeoPositionWatcher<GeoCoordinate> watcher; if (Microsoft.Devices.Environment.DeviceType == Microsoft.Devices.DeviceType.Device) { watcher = new GeoCoordinateWatcher(); } else { watcher = new FakeGeoPositionWatcher(); } // Intercetto gli eventi e avvio watcher.StatusChanged += new EventHandler<GeoPositionStatusChangedEventArgs>(watcher_StatusChanged); watcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(watcher_PositionChanged); watcher.Start();
L'implementazione di FakeGeoPositionWatcher non fa altro che supportare gli eventi StatusChanged e PositionChanged, e scatenare ad intervalli regolari il cambio di posizione simulando lo spostamento del segnale GPS. Di seguito l'implementazione completa:
public class FakeGeoPositionWatcher : IGeoPositionWatcher<GeoCoordinate> { private AsyncOperation operation; private Timer timer; // Posizione iniziale private GeoPosition<GeoCoordinate> position = new GeoPosition<GeoCoordinate>(DateTimeOffset.Now, new GeoCoordinate(45.477827, 9.310956, 0, 30, 30, 0, 0)); public GeoPosition<GeoCoordinate> Position { get { return position; } } public GeoPositionStatus Status { get; set; } public event EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>> PositionChanged; public event EventHandler<GeoPositionStatusChangedEventArgs> StatusChanged; public void Start(bool suppressPermissionPrompt) { if (timer == null) { operation = AsyncOperationManager.CreateOperation(null); // Timer per scatenare il cambio di posizione timer = new Timer(Raise, null, 0, 5000); // Scateno lo startup if (StatusChanged != null) StatusChanged(this, new GeoPositionStatusChangedEventArgs(GeoPositionStatus.Initializing)); if (StatusChanged != null) StatusChanged(this, new GeoPositionStatusChangedEventArgs(GeoPositionStatus.Ready)); } } public void Start() { this.Start(false); } public void Stop() { if (timer != null) timer.Dispose(); timer = null; } public bool TryStart(bool suppressPermissionPrompt, TimeSpan timeout) { this.Start(); return true; } private void Raise(object s) { operation.Post(st => { this.Position.Location = new GeoCoordinate(this.Position.Location.Latitude, this.Position.Location.Longitude + 0.0002, this.Position.Location.Altitude + 0.0002, Math.Max(2, this.Position.Location.HorizontalAccuracy - 5), Math.Max(2, this.Position.Location.VerticalAccuracy - 5), this.Position.Location.Speed, this.Position.Location.Course); if (PositionChanged != null) PositionChanged(this, new GeoPositionChangedEventArgs<GeoCoordinate>(this.Position)); }, null); } }
Da notare che gli eventi, per mantenere la stessa caratteristica dell'implementazione reale, devono essere scatenati sul thread UI. Per farlo si fa uso della classe AsyncOperationManager di cui è possibile trovare un approfondimento all'indirizzo
https://www.silverlightitalia.com/articoli/silverlight/multithreading-silverlight-2.0.aspx
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Supportare lo HierarchyID di Sql Server in Entity Framework 8
Paginare i risultati con QuickGrid in Blazor
Creare un'applicazione React e configurare Tailwind CSS
Usare lo spread operator con i collection initializer in C#
Utilizzare la versione generica di EntityTypeConfiguration in Entity Framework Core
Triggerare una pipeline su un altro repository di Azure DevOps
Creare una libreria CSS universale: Clip-path
Autenticarsi in modo sicuro su Azure tramite GitHub Actions
Eseguire script pre e post esecuzione di un workflow di GitHub
Utilizzare il trigger SQL con le Azure Function
Disabilitare automaticamente un workflow di GitHub
Generare la software bill of material (SBOM) in GitHub
I più letti di oggi
- Utilizzare il metodo CountBy di LINQ per semplificare raggruppamenti e i conteggi
- Effettuare il log delle chiamate a function di GPT in ASP.NET Web API
- Chiamare direttamente un numero di telefono con HTML5
- Richiamare programmaticamente le operazioni di aggiornamento, eliminazione e inserimento di FormView, DetailsView e GridView