SlideShare une entreprise Scribd logo
1  sur  35
Xamarin
Persistenza
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
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);
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");
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
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);
}
}
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>
Es. File IO (3)
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
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
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
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.
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/
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
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
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
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
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);
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"
/>
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
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.
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
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)
Es. Richiesta permessi Android
6.0 (1)
 Requisiti
 Device con Android 6.0 o superiore installato
 Android target 6.0 o superiore nel manifest
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);
}
}
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);
}
Es. Riechiesta permessi Android
6.0 (4)
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
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; }
}
}
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");
}
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);
}
}
}
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;
}
}
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>
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();
}
Es. Sqlite (6)

Contenu connexe

Similaire à Persistenza su Xamarin

Corso Avanzato Alfresco Ecm
Corso Avanzato Alfresco EcmCorso Avanzato Alfresco Ecm
Corso Avanzato Alfresco Ecm
edoardo fraioli
 

Similaire à Persistenza su Xamarin (20)

Drupal - per chi vuole iniziare
Drupal - per chi vuole iniziareDrupal - per chi vuole iniziare
Drupal - per chi vuole iniziare
 
Java lezione 13
Java lezione 13Java lezione 13
Java lezione 13
 
Presentazione Tesi Marco Ventura
Presentazione Tesi Marco VenturaPresentazione Tesi Marco Ventura
Presentazione Tesi Marco Ventura
 
Introduzione ad Android jug marche meeting 2011_04_30
Introduzione ad Android jug marche meeting 2011_04_30Introduzione ad Android jug marche meeting 2011_04_30
Introduzione ad Android jug marche meeting 2011_04_30
 
Sviluppare applicazioni android
Sviluppare applicazioni androidSviluppare applicazioni android
Sviluppare applicazioni android
 
Java Advanced
Java AdvancedJava Advanced
Java Advanced
 
I package Android
I package AndroidI package Android
I package Android
 
Apache Maven - Gestione di progetti Java e build automation
Apache Maven - Gestione di progetti Java e build automationApache Maven - Gestione di progetti Java e build automation
Apache Maven - Gestione di progetti Java e build automation
 
Lezione Android prima parte
Lezione Android prima parteLezione Android prima parte
Lezione Android prima parte
 
Framework per la gestione di un file system cifrato per i dispositivi Android
Framework per la gestione di un file system cifrato per i dispositivi AndroidFramework per la gestione di un file system cifrato per i dispositivi Android
Framework per la gestione di un file system cifrato per i dispositivi Android
 
Corso Avanzato Alfresco Ecm
Corso Avanzato Alfresco EcmCorso Avanzato Alfresco Ecm
Corso Avanzato Alfresco Ecm
 
Presentazione java7
Presentazione java7Presentazione java7
Presentazione java7
 
Grasso Frameworks Ajax
Grasso Frameworks AjaxGrasso Frameworks Ajax
Grasso Frameworks Ajax
 
Wp8 2014
Wp8 2014Wp8 2014
Wp8 2014
 
Master Informatica del Testo – Edizione elettronica - Arezzo - 2012
Master Informatica del Testo – Edizione elettronica - Arezzo - 2012Master Informatica del Testo – Edizione elettronica - Arezzo - 2012
Master Informatica del Testo – Edizione elettronica - Arezzo - 2012
 
Cac Es2
Cac Es2Cac Es2
Cac Es2
 
Adobe TechConnection: Flex Best Practices
Adobe TechConnection: Flex Best PracticesAdobe TechConnection: Flex Best Practices
Adobe TechConnection: Flex Best Practices
 
Java lezione 19
Java lezione 19Java lezione 19
Java lezione 19
 
Hosting: 10 consigli per mettere al sicuro un sito - parte 2 #TipOfTheDay
Hosting: 10 consigli per mettere al sicuro un sito - parte 2 #TipOfTheDayHosting: 10 consigli per mettere al sicuro un sito - parte 2 #TipOfTheDay
Hosting: 10 consigli per mettere al sicuro un sito - parte 2 #TipOfTheDay
 
Android Overview
Android OverviewAndroid Overview
Android Overview
 

Plus de Beniamino Ferrari

Plus de Beniamino Ferrari (11)

Laravel 7 REST API
Laravel 7 REST APILaravel 7 REST API
Laravel 7 REST API
 
Interfaccia di Xamarin
Interfaccia di XamarinInterfaccia di Xamarin
Interfaccia di Xamarin
 
Xaml su Xamarin
Xaml su XamarinXaml su Xamarin
Xaml su Xamarin
 
Installazione di Xamarin
Installazione di XamarinInstallazione di Xamarin
Installazione di Xamarin
 
Introduzione a Xamarin
Introduzione a XamarinIntroduzione a Xamarin
Introduzione a Xamarin
 
Net core base
Net core baseNet core base
Net core base
 
Corso angular js material
Corso angular js materialCorso angular js material
Corso angular js material
 
Corso angular js componenti
Corso angular js componentiCorso angular js componenti
Corso angular js componenti
 
Corso angular js base
Corso angular js baseCorso angular js base
Corso angular js base
 
Corso linux base
Corso linux baseCorso linux base
Corso linux base
 
couchbase mobile
couchbase mobilecouchbase mobile
couchbase mobile
 

Dernier

Dernier (9)

GIORNATA TECNICA 18/04 | SPIZZIRRI Massimo
GIORNATA TECNICA 18/04 | SPIZZIRRI MassimoGIORNATA TECNICA 18/04 | SPIZZIRRI Massimo
GIORNATA TECNICA 18/04 | SPIZZIRRI Massimo
 
GIORNATA TECNICA 18/04 | DE LEO Antonio
GIORNATA TECNICA 18/04  | DE LEO AntonioGIORNATA TECNICA 18/04  | DE LEO Antonio
GIORNATA TECNICA 18/04 | DE LEO Antonio
 
GIORNATA TECNICA DA AQP 18/04 | MOTTA Simone
GIORNATA TECNICA DA AQP 18/04 | MOTTA SimoneGIORNATA TECNICA DA AQP 18/04 | MOTTA Simone
GIORNATA TECNICA DA AQP 18/04 | MOTTA Simone
 
GIORNATA TECNICA 18/04 | LITTERIO Raffaele
GIORNATA TECNICA 18/04 | LITTERIO RaffaeleGIORNATA TECNICA 18/04 | LITTERIO Raffaele
GIORNATA TECNICA 18/04 | LITTERIO Raffaele
 
Presentzione Matematica similitudini circonferenze e omotetie.pptx
Presentzione  Matematica similitudini circonferenze e omotetie.pptxPresentzione  Matematica similitudini circonferenze e omotetie.pptx
Presentzione Matematica similitudini circonferenze e omotetie.pptx
 
GIORNATA TECNICA DA AQP 18/04 | ZONNO Serena
GIORNATA TECNICA DA AQP 18/04 | ZONNO SerenaGIORNATA TECNICA DA AQP 18/04 | ZONNO Serena
GIORNATA TECNICA DA AQP 18/04 | ZONNO Serena
 
GIORNATA TECNICA 18/04 | BENANTI Alessandro
GIORNATA TECNICA 18/04 | BENANTI AlessandroGIORNATA TECNICA 18/04 | BENANTI Alessandro
GIORNATA TECNICA 18/04 | BENANTI Alessandro
 
GIORNATA TECNICA 18/04 | DE ROSA Roberto
GIORNATA TECNICA 18/04 | DE ROSA RobertoGIORNATA TECNICA 18/04 | DE ROSA Roberto
GIORNATA TECNICA 18/04 | DE ROSA Roberto
 
Descrizione della struttura architettonica Eretteo.pptx
Descrizione della struttura architettonica Eretteo.pptxDescrizione della struttura architettonica Eretteo.pptx
Descrizione della struttura architettonica Eretteo.pptx
 

Persistenza su Xamarin

  • 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. 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. 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. 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. 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. 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>
  • 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. Es. Riechiesta permessi Android 6.0 (4)
  • 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. 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. 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. 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. 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. 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. 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(); }