Upload
nguyen-tuan
View
147
Download
2
Embed Size (px)
DESCRIPTION
Files and Storage on Windows Phone
Citation preview
Local DatabaseFiles & Storage
Nguyen Tuan | Microsoft Certified Trainer
Agenda
• Local Data Storage: Overview
• Using Isolated Storage
• Using Setting Storage
• File & Protocol Association
• Data serialization
• Local database
• SQLite database
• External Storage(Using SD Card)
Local Data Storage: Overview
ApplicationSettings File
App
ApplicationFiles
Package Manager
Install Folder
Install
DB
Database file
DB DatabaseFile (r/o)
Installation folder
• Is a read-only folder
• Contains files of your app package
• APIs to access the installation folder:• Application.GetResourceStream(Uri) method
• DataContext class
• Package.InstalledLocation property
• StorageFile and StorageFolder classes
Local folder
• Is the root folder of your app’s data store
• Is not altered or updated when you update your app
• Will be removed when the application is uninstalled
• It may be something like this:
C:\Data\Users\DefApps\AppData\{5D93133B-3B39-4ABF-8D61-277D77B9F2AD}\Local
Application.GetResourceStream(Uri)
// Get the image stream at the specified URI that// is relative to the application package root.Uri uri = new Uri(relativeUriString, UriKind.Relative); StreamResourceInfo sri = Application.GetResourceStream(uri);
// Convert the stream to an Image object.BitmapImage bi = new BitmapImage(); bi.SetSource(sri.Stream); Image img = new Image(); img.Source = bi;
• Use this method to stream files from the installation folder
DataContext class
• To connect to a reference database that is part of the app package
• is an object representing the database, a proxy, containing Table objects that represent the tables in the database
Package.InstalledLocation property
• Returns the installation folder as a StorageFolder object
• The Path property to get the full path of the installation folder
Windows.ApplicationModel.Package package = Windows.ApplicationModel.Package.Current;Windows.Storage.StorageFolder installedLocation = package.InstalledLocation;
String output = String.Format("Installed Location: {0}", installedLocation.Path);
Windows.Storage classes
• StorateFolder• Represent a store area containing files and folders
• StorageFile• Represent a file and provide method for manipulating
Saving Data
private async void WriteMessage(String message) {StorageFolder folder = ApplicationData.Current.LocalFolder;
StorageFile file = await folder.CreateFileAsync("message.dat", CreationCollisionOption.OpenIfExists);
Stream stream = await file.OpenStreamForWriteAsync();
using (StreamWriter writer = new StreamWriter(stream)){
await writer.WriteAsync(message);}
}
Loading Data
private async Task<string> ReadMessageAsync() {string data = string.Empty;StorageFolder folder = ApplicationData.Current.LocalFolder;StorageFile file = await folder.GetFileAsync("message.dat");
Stream stream = await file.OpenStreamForReadAsync();using (StreamReader reader = new StreamReader(stream)){
data = await reader.ReadToEndAsync();}return data;
}
Isolated Storage Classes
• Isolated Storage is used to store local data
• All I/O operations are restricted to isolated storage
• IsolatedStorageFile• Represents an isolated storage area containing files and folders
• IsolatedFileStream• Exposes a file stream access to a file stored within isolated storage
• IsolatedStorageSetting• Dictionary that stores key-value pairs in isolated storage
Saving Data
private void WriteMessageToIsolatedStorage(string message) {using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication()) {
using(IsolatedStorageFileStream stream = new IsolatedStorageFileStream("message.dat", FileMode.Append, FileAccess.Write, store)){
StreamWriter writer = new StreamWriter(stream);writer.WriteLine(message);writer.Close();
}}
}
Loading Data
private string ReadMessageFromIsolatedStorage() {string data = string.Empty;using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication()) {
using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream("message.dat", FileMode.Open, store)) {
StreamReader reader = new StreamReader(stream);data = reader.ReadToEnd();reader.Close();
}}return data;
}
Saving Data in Settings
• Is used to store app’s setting in form of key-value.
• It works like a dictionary
private void SaveSetting(string key, string value) {IsolatedStorageSettings.ApplicationSettings[key] = value;IsolatedStorageSettings.ApplicationSettings.Save();
}
private string LoadSetting(string key) {if (IsolatedStorageSettings.ApplicationSettings.Contains(key)) {
return (string)IsolatedStorageSettings.ApplicationSettings[key];}return null;
}
Special-use folders in the local folder
• Shared
• Shared/Media
• Shared/ShellContent
• Shared/Transfers
• PlatformData
File & Protocol Association
• File association allows app to launch when the user want to open a particular file type, via:• an email attachment
• a website via Internet Explorer
• a text message
• a NFC tag
• another app from the Store
WMAppManifiest.xml
Demo: FilesStorage
Serialization/Deserialization
• Convert an object into a stream of bytes in order to store the object or transmit it to memory, a database, or a file
• Binary serialization
• XML serialization
• SOAP serialization
XMLSerializer (1)
• Used to serialize/deserialize bettween objects and xml data
using System.Xml.Serialization;
[XmlRoot(“contact")]public class Contact{
[XmlElement("id")]public int ID{get;set;}[XmlElement("name")]public string Name { get; set; }[XmlElement("email")]public string Email { get; set; }
}
XMLSerializer (2) - Serialize
using System.Xml.Serialization;.. .. .. .. ..
private async void SaveContactAsync(Contact contact){StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync("contact.xml",
CreationCollisionOption.ReplaceExisting);var outStream = await file.OpenStreamForWriteAsync();XmlSerializer serializer = new XmlSerializer(typeof(Contact));serializer.Serialize(outStream, contact);await outStream.FlushAsync();outStream.Close();
}
XMLSerialize (3) – XML File
<?xml version="1.0" encoding="utf-8" ?><contact><id>1</id><name>Maria Rose</name><email>[email protected]</email>
</contact>
Contact contact = new Contact() { ID = 1,Name = "Maria Rose",Email = "[email protected]"
};saveContact(contact);
XMLSerializer (4) - Deserialize
using System.Xml.Serialization;.. .. .. .. ..
private async Task<Contact> LoadContactAsync() {StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync("contact.xml");var inStream = await file.OpenStreamForReadAsync();XmlSerializer serializer = new XmlSerializer(typeof(Contact));Contact contact = (Contact)serializer.Deserialize(inStream);inStream.Close();return contact;
}
Other Serializers
• DataContractSerializer
• DataContractJsonSerializer
• Third party
Demo: XML Serializer1.DataStorage
Local database
• App can store relational data in local database
• Resides on app’s Local folder
• Use LINQ to SQL for all database operations
• LINQ provides object-relational mapping capabilites
DataContext
• DataContext is a proxy, represents the database
• Contains Table objects which represent tables on database
• Table objects is made up of entities that correspond to rows of data in a database
public class TodoDataContext:DataContext{
public static string DBConnectionString = "Data Source=isostore:/todo.sdf";
public TodoDataContext(string connectionString):base(connectionString){
}public Table<TodoItem> TodoItems;
}
Entity Class
public class TodoItem:INotifyPropertyChanged, INotifyPropertyChanging{
private int _id;[Column(IsPrimaryKey=true, IsDbGenerated=true, DbType="INT NOT NULL IDENTITY", CanBeNull=false,
AutoSync=AutoSync.OnInsert)]public int Id {
get {return this._id;
}set {
if (_id != value) {NotifyPropertyChanging("Id");this._id = value;NotifyPropertyChanged("Id");
}}
}….
}
Creating database
using (TodoDataContext db = new TodoDataContext(TodoDataContext.DBConnectionString)){
if (!db.DatabaseExists()){
db.CreateDatabase();}
}
Database operation
TodoItem newItem = new TodoItem() { Name = txtItemName.Text };items.Add(newItem);db.TodoItems.InsertOnSubmit(newItem);db.SubmitChanges();
ObservableCollection<TodoItem> items = new ObservableCollection<TodoItem>();var todoItems = from i in db.TodoItems select i;foreach (var i in todoItems) {
items.Add(i);}
Demo: Local Database
SQLite
• Is a SQL database engine
• Is self-contained
• Is serverless
• Is zero-configuration
• Is transactional
Why SQLite?
Worlds’ most popular database
Rich Features
Reliable
SQLite.org
Documentation
SQL Syntax
C/C++ API Reference
Source and tools download
SQLite for Windows Phone
• SQLite database engine is fully supported on WP8 platform
• SQLite engine for Windows Phone available as a Visual Studio extension
Csharp-sqlite
• Is an independent reimplementation of the SQLite software library
sqlite-net-wp8
• A C++/CX wrapper for SQLite functions that sqlite-net depends on.
• Can be used as an alternative to csharp-sqlite on Windows Phone 8
.NET APIs
SQLite-NETLINQ syntaxLightweight ORMSimilar to WP8 Local Database (LINQ to SQL)
SQLitePCLSQL statements
Thin wrapper around the SQLite C API
using (var db = new SQLitePCL.Database("demo.db")){
db.Open(); using (var stmt = db.PrepareStatement
("SELECT name, age FROM people")) { while (stmt.Step()) { var name = stmt.GetTextAt(0); var age = stmt.GetIntAt(1);
}}
}
var db =new SQLite.SQLiteAsyncConnection(App.DBPath);
var _customer = await(from c in db.Table<Customer>() where c.Id == customerIdselect c).FirstOrDefaultAsync();
if (customer != null) {
var Id = _customer.Id; var Name = _customer.Name;
}
Installing SQLitePCL to your Solution
1. Add Reference to SQLite extension SDK2. In Configuration Manager, change
target platform to X86 or ARM3. In ‘Manage NuGet Packages’, add
reference to SQLitePCL package
Defining tables
SQLitePCL is really a thin wrapper around the SQLite ‘C’ APIInteract with the database using
SQL statementsParameterized queries and statements
Create database and tables
private void LoadDatabase()
{
// Get a reference to the SQLite database
conn = new SQLiteConnection("sqlitepcldemo.db");
string sql = @"CREATE TABLE IF NOT EXISTS
Customer (Id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
Name VARCHAR( 140 ),
City VARCHAR( 140 ),
Contact VARCHAR( 140 )
);";
using (var statement = conn.Prepare(sql))
{
statement.Step();
}
}
Insert
// SqlConnection was opened in App.xaml.cs and exposed through property conn
var db = App.conn;
try
{
using (var custstmt = db.Prepare("INSERT INTO Customer (Name, City, Contact) VALUES (?, ?, ?)"))
{
custstmt.Bind(1, customerName);
custstmt.Bind(2, customerCity);
custstmt.Bind(3, customerContact);
custstmt.Step();
}
}
catch (Exception ex)
{
// TODO: Handle error
}
Selectpublic Customer GetCustomer(int customerId)
{
Customer customer = null;
using (var statement = dbconn.Prepare("SELECT Id, Name, City, Contact FROM Customer WHERE Id = ?"))
{
statement.Bind(1, customerId);
if (SQLiteResult.DONE == statement.Step())
{
customer = new Customer()
{
Id = (long)statement[0],
Name = (string)statement[1],
City = (string)statement[2],
Contact = (string)statement[3]
};
}
}
return customer;
}
Update
// See if the customer already exists
var existingCustomer = GetCustomer(customer.Id);
if (existingCustomer != null)
{
using (var custstmt = dbconn.Prepare("UPDATE Customer SET Name = ?, City = ?, Contact = ? WHERE Id=?"))
{
// NOTE when using anonymous parameters the first has an index of 1, not 0.
custstmt.Bind(1, customer.Name);
custstmt.Bind(2, customer.City);
custstmt.Bind(3, customer.Contact);
custstmt.Bind(4, customer.Id);
custstmt.Step();
}
}
Delete
public void DeleteCustomer(int customerId)
{
using (var statement = dbconn.Prepare("DELETE FROM Customer WHERE Id = ?"))
{
statement.Bind(1, customerId);
statement.Step();
}
}
Demo: SQLite
48
The SD Card in Windows Phone
This makes it possible for applications to share data amongst themselves
Maps to a local folder on your PC
49
Setting SD card capabilities
Removable Storage
Pictures Library
Videos Library
Music Library
50
Applications and file associations
An image processing program will work with files such as .jpg, .png, etc
A sound processing program will work with .mp3 files
You can add your own custom file types for your particular application if you wish
Note that this is not required for applications accessing files in their own local/roaming/temporary storage
This is the same mechanism used for app-to-app communications through file associations (See Session 10)
51
Setting file associations for your application
This application can only work with .txt files
52
Getting an SD Card
• These statements get a reference to the SD card on the phone
• They are part of a method that creates a file on the SD card
• This method is part of the demo software we will be running later
53
var devices = Windows.Storage.KnownFolders.RemovableDevices;var sdCards = await devices.GetFoldersAsync();if (sdCards.Count == 0) return;StorageFolder firstCard = sdCards[0];
Getting an SD Card
• We get a list of SD cards using the KnownFolders API
• There will only be 0 or 1
54
var devices = Windows.Storage.KnownFolders.RemovableDevices;var sdCards = await devices.GetFoldersAsync();if (sdCards.Count == 0) return;StorageFolder firstCard = sdCards[0];
Getting an SD Card
• If there is not one present the value of the Count property will be 0
• This method returns if there are no SD Cards on the device
• Your application must handle this eventuality gracefully
•Not all devices have an SD card slot
• The slot might not have a card fitted into it
55
var devices = Windows.Storage.KnownFolders.RemovableDevices;var sdCards = await devices.GetFoldersAsync();if (sdCards.Count == 0) return;StorageFolder firstCard = sdCards[0];
Getting an SD Card
• The card is exposed as a StorageFolder, so we can use it in the same way the previous devices we have seen
• We can create folders and files
• But we can only work with files types for which we have declared a file association in the manifest
56
var devices = Windows.Storage.KnownFolders.RemovableDevices;var sdCards = await devices.GetFoldersAsync();if (sdCards.Count == 0) return;StorageFolder firstCard = sdCards[0];
Inserting an SD card in the emulator
57
SD Cards in the Emulator
58
Ejecting an SD Card from the emulator
There is an option to select this
59