Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Persistenza su Xamarin

90 views

Published on

Come implementare la persistenza su Xamarin, file, special folder, android permission e sqlite

Published in: Engineering
  • Be the first to comment

  • Be the first to like this

Persistenza su Xamarin

  1. 1. Xamarin Persistenza
  2. 2. Classi di IO  Xamarin.Forms gira su più piattaforme ciascuna delle quali possiede un proprio filesystem  Le classi del namespace System.IO possono essere utilizzate per accedere al filesystem di ciascuna piattaforma  La classe File permette di creare, eliminare e leggere file  La classe Directory permette di creare, eliminare o di mostrare il contenuto delle directory  É possibile anche utilizzare le classi che derivano da Stream per ottenere un più alto grado di controllo sulle operazioni su file come compressione o posizionamento all’interno di un file
  3. 3. File (1)  Un file di testo può essere scritto usando il metodo File.WriteAllText  es. File.WriteAllText(filename, text);  Un file di testo può essre scritto usando il metodo File.ReadAllText  es. string text = File.ReadAllText(filename);  Si può verificare che un file esista usando il metodo File.Exists  es. bool doesExist = File.Exists(filename);
  4. 4. File (2)  Il percorso della parte del filesystem riservata alla applicazione di ogni piattaforma è determinato da .NET Standard usando l’enumerativo Environment.SpecialFolder come primo argomento del metodo Environment.GetFolderPAth  Questo può essere concatenato con il nome del file usando il metodo Path.Combine  Es string fileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicati onData), "temp.txt");
  5. 5. Environment.SpecialFolder Android  Environment.SpecialFolder Directory  ApplicationData INTERNAL_STORAGE/.config  Desktop INTERNAL_STORAGE/Desktop  LocalApplicationData INTERNAL_STORAGE/.local/share  MyDocuments INTERNAL_STORAGE  MyMusic INTERNAL_STORAGE/Music  MyPictures INTERNAL_STORAGE/Pictures  MyVideos INTERNAL_STORAGE/Videos  Personal INTERNAL_STORAGE
  6. 6. Es. File IO (1) public partial class MainPage : ContentPage { public MainPage() { InitializeComponent(); string text = "Xamarin forms file read write test"; string filename = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "temp.txt"); FilePath.Text += filename; File.WriteAllText(filename, text); bool doesExist = File.Exists(filename); if(doesExist) FileContent.Text += File.ReadAllText(filename); } }
  7. 7. Es. File IO (2) <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:AppTestFile" x:Class="AppTestFile.MainPage"> <StackLayout Orientation="Vertical" > <StackLayout VerticalOptions="FillAndExpand"> <Label x:Name="FilePath" Text="Path: " HorizontalOptions="CenterAndExpand" VerticalOptions="Start" /> <Label x:Name="FileContent" Text="Content: " HorizontalOptions="CenterAndExpand" VerticalOptions="Start" /> </StackLayout> </StackLayout> </ContentPage>
  8. 8. Es. File IO (3)
  9. 9. Android File Storage  Una requisito fondamentale per App Android è quello di manipolare file  Salvare immagini, scaricare documenti esprtare data  Aandroid possiede due gruppi di filesystem che risiedono in due tipi di storage:  Internal storage è la porzione di filesystem che può essere utilizzata solamente dalle app e dal sistema operativo  External storage è una porzione di filesystem accessibile da tutte le apps, dagli utenti. In alcuni device è rimovibile
  10. 10. Internal vs external storage (1)  Concettualmente, l'archiviazione interna e l'archiviazione esterna sono molto simili: sono entrambi i luoghi in cui un'app Xamarin.Android può salvare il file  Internal Storage è la memoria non-volatile che Android alloca per sistema operativo e APKs.  Android alloca un directory nella internal storage partition per ogni App  Quando un’app viene disinstallata tutti i file presenti nella memoria interna vengono cancellati
  11. 11. Internal vs external storage (2)  In Android 6.0 e superiori i file presenti nella memoria interna possono essere sfruttare la feature di auto backup di Google  La memoria interna hanno degli svantaggi:  I file non possono essere condivisi  I file vengono cancellati se l’app viene cancellata  Lo spazio disponibile è limitato
  12. 12. External strorage  Il compito principale della external storage è disporre di uno spazio non esclusivamente accessibile dall’app o per ottenere spazio per una grande allocazione di spazio  Private: i file privati sono file specifici dell'applicazione (ma sono ancora accessibili dalle altre app). Android si aspetta che i file privati siano archiviati in una directory specifica su una memoria esterna. Anche se i file sono chiamati "privati", sono ancora visibili e accessibili da altre app sul dispositivo, non gli viene fornita alcuna protezione speciale da parte di Android.  Public: si tratta di file che non sono considerati specifici dell'applicazione e devono essere condivisi liberamente.
  13. 13. Private external files (1)  Sono considerati specifici di un’applicazione (simili ai file interni) ma vengono conservati su una memoria esterna per un numero qualsiasi di motivi (ad esempio, sono troppo grandi per l'archiviazione interna). Simili ai file interni, questi file verranno eliminati quando l'app viene disinstallata dall'utente.  Es. Android.Content.Context.GetExternalFilesDir(null) restituisce  /storage/emulated/0/Android/data/com.companyname.app/files/
  14. 14. Private external files (2)  La radice di locazione dei file esterni privati si ottiene chiamando  Android.Content.Context.GetExternalFilesDir(string type)  Questo metodo restituisce un oggetto di tipo Java.IO.File che rappresenta una directory su external storage  Se type è null viene restituita la directory radice altrimenti usando una costante Android.OS.Environment viene restituita una determinata directory
  15. 15. Private external files (3)  Android.OS.Environment Directory  DirectoryAlarms PRIVATE_EXTERNAL_STORAGE/Alarms  DirectoryDcim PRIVATE_EXTERNAL_STORAGE/DCIM  DirectoryDownloads PRIVATE_EXTERNAL_STORAGE/Download  DirectoryDocuments PRIVATE_EXTERNAL_STORAGE/Documents  DirectoryMovies PRIVATE_EXTERNAL_STORAGE/Movies  DirectoryMusic PRIVATE_EXTERNAL_STORAGE/Music  DirectoryNotifications PRIVATE_EXTERNAL_STORAGE/Notifications  DirectoryPodcasts PRIVATE_EXTERNAL_STORAGE/Podcasts  DirectoryRingtones PRIVATE_EXTERNAL_STORAGE/Ringtones  DirectoryPictures PRIVATE_EXTERNAL_STORAGE/Pictures
  16. 16. Public external files  I file pubblici su external storage non verranno eliminati quando l'app viene disinstallata.  Le app Android devono essere autorizzate prima che possano leggere o scrivere su public external storage.  Android.OS.Environment.ExternalStorageDirectory è un property che restituisce un Java.IO.File che rappresenta la directory esterna principale es /storage/emulated/0/  Le stesse directory che esistono per la memoria privata sono presenti anche per quella pubblica e si ottengono tramite Android.OS.Environment.GetExternalStoragePublicDirectory(string directoryType)  queste sono dedicate e accessibili da tutte le applicazioni
  17. 17. External Storage Android Check (1)  Prima di accedere ad uno dei file presenti su external storage è necessario  Verificare lo stato dell’external storage: la memoria potrebbe non essere montata o accessibile  Verificare il permesso di accedervi a runtime: le app android devono richiedere il permesso per potere accedere alla external storage
  18. 18. External Storage Android Check (2)  Android.OS.Environment.ExternalStorageState proprietà contiene una stringa che identifica lo stato della memoria esterna  La maggior parte delle app Android dovrà solo verificare se è installata memoria esterna.  Il seguente codice mostra come verificare che l'archiviazione esterna sia montata per l'accesso in sola lettura o l'accesso in lettura-scrittura  bool isReadonly = Environment.MediaMountedReadOnly.Equals(Environment.ExternalStorageState);  bool isWriteable = Environment.MediaMounted.Equals(Environment.ExternalStorageState);
  19. 19. External Storage Android Check (3)  Tutte le app Android devono dichiarare una delle due autorizzazioni per l'archiviazione esterna nel file AndrroidManifest.xml  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  20. 20. Richiesta dei permessi  Le app che hanno come target Android 6.0 devono eseguire la richiesta dei permessi runtime  Le app che hanno target Android 5.1 o inferiori non necessitano di eseguire la richiesta runtime ma è sufficiente utilizzare il file AndroidManifest.xml
  21. 21. Runtime Permission Checks in Android 6.0  Normal Permissions – queste sono autorizzazioni cui mettere a rischio di sicurezza poco la sicurezza o privacy dell'utente. Android 6.0 concederà autorizzazioni normale automaticamente al momento dell'installazione. Vedere la documentazione di Android per un elenco completo delle autorizzazioni normali.  Dangerous Permission – a differenza dei normali autorizzazioni, autorizzazioni pericolose sono quelli che proteggono sicurezza o privacy dell'utente. Questi permessi devono essere concessi esplicitamente dall'utente tramige popup. Inviare o ricevere un messaggio SMS è un esempio di un'azione che richiede un'autorizzazione pericolosa.
  22. 22. Runtime Permission Checks in Android 6.0 (1)  Il metodo ContextCompat.CheckSelfPermission serve per verificare che una determinato permesso sia stato convalidato  Questo metodo restituisce un enum di tipo Android.Content.PM.Permission che contiene due valori  Permission.Granted lo speficifico permesso è stato convalidato  Permission.Denied lo specificao permesso non è stato convalidato
  23. 23. Runtime Permission Checks in Android 6.0 (2)  ActivityCompat.RequestPermissions(Activity activity, string[] permissions, int requestCode)  Questo metodo serve per attivare il popup di richiesta permessi  Activity è l’istanza dell’activity che richiede il permesso  Permissions è la lista dei permessi richiesti  RequestCode è un intero utilizzato per convalidare la richiesta del permesso nel metodo OnRequestPermissionsResult che intercetta la risposta dell’utente(dovrebbe essere maggiore di zero)
  24. 24. Es. Richiesta permessi Android 6.0 (1)  Requisiti  Device con Android 6.0 o superiore installato  Android target 6.0 o superiore nel manifest
  25. 25. Es. Riechiesta permessi Android 6.0 (2)  Nella MainActvitiy.cs del progetto Xamarin.Android vado ad inserire il seguente override per ottenere il permesso di scrittura su External storage int REQUEST_STORAGE = 1; protected override void OnStart() { base.OnStart(); if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.WriteExternalStorage) != Permission.Granted) { ActivityCompat.RequestPermissions(this, new String[] { Manifest.Permission.WriteExternalStorage }, REQUEST_STORAGE); } }
  26. 26. Es. Riechiesta permessi Android 6.0 (3)  Nella MainActvitiy.cs del progetto Xamarin.Android vado ad inserire il seguente override per ricevere la conferma che il permesso sia stato concessopublic override void OnRequestPermissionsResult( int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults) { if (requestCode == REQUEST_STORAGE) { if ((grantResults.Length == 1) && (grantResults[0] == Permission.Granted)) { Log.Info("My AP", "My storage permission accepted"); } else { .Info("My AP", "My storage permission denied"); } Log.Info("My AP", "My storage received"); } base.OnRequestPermissionsResult(requestCode, permissions, grantResults); }
  27. 27. Es. Riechiesta permessi Android 6.0 (4)
  28. 28. Xamarin.Forms Local Database  Xamarin.Forms supporta applicazioni basate su database che utilizzano il motore di database SQLite, che consente di caricare e salvare oggetti utilizzando lo shared code.  Le applicazioni Xamarin.Forms possono usare il pacchetto nuget sqlite-net-pcl  Di seguito un esempio di come creare una ToDo list memorizzandola in un database
  29. 29. Es. Sqlite  Creo una directory Model nel progetto PCL e includo la mia classe di model using SQLite; namespace AppDatabase.Model { public class TodoItem { [PrimaryKey, AutoIncrement] public int ID { get; set; } public string Name { get; set; } public string Notes { get; set; } public bool Done { get; set; } } }
  30. 30. Es. Sqlite (2.1)  Creo una classe crud TodoItemDatabase mettendola in una cartella Data public class TodoItemDatabase { readonly SQLiteAsyncConnection database; public TodoItemDatabase(string dbPath) { database = new SQLiteAsyncConnection(dbPath); //Executes a "create table if not exists" on the database. database.CreateTableAsync<TodoItem>().Wait(); } public Task<List<TodoItem>> GetItemsAsync() { return database.Table<TodoItem>().ToListAsync(); } public Task<List<TodoItem>> GetItemsNotDoneAsync() { return database.QueryAsync<TodoItem>("SELECT * FROM [TodoItem] WHERE [Done] = 0"); }
  31. 31. Es. Sqlite (2.2) public Task<TodoItem> GetItemAsync(int id) { return database.Table<TodoItem>().Where(i => i.ID == id).FirstOrDefaultAsync(); } public Task<int> SaveItemAsync(TodoItem item) { if (item.ID != 0) { return database.UpdateAsync(item); } else { return database.InsertAsync(item); } } public Task<int> DeleteItemAsync(TodoItem item) { return database.DeleteAsync(item); } } }
  32. 32. Es. Sqlite (3)  Nel file App.xaml.cs aggiungere l’inizializzazione statica del database aggiungendo il seguente codice nella classe App static TodoItemDatabase database; public static TodoItemDatabase Database { get { if (database == null) { database = new TodoItemDatabase(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "TodoSQLite.db3")); } return database; } }
  33. 33. Es. Sqlite (4)  Nel file di MainPage.xaml inserire una ListView che mostra i dati  Salvare l’icona check.png in Resources/drawable nel progetto Android <?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:AppDatabase" x:Class="AppDatabase.MainPage"> <ListView x:Name="listView" Margin="20" > <ListView.ItemTemplate> <DataTemplate> <ViewCell> <StackLayout Margin="20,0,0,0" Orientation="Horizontal" HorizontalOptions="FillAndExpand"> <Label Text="{Binding Name}" VerticalTextAlignment="Center" HorizontalOptions="StartAndExpand" /> <Image Source="check.png" HorizontalOptions="End" IsVisible="{Binding Done}" /> </StackLayout> </ViewCell> </DataTemplate> </ListView.ItemTemplate> </ListView> </ContentPage>
  34. 34. Es. Sqlite (5)  Nella file MainPage.xaml.cs aggiungere qualche elemento al database ed esegue il bind dei dati con il seguente codice protected override async void OnAppearing() { base.OnAppearing(); TodoItem todoItem = new TodoItem(); todoItem.Name = "Todo1"; todoItem.Notes = "Take the rabbish out"; todoItem.Done = true; await App.Database.SaveItemAsync(todoItem); TodoItem todoItem2 = new TodoItem(); todoItem2.Name = "Todo2"; todoItem2.Notes = "do homework"; todoItem2.Done = false; await App.Database.SaveItemAsync(todoItem2); listView.ItemsSource = await App.Database.GetItemsAsync(); }
  35. 35. Es. Sqlite (6)

×