Windows 8. Contrato de compartir.

Introducción

Las aplicaciones Windows Store usan contratos y extensiones para interactuar con otras aplicaciones o el propio sistema. Son una de las grandes novedades planteadas en el sistema.

Contratos. Son un acuerdo establecido entre dos o más aplicaciones. Las aplicaciones Windows Store deben incluir declararaciones en el archivo de manifiesto para que puedan comunicarse con Windows y con otras aplicaciones.

Contamos con una gran variedad de contratos entre los que podemos destacar:

  • Buscar: Permite realizar búsquedas en la aplicación e incluso en otras aplicaciones.
  • Reproducir en: Permite reproducir contenido en dispositivos DLNA.
  • Configuración: Permiten gestionar un acceso rápido a la configuración relacionada con la aplicación.
  • Compartir: Permite al usuario compartir información entre aplicaciones. Nos facilita mucho la tarea de compartir contenido ahorrandonos una gran cantidad de código extra. Las aplicaciones que admiten el contrato compartir pueden compartir  contenido con otras aplicaciones que también lo admitan.

Los contratos nos facilitan mucho trabajo ahorrandonos mucha cantidad de código. Además nos permite con suma facilidad cumplir una de las grandes premisas de unas aplicaciones Windows Store. Una aplicación Windows Store debe ser excelente en un único aspecto antes que cumplir en múltiples. Los contratos permiten que las aplicaciones colaboren entre sí por lo que el usuario tiene aplicaciones excelentes sin perder funcionalidad.

Por último, cabe resaltar un detalle muy importante. Todos los contratos están disponibles para el usuario en la barra de Charms (Contratos) disponible en la parte lateral derecha mediante un simple gesto.

Contrato compartir

En una gran cantidad de aplicaciones Windows Store el usuario puede encontrar información de su interés y quiera compartirla con alguien. El contrato de Share nos permite compartir información de manera fácil y rápida.

Una aplicación Windows Store puede admitir la característica de compartir de dos formas. Puede ser una aplicación de origen. Es decir, proporciona contenido a compartir. O puede ser una aplicación de destino que el usuario puede seleccionar como destino del contenido.

El siguiente diagrama es un resumen de cómo funciona el uso compartido de contenido (origen y destino):

Share

Share

¿Qué tipo de información se puede compartir?

  • Texto plano.
  • Enlaces.
  • Texto con formato. HTML.
  • Archivos.
  • Imágenes.

En esta entrada vamos a centrar nuestra atención en el contrato de búsqueda como origen (fuente de información).

Compartir. Origen.

Como siempre solemos hacer vamos a realizar un ejemplo lo más simple posible pero que nos sea válida para lograr nuestros objetivos. La plantilla selecciona para realizar el ejemplo lo más simple posible será “Blank Application”:

Blank Application

Sólo podemos compartir un tipo de datos por cada página. Por ello, vamos a crear un pequeño menú de botones que nos permitirá navegar a diferentes páginas donde vamos a implementar la posibilidad de compartir contenido:

<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
     <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
          <Button x:Name="btnShareText" Content="Compartir Texto plano" Height="150" Width="250"/>
          <Button x:Name="btnShareFormattedText" Content="Compartir Texto con formato" Height="150" Width="250"/>
          <Button x:Name="btnShareImage" Content="Compartir Imagen" Height="150" Width="250"/>
          <Button x:Name="btnShareLink" Content="Compartir Enlace" Height="150" Width="250"/>
     </StackPanel>
</Grid>

Tras añadir los botones, añadimos los eventos Click de cada botón:

<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
     <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
          <Button x:Name="btnShareText" Content="Compartir Texto plano" Height="150" Width="250" Click="btnShareText_Click"/>
          <Button x:Name="btnShareFormattedText" Content="Compartir Texto con formato" Height="150" Width="250" Click="btnShareFormattedText_Click"/>
          <Button x:Name="btnShareImage" Content="Compartir Imagen" Height="150" Width="250" Click="btnShareImage_Click"/>
          <Button x:Name="btnShareLink" Content="Compartir Enlace" Height="150" Width="250" Click="btnShareLink_Click"/>
     </StackPanel>
</Grid>

El aspecto visual conseguido es algo como lo siguiente:

UI

UI

En el code-behind:

private void btnShareText_Click(object sender, RoutedEventArgs e)
{

}

private void btnShareFormattedText_Click(object sender, RoutedEventArgs e)
{

}

private void btnShareImage_Click(object sender, RoutedEventArgs e)
{

}

private void btnShareLink_Click(object sender, RoutedEventArgs e)
{

}

Cada botón va a permitirnos navegar a una nueva página donde implementaremos el contrato Share para poder compartir un tipo de dato diferente en cada página. Para ello debemos añadir nuevas páginas al proyecto. Creamos una carpeta llamada Views. Dentro de la carpeta agregamos cuatro páginas:

  • Text. En esta página vamos a compartir texto plano. Caso más simple.
  • Link. Compartiremos enlaces.
  • FormattedText. Compartiremos texto con formato. HTML.
  • Image. Compartiremos imagenes.

Añadimos la lógica a cada botón para permitir la navegación:

private void btnShareText_Click(object sender, RoutedEventArgs e)
{
     this.Frame.Navigate(typeof(Text));
}

private void btnShareFormattedText_Click(object sender, RoutedEventArgs e)
{
     this.Frame.Navigate(typeof(FormattedText));
}

private void btnShareImage_Click(object sender, RoutedEventArgs e)
{
     this.Frame.Navigate(typeof(Ejemplo_Contrato_Compartir.Views.Image));
}

private void btnShareLink_Click(object sender, RoutedEventArgs e)
{
     this.Frame.Navigate(typeof(Link));
}

Vamos a analizar el código necesario en cada una de las páginas para compartir:

Texto Plano

Para poder utilizar el contrato Share debemos añadir la referencia al siguiente namespace:

using Windows.ApplicationModel.DataTransfer;

En primer lugar, necesitamos definir un objeto de tipo DataTransferManager.

DataTransferManager _dataTransferManager;

Al entrar en la página (evento OnNavigatedTo) instanciamos el objeto de tipo DataTransferManager. Además, crearemos un controlador de eventos para el evento DataRequested que se lanzará al solicitar datos en la página para ser compartidos:

protected override void OnNavigatedTo(NavigationEventArgs e)
{
     base.OnNavigatedTo(e);
     _dataTransferManager = DataTransferManager.GetForCurrentView();
     _dataTransferManager.DataRequested += _dataTransferManager_DataRequested;
}

Recordar siempre cancelar la suscripción al evento DataRequested al salir de la página (buena práctica):

protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
     base.OnNavigatingFrom(e);
     _dataTransferManager.DataRequested -= _dataTransferManager_DataRequested;
}

Por último, queremos compartir un simple texto. Lo haremos en el método _dataTransferManager_DataRequested:

void _dataTransferManager_DataRequested(DataTransferManager sender, DataRequestedEventArgs args)
{
     string textTitle = "Título a compartir";
     string textSource = "Contenido a compartir. En este ejemplo, texto plano, sin formato.";

     DataPackage data = args.Request.Data;
     data.Properties.Title = textTitle;
     data.SetText(textSource);
}

Simple. Creamos un objeto de tipo DataPackage y establecemos las propiedades básicas donde establecemos el texto plano a compartir tilizando el método SetText.

Enlaces

Para el resto de páginas (enlaces, texto con formato e imagenes) debemos repetir una gran parte de la lógica ya explicada. Crear el objeto de tipo DataTransferManager, instanciarlo al entrar en la página, suscribirnos al evento DataRequested, etc. Por ello, vamos a suprimir dicha repetición centrandonos en la parte cambiante e importante, la lógica dentro del evento DataRequested.

El compartir un enlace es muy similar al compartir texto plano. Creamos un objeto de tipo DataPackage e establecemos propiedades. La gran diferencia es que utilizaremos un objeto tipo Uri para indicar la URL. Establecemos la Uri mediente el método SetUri.

void _dataTransferManager_DataRequested(DataTransferManager sender, DataRequestedEventArgs args)
{
     string textTitle = "Compartir un enlace";

     DataPackage data = args.Request.Data;
     data.Properties.Title = textTitle;

     Uri link = new Uri("https://javiersuarezruiz.wordpress.com");
     data.SetUri(link);
}

HTML

Sin duda una de las formas más extendidas de compartir contenido. Veamos como sería:

void _dataTransferManager_DataRequested(DataTransferManager sender, DataRequestedEventArgs args)
{
     string textTitle = "Título a compartir";
     string formattedTextSource = "Contenido a compartir. En este ejemplo, texto <strong>con</strong> formato.";

     DataPackage data = args.Request.Data;
     data.Properties.Title = textTitle;
     data.SetHtmlFormat(HtmlFormatHelper.CreateHtmlFormat(formattedTextSource));
}

Comenzamos como hasta ahora. Creamos una cadena con setencias HTML. A continuación, creamos un objeto de tipo DataPackage. Establecemos las propiedades donde lo más importante a resaltar que establecemos el texto con formato utilizando el método SetHtmlFormat. El texto con formato se consigue haciendo una llamada a HtmlFormatHelper que recibirá una cadena de texto que convertirá a HTML.

Imágenes

Vamos a ver el código necesario para compartir imagenes:

async void _dataTransferManager_DataRequested(DataTransferManager sender, DataRequestedEventArgs args)
{
     string textTitle = "Título a compartir";
     string textSource = "Contenido a compartir. En este ejemplo, una imagen.";

     DataPackage data = args.Request.Data;
     data.Properties.Title = textTitle;
     data.Properties.Description = textSource;

     DataRequestDeferral waiter = args.Request.GetDeferral();

     StorageFile image = await Package.Current.InstalledLocation.GetFileAsync("Assets\\Logo.png");
     data.Properties.Thumbnail = RandomAccessStreamReference.CreateFromFile(image);
     data.SetBitmap(RandomAccessStreamReference.CreateFromFile(image));

     List<IStorageItem> files = new List<IStorageItem>();
     files.Add(image);
     data.SetStorageItems(files);

     waiter.Complete();
}

Utilizamos el ya conocido objeto DataPackage donde establecemos la imágen a compartir utilizando el método SetBitmap.

Puedes descargar el ejemplo realizado:

En próximas entradas seguiremos analizando el contrato de compartir. Veremos como compartir documentos RTF, archivos, etc. Además, veremos como podemos establecer nuestra aplicación como fuente de información en el contrato de compartir.  Recordar, cualquier duda o sugerencia será bienvenida en los comentarios de la entrada.

Más información

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s