viernes, 30 de octubre de 2015

Usando SQLite .NET multiplataforma en Xamarin Android, Xamarin IOS, Windows Phone y Windows Store (Parte 2 WS)

Al igual que en el caso de Windows Phone lo primero es crear un proyecto nuevo, enlazarlo con Project Linker y agregar la referencia a una extensión como se hizo en la primera parte de este tutorial, por este motivo no me detendré en algunos pasos que se repiten en esta segunda parte y me enfocare a lo especifico de Windows Store.
Primero generamos el proyecto nuevo
5CreandoWS

El siguiente paso sería enlazar el proyecto Core a este que acabamos de crear del mismo modo en que se hizo con Windows Phone
Después de realizado lo anterior hay que instalar la extensión “SQLite for Windows Runtime(Windows 8.1)” desde el administrador de extensiones de Visual Studio (Menú Herramientas/Actualizaciones y extensiones)
image
Finalmente agregamos la referencia a esta extensión en nuestro proyecto.
image
Un detalle importante es que se debe crear un paquete de nuestra aplicación por arquitectura (x86,x64 o ARM) por lo cual hay que quitar esta referencia y volverla a agregar cada que cambiemos la arquitectura de lo contrario obtendremos la excepción “An exception of type 'System.BadImageFormatException' occurred in SQL.WS.exe but was not handled in user code”.  Esta excepción se debe a que la extensión agrega los paquetes específicos de la arquitectura que este definida en el momento en que se agrega la referencia.
image

Utilizando SQLite en el proyecto de Windows Store

Como ya tenemos desarrollada nuestra clase para administrar nuestra base de datos local (CRUDManager) y en pasos anteriores ya enlazamos Core a este proyecto solo nos resta generar la funcionalidad especifica de la plataforma, la cual básicamente es la interfaz de usuario y las llamadas a las funciones de CRUDManager.
En este caso el código es muy similar al de Windows Phone al ambos usar XAML como lenguaje para generar la interfaz de usuario. Aprovechando el tamaño de la pantalla y no dedicándole mucho tiempo al diseño voy a poner toda la funcionalidad en una misma pantalla a diferencia de Windows Phone que estaba acomodada por dos pantallas.
image
<Page
    x:Class="SQL.WS.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:SQL.WS"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <StackPanel Orientation="Horizontal">
            <StackPanel Width="320">
                <TextBlock FontSize="40">Guadar contactos</TextBlock>
                <TextBlock FontSize="20" >Nombre</TextBlock>
                <TextBox x:Name="txtName"></TextBox>
                <TextBlock FontSize="20">Edad</TextBlock>
                <TextBox x:Name="txtAge"></TextBox>
                <TextBlock FontSize="20">Correo Electrónico</TextBlock>
                <TextBox x:Name="txtMail"></TextBox>
                <TextBlock FontSize="20">Teléfono</TextBlock>
                <TextBox x:Name="txtPhoneNumber"></TextBox>
                <Button x:Name="btnSave" Margin="0,0,-3,0" Width="323" Click="btnSave_Click">Guardar</Button>

            </StackPanel>
            <StackPanel Width="300" Margin="100 0 0 0">
                <TextBlock FontSize="40">Buscar contactos</TextBlock>
                <TextBlock FontSize="20">Nombre</TextBlock>
                <TextBox x:Name="txtSName"></TextBox>
                <Button x:Name="btnSearch" Click="btnSearch_Click" Margin="0,0,-3,0" Width="303">Buscar</Button>
                <Button x:Name="btnAllItems" Click="btnAllItems_Click" Width="303" Margin="0,0,-3,0">Mostrar Todos</Button>
                <ListBox x:Name="lbResults" Height="250">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <StackPanel>
                                <TextBlock FontWeight="Bold">Nombre</TextBlock>
                                <TextBlock Text="{Binding Name}"></TextBlock>
                                <TextBlock FontWeight="Bold">Edad</TextBlock>
                                <TextBlock Text="{Binding Age}"></TextBlock>
                                <TextBlock FontWeight="Bold">Correo Electrónico</TextBlock>
                                <TextBlock Text="{Binding Mail}"></TextBlock>
                                <TextBlock FontWeight="Bold">Teléfono</TextBlock>
                                <TextBlock Text="{Binding PhoneNumber}"></TextBlock>
                            </StackPanel>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
                <Button x:Name="btnDelete" Width="293" Click="btnDelete_Click">Eliminar seleccionado</Button>
            </StackPanel>
        </StackPanel>
    </Grid>
</Page>
Finalmente el código que da funcionalidad a esta interfaz es prácticamente el mismo que para WP
using SQL.Core.Core;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238

namespace SQL.WS
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            InitializateDB();
        }

        CRUDManager crud;
        void InitializateDB()
        {
            var sqliteFilename = "ContactsDb";
            var path = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, sqliteFilename); ;

            crud = new CRUDManager(path);
        }

        private void btnSave_Click(object sender, RoutedEventArgs e)
        {
            Contact contact =
                new Contact(txtName.Text, int.Parse(txtAge.Text), txtPhoneNumber.Text, txtMail.Text);

            crud.SaveValue<Contact>(contact);
            lbResults.ItemsSource = crud.GetAllItems<Contact>();
        }

        private void btnSearch_Click(object sender, RoutedEventArgs e)
        {
            //Buscamos el contacto que coincida con lo introducido por el usuario
            lbResults.ItemsSource = new List<Contact> { crud.GetItem<Contact>(txtName.Text) };
        }

        private void btnAllItems_Click(object sender, RoutedEventArgs e)
        {
            //Mostramos todos los registros
            lbResults.ItemsSource = crud.GetAllItems<Contact>();
        }



        private void btnDelete_Click(object sender, RoutedEventArgs e)
        {
            //Eliminamos el contacto seleccionado
            crud.Delete<Contact>(((Contact)lbResults.SelectedItem).Key);
            lbResults.ItemsSource = null;
        }
    }
}

jueves, 15 de octubre de 2015

Usando SQLite .NET multiplataforma en Xamarin Android, Xamarin IOS, Windows Phone y Windows Store (Parte 1 WP)

En esta serie de publicaciones voy a mostrar cómo crear una aplicación multiplataforma que permita crear bases de datos locales SQLite usando SQLite.Net para las plataformas:
  • Windows Phone 8.1 (Parte 1)
  • Windows Store (Parte 2)
  • IOS y Android (Parte 3)
Para empezar Vamos a generar una solución en Visual Studio la cual contenga los 4 proyectos que se van a usar a lo largo de este tutorial. Para este ejemplo se va a compartir el código mediante un proyecto Core que va a ser enlazado a los diferentes proyectos de la aplicación, en un futuro escribiré una publicación para mostrar el uso de SQLite usando una Librería de clases portable.
  • Librería de clases de C# (SQL.Core)
  • Proyecto de Windows Phone (SQL.WP)
  • Proyecto de Windows Store (SQL.WS)
  • Proyecto de Xamarin Android (SQL.Droid)
  • Proyecto de Xamarin IOS (SQL.IOS)

Creando el proyecto Core

1CreandoCore

domingo, 23 de agosto de 2015

Charla sobre Xamarin en TelmexHub (12 de Septiembre 4:00pm)





El próximo 12 de septiembre a las 4:00pm estaré en TelmexHub hablando sobre Xamarin y sus ventajas en el desarrollo multiplataforma.

El objetivo de la charla es conocer el porque Xamarin es una excelente herramienta para desarrollar Apps para IOS y Android además de poder utilizar ese mismo código en aplicaciones Windows Phone, Desktop, Web y otras plataformas que usan C# como lenguaje nativo.

Esta platica no será de desarrollar mucho código por lo cual no es necesario asistir con equipo a menos de que quieran realizar el ejemplo, aunque esta es mas una platica para dar a conocer como funciona Xamarin y hablar sobre como es el tema de las licencias y los beneficios que existen actualmente para los estudiantes.

Después de esta platica tengo planeado ofrecer un curso de C# como preparación a un futuro curso de Xamarin Android/IOS y apps para Windows Store.

Finalmente quien guste asistir debe registrarse en la pagina del evento: http://telmexhub.org/evento/3607

Del mismo modo les adjunto la página de Meetup donde se van a ir poniendo las fechas de los eventos futuros http://www.meetup.com/es/Devs-Xamarin-Android-IOS-y-Windows-Ciudad-de-Mexico/events/224780385/

jueves, 20 de agosto de 2015

Guardar datos de contacto en una etiqueta NFC con WP 8.1

Hace unos días encontré una etiqueta NFC que tengo desde hace unos años y por curiosidad decidí probar si aun funcionaba. Después de comprobar que aun funciona decidí actualizar mi App, la cual estaba hecha para Windows Phone 8, a Windows Phone 8.1 utilizando la función que sirve para generar una vCard para compartir datos de contacto mediante NFC.

Parte teórica

Elegí esta función sobre otras (escribir un “Hola Mundo” o un enlace a una página web) debido a que el crear una vCard involucra entender de mejor manera un estándar para almacenar datos NFC, voy a tratar de explicarlo de manera muy rápida, dejando algunas fuentes que me sirvieron por si quieren conocer mas a fondo del tema.

El estándar NDEF (Data Exchange Format) creado por el NFC Forum sirve para definir la estructura de datos de aplicación que se transmiten entre dos dispositivos NFC. Por otro lado el NFC Forum también definió el concepto de “NFC Forum Type Tag Operations” el cual sirve para identificar el tipo de operación que va a realizar una TAG NFC.

Para una referencia formal sobre este tema pueden visitar este documento; http://www.nxp.com/documents/other/R_10014.pdf y por supuesto la página del NFC Forum con las especificaciones http://members.nfc-forum.org/specs/spec_list/ 

Ya entrando al tema importante del post, lo primero es tener el formato en que se guardara la información de contacto en la etiqueta NFC, el cual es el siguiente para este ejemplo:

BEGIN:VCARD
VERSION:2.1
FN:
N:;
TEL;CELL:
EMAIL;INTERNET:
END:VCARD

Se pueden agregar mas datos siguiendo el estándar de una vCard, en este caso con la información de Wikipedia es suficiente https://en.wikipedia.org/wiki/VCard

Resumiendo todo lo mencionado anteriormente, lo que se va a hacer el lo que muestra este diagrama tomado del primer pdf sobre NDEF que deje mas arriba
image
  1. La entrada son los datos que se van a almacenar, en este caso los de la tarjeta de contacto
  2. El mensaje NDEF que encapsula lo anterior. Este mensaje tiene la siguiente estructura:
image
Parte importante aquí es que el mensaje define el tipo de dato que contiene, en el PDF se encuentra una lista muy completa de los tipos de dato. Algunos ejemplos (incluido el que usaremos)
image
  1. El NFC Type Tag Platform, para entender mejor esto si hay que leer la especificación del NFC Forum  debido a que habla de las especificaciones de las etiquetas como la memoria, velocidad, etc.
  2. Y finalmente la etiqueta donde se va a almacenar esta información.

Parte practica

Ahora si ya viene el código, para empezar definimos la interfaz XAML de nuestra aplicación, la cual simplemente contiene los campos con los datos (Nombre, apellido, teléfono y e-mail)
<Page
    x:Class="NfcVCard.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:NfcVCard"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">


    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!--TitlePanel contiene el nombre de la aplicación y el título de la página-->
        <StackPanel Grid.Row="0" Margin="12,17,0,28">
            <TextBlock Text="NFC Writer" Style="{StaticResource SubheaderTextBlockStyle}"/>
            <TextBlock Text="vcard" Margin="9,-7,0,0" Style="{StaticResource HeaderTextBlockStyle}"/>
        </StackPanel>

        <!--ContentPanel. Colocar aquí el contenido adicional-->
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <StackPanel>
                <TextBlock>Nombre</TextBlock>
                <TextBox InputScope="NameOrPhoneNumber" x:Name="txtNombre"></TextBox>
                <TextBlock>Apellido</TextBlock>
                <TextBox InputScope="NameOrPhoneNumber" x:Name="txtApellido"></TextBox>
                <TextBlock>Telefono</TextBlock>
                <TextBox InputScope="TelephoneNumber" x:Name="txtTelefono"></TextBox>
                <TextBlock>Mail</TextBlock>
                <TextBox InputScope="EmailSmtpAddress" x:Name="txtMail"></TextBox>
                <Button x:Name="btnEscribir" Click="btnEscribir_Click">Escribir Tag</Button>
            </StackPanel>
        </Grid>
    </Grid>


</Page>



Y el código de funcionalidad es el siguiente:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Networking.Proximity;
using Windows.Storage.Streams;
using Windows.UI.Popups;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=391641

namespace NfcVCard
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();

            this.NavigationCacheMode = NavigationCacheMode.Required;

        }

        /// <summary>
        /// Invoked when this page is about to be displayed in a Frame.
        /// </summary>
        /// <param name="e">Event data that describes how this page was reached.
        /// This parameter is typically used to configure the page.</param>
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            // TODO: Prepare page for display here.

            // TODO: If your application contains multiple pages, ensure that you are
            // handling the hardware Back button by registering for the
            // Windows.Phone.UI.Input.HardwareButtons.BackPressed event.
            // If you are using the NavigationHelper provided by some templates,
            // this event is handled for you.

        }

        ProximityDevice _device;
        private void btnEscribir_Click(object sender, RoutedEventArgs e)
        {
            StatusBarProgressIndicator progressbar = StatusBar.GetForCurrentView().ProgressIndicator;
            progressbar.ShowAsync();
            progressbar.Text = "Acerca la etiqueta";
            btnEscribir.IsEnabled = false;

            string nombreCompleto = txtNombre.Text + " " + txtApellido.Text;
            string nombre = txtNombre.Text;
            string apellido = txtApellido.Text;
            string celular = txtTelefono.Text;
            string mail = txtMail.Text;
     //Obtenemos el dispositivo NFC del teléfono
            _device = ProximityDevice.GetDefault();
            //Creamos la tarjeta virtual con el formato que debe ser
            var vcard = string.Format("BEGIN:VCARD\nVERSION:2.1\nFN:{0}\nN:{1};{2}\nTEL;CELL:{3}\nEMAIL;INTERNET:{4}\nEND:VCARD", nombreCompleto, apellido, nombre, celular, mail);
            //El DataWriter que contiene los datos para escribir el mensaje binario a la etiqueta NFC
            var dataWriter = new DataWriter() { UnicodeEncoding = UnicodeEncoding.Utf8 }; dataWriter.WriteString(vcard);
            //Publicamos el mensaje binario en la etiqueta NFC, definimos el tipo de mensaje que es y támbien que método se va a ejecutar al finalizar el guardado
            _device.PublishBinaryMessage("WindowsMime:WriteTag.text/vcard", dataWriter.DetachBuffer(), MesssageTransmitted);
        }

        private async void MesssageTransmitted(ProximityDevice sender, long messageId)
        {
            //Le indicamos al dispositivo que deje de escribir el mensaje
            _device.StopPublishingMessage(messageId);



            await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
            {
                StatusBarProgressIndicator progressbar = StatusBar.GetForCurrentView().ProgressIndicator;
                progressbar.HideAsync();
                btnEscribir.IsEnabled = true;
                new MessageDialog("Contenido guardado").ShowAsync();
            });
        }
    }
}

Para que lo anterior funcione de manera correcta hay que hacer dos cosas extra, hay que darle los permisos necesarios a la aplicación para que pueda usar el sensor NFC, de lo contrario obtendremos el error

An exception of type 'System.UnauthorizedAccessException' occurred in NfcVCard.ni.EXE but was not handled in user code

Additional information: Access is denied.

Esto se hace en el Manifiesto en la secciones de “Requirements” y “Capabilities”

image

image

En este enlace dejo el código fuente: Proyecto NFC

Aquí también un pequeño video de muestra de como se ve el proyecto en acción y como la etiqueta se puede leer perfectamente desde WP y desde un dispositivo con Android.


lunes, 17 de agosto de 2015

Xamarin gratis para desarrolladores Windows Phone

  Xamarin-Heart-Windows

Si publicaste una app para Windows Phone antes del día de hoy (17 de agosto de 2015) puedes pedir una licencia de Xamarin IOS y Android gratis la cual incluye el soporte para Visual Studio.

Esta oferta termina el 31 de Agosto para los desarrolladores independientes que quieran una suscripción para uso personal y no aplica para clientes actuales de Xamarin.

Para obtener la licencia hay que llenar el siguiente formulario: https://resources.xamarin.com/xamarin-for-windows-phone-app.html   Fuente: Xamarin Blog







martes, 5 de noviembre de 2013

Error al obtener licencia de desarrollador Windows 8.1 (0x80080005)

Hace unos días hice una instalación limpia de Windows 8.1, a la cual lo primero que hice fue instalarle Visual Studio 2012 y 2013 junto con el SDK de Windows Phone 8. Para mi sorpresa al querer ejecutar una de mis aplicaciones de Windows Store me apareció la alerta de que no contaba con una licencia de desarrollador dando la opción de con un click obtener una, lo cual no fue tan sencillo como parecía y es el tema de este post.

Después de un rato de intentar conectarse al servidor para obtener la licencia me apareció el siguiente error:

Error al comprar la licencia de desarrollador. Error: Error en la ejecución de servidor
. Código de resultado 0x80080005


Después de mucho investigar e intentar todas las soluciones para casos similares de falla al obtener la licencia pero sin encontrar en algún lado el mismo problema, me di a la tarea de buscar respecto al error dejando de lado que esto pasaba desde Visual Studio y me encontré que este problema se debía a una cuestión de permisos.

Al aplicarla para mi caso especifico con Visual Studio los pasos que seguí fueron los siguientes:

1. Abrí las "Herramientas Administrativas" como mi versión de Windows esta en este idioma desde el charm de búsqueda lo busqué por su nombre.

2. Dentro de la ventana de herramientas administrativas abrí "Servicios de componentes".

3. Navegue por la vista de árbol del lado izquierdo a la siguiente ruta
Servicios de componentes > Equipos > Mi PC > Configuración DCOM



4. Al llegar a Configuración DCOM busqué la parte correspondiente a Visual Studio en este caso eran 3
 Microsoft Visual Studio

 Microsoft Visual Studio 2012

 Microsoft Visual Studio 2013


5. El último paso fue validar que los permisos estuvieran bien en estos 3 lugares, lo cual es tan simple como:
a)Dar click derecho, elegir propiedades

b)Pasar a la pestaña seguridad

c)En la sección de permisos de acceso seleccionar personalizados 
d)dar click en editar y seleccionar el permiso de acceso remoto.



*En mi caso solo tuve que hacer la modificación en "Microsoft Visual Studio"

Después de realizar esto al primer intento obtuve mi licencia de desarrollador.

miércoles, 8 de mayo de 2013

Error en el "Application Deployment" HRESULT: 0x89721500 al intentar instalar un archivo .xap en un dispositivo WP

En esta ocasión les comparto como logre solucionar este error (0x89721500) cuando trataba de probar una aplicación, desarrollada por un compañero, intentando instalar el paquete .xap desde la utilidad "Application Deployment" la cual se instala junto con el SDK de Windows Phone.

Después de investigar por la red y probar sin éxito las diversas opciones de solución, las cuales les listo a continuación:
  • Reparar el SDK.
  • Cambiar el idioma del sistema por el mismo del SDK.
  • Reinstalar el SDK en otro idioma

Me fue posible solucionar mi problema simplemente eliminando la siguiente carpeta:
"C:\Users\<username>\AppData\Local\Microsoft\Phone Tools\CoreCon\11.0"

Después de corregir lo anterior, por descuido mío el Application Deployment me envío otro código de error, el cual era que había excedido el número máximo de aplicaciones de desarrollador en mi dispositivo.

Dado que la aplicación solo nos da el numero de error les dejo también esta tabla con los código de error y su descripción.


HRESULT value
Nature of the error
0x8973180E
Zune software is not installed. Please install the latest version of Zune software.
0x8973180F
Incorrect version of the Zune softeware installed. Please download the latest version.
0×89731810
Corrupted device configuration. To correct this problem, reinstall Visual Studio 2010 Express for Windows Phone.
0×89731811
Zune software is not started. Please try again from the Zune to ensure that the software is running.
0×89731812
Connection to device failed. Please ensure the phone is connected and the not on the lock screen.
0×89731813
Application failed to start. Please ensure that the device has been registered and unlocked. Explanation on how to register can be found here http://go.microsoft.com/fwlink/?LinkId=195284.
0×81030110
Failed to install the application. Runtime error has occurred. Capabilities WMAppManifest.xml file located in the attribute content is incorrect. (This link might help)
0×81030111
Ensure the app has finished uninstalling before redeploying. (From personal experience)
0×81030118
Installation of the application failed. Device is developer locked. Register for the developer unlock program before deploying the application.
0×81030119
You cannot install the application. You have reached the maximum number of applications being developed for the device can be installed on this development. Please uninstall a previous developer application. (I believe the current limit it 10 side-loaded apps at a time).