Browsing posts in: Windows 8

Cómo hacer que PointerPressed y PointerReleased funcionen en un botón de Windows 8 con C#

Hoy, haciendo algunas pruebas para el trabajo, tuve la necesidad de detectar sólo cuando el usuario está -activamente- presionando un botón. Es decir, no el evento click/tap ni un hold, sólo cuando tiene el click/dedo encima del botón mientras lo mantiene presionado. Esto se corresponde con los eventos PointerPressed y PointerReleased de los elementos visuales.

El problema, en Windows 8, está en que estos eventos no se disparan correctamente en un botón, directamente no se disparan. Algo disparatado, realmente, teniendo en cuenta que es un elemento visual que está hecho específicamente para ser presionado. Sea como fuere, puede haber dos soluciones:

  1. Si necesitas varios botones pulsados a la vez entonces, la solución no es usar un botón, sino un Grid, como bien me sugirió Adrián Fernández.
  2. Si sólo necesitas un botón a la vez, la solución pasa por hacerlo de una manera más rústica que sólo suscribiéndose al PointerPressed y PointerReleased, con el siguiente código:
BotonQueNecesites.AddHandler(PointerPressedEvent, new PointerEventHandler(BotonQueNecesites_PointerPressed), true);

Recuerda que puedes usar Ctrl+. sobre BotonQueNecesites_PointerPressed para poder crear el método con los argumentos correctos, sin necesidad de sabértelos de memoria. Así pues, el caso contrario par el PointerReleased resulta análogo:

BotonQueNecesites.AddHandler(PointerReleasedEvent, new PointerEventHandler(BotonQueNecesites_PointerReleased), true);

A partir de esto, sólo queda definir los handlers:

private void BotonQueNecesites_PointerReleased(object sender, PointerRoutedEventArgs e)
{
     output.Text = "Released";
}

private void BotonQueNecesites_PointerPressed(object sender, PointerRoutedEventArgs e)
{
     output.Text = "Pressed";
}

Habilitar Single Sign-On con Mobile Services y el Live SDK en Windows Phone 8 y Windows 8 con C#

Vamos al grano, lo que queremos: autenticar automágicamente a un usuario cuando se abra la aplicación, que sólo tenga que meter su usuario y contraseña una sola vez, la primera vez que abre la app.

Como soluciones posibles, Quique y yo, fuimos a por la forma “sencilla” en WinJS: serializar y guardar el usuario en local, luego checkear el usuario antes de intentar autenticarlo otra vez, pero hay una mejor forma de hacerlo: habilitar el Single Sign-On del Live SDK, autenticarte con él en la aplicación de Live que debes tener creada igualmente si quieres el provider de la Microsoft Account en Mobile Services y luego usar la sobrecarga del método LoginAsync que toma como argumento una string con el token que te devuelve la autenticación del Live. Vamos allá:

En Windows Phone 8

En un método Authenticate que queráis. Como nota, en Windows Phone 8, los métodos de autenticación deben ir en el Loaded, más que en el OnNavigatedTo para no hacer guarradas, ya que en WP8 se navega a otra página para hacer el logueo y pedir permisos, no así en W8, por lo que tendríais 2 OnNavigatedTo, causando una excepción si no implementáis un centinela (caí en esto gracias a Gorka en el mail de soporte):


while (liveSession == null)
 {

var authClient = new LiveAuthClient("<<TU ID DE APP>>");

string [] reqs = new[] { "wl.signin", "wl.basic", "wl.offline_access" };
 var init = await authClient.InitializeAsync(reqs);

var session = authClient.Session;

if (init.Status != LiveConnectSessionStatus.Connected)
 {
 MessageBox.Show("This app needs an authenticated user to work, please check mygym.azurewebsites.net  for info & privacy", "Please Log in", MessageBoxButton.OK); //cambia por tu sitio
 var logStatus = await authClient.LoginAsync(reqs);

if (logStatus.Status == LiveConnectSessionStatus.Connected)
 {
//primer login
 session = logStatus.Session;
 liveSession = session;
 LiveConnectClient client = new LiveConnectClient(liveSession);
 LiveOperationResult meResult = await client.GetAsync("me");
 string title = string.Format("Welcome {0}!", meResult.Result["first_name"]);
 MessageBox.Show("Welcome to My Gym for the first time, please check mygym.azurewebsites.net for more info or how-to.", title, MessageBoxButton.OK); //reemplazad con vuestros datos
 user = await mobileServiceClient.LoginAsync(session.AuthenticationToken); //esta es la autenticación hacia Mobile Services
 }
 }

if (init.Status == LiveConnectSessionStatus.Connected)
 {
 //el resto de logins
 liveSession = session;
 user = await mobileServiceClient.LoginAsync(session.AuthenticationToken); //autenticación contra Mobile Services
 }

}

Con esto ya lo tenéis acabado, sólo os pedirá user/pass la primera vez que se ejecute la app después de cada instalación.

En Windows 8

Aquí es más o menos lo mismo, aunque el Authenticate puede ir en un OnNavigatedTo, ya que internamente usa WebAuthBroker, que no navega a otra página, sino que saca un pop-up. Lo que cambia es la forma de inicializar el cliente de Live, que no se inicializa con el ID de la app, sino con la URL de callback, además de haber simplificado el código, quitando un par de llamadas al Live para obtener el nombre, por ejemplo:

var authClient = new LiveAuthClient("<<URL DE TU SERVICIO>>");

            reqs = new[] { "wl.signin", "wl.basic", "wl.offline_access" };
            var init = await authClient.InitializeAsync(reqs);

            var session = authClient.Session;

            if (init.Status != LiveConnectSessionStatus.Connected)
            {
                //hay que autenticarse
                var logStatus = await authClient.LoginAsync(reqs);

                if (logStatus.Status == LiveConnectSessionStatus.Connected)
                {
                    //primera autenticación
                    session = logStatus.Session;
                    user = await mobileServiceClient.LoginAsync(session.AuthenticationToken);
                }
            }

            if (init.Status == LiveConnectSessionStatus.Connected){
            //resto de logins
            user = await mobileServiceClient.LoginAsync(session.AuthenticationToken);

            }

¡Todo hecho!. ¿Dudas? Tenéis los comentarios 🙂


Cómo depurar remotamente en Windows RT

escritorio

Si habéis sido buenos estas navidades, a muchos -ojalá- os habrá quedado el escritorio con una configuración parecida a la del mio. En mi caso fue una Asus Vivo Tab RT por cortesía del Desafío Windows 8 de Microsoft. Al ser arquitectura ARM, Visual Studio 2012 no entra en ella, pero aún así nos servirá como un dispositivo de prueba de nuestros desarrollos, además, un entorno diferente a nuestro PC, haciendo más variado -y divertido– el testing. En fin, que si has entrado aquí es porque sabes qué es lo que esperabas encontrar, así que vamos al lío:

Continue Reading


Cómo incluir la política de privacidad en opciones de configuración de la aplicación en Windows 8

Hace unos días estaba subiendo una de mis primeras aplicaciones para la Windows 8 Store, así que, antes de subirla, decidí darle un último repaso a las exigencias de la Store, entonces recordé algo que vi en el MSP Summit de Madrid de la semana pasada: si usas Internet en tu app, debes incluir una política de privacidad dentro del menú de configuración de tu aplicación, enmarcada dentro de la barra de charms. Tras una búsqueda rápida por los foros de MSDN no encontré nada, así que, yendo a algo más potente, estos son los resultados de la búsqueda. Vamos allá:

Primero hemos de crear una web donde dejemos clara nuestra política de privacidad. En mi caso, la aplicación no recogía datos de usuario de ningún tipo, sencillamente usaba Internet para mostrar información, así que tomé uno cualquiera de ejemplo y lo modifiqué, quedando así. Guarda el link a tu página, ya que tendrás que ponerlo cuando subas la aplicación a la store.

Segundo vamos al código. La mecánica es sencilla, nos suscribimos al evento CommandsRequested de la vista actual en otro evento que tengamos o método. Lo suyo es hacerlo en el OnNavigatedTo o LoadState, aunque me gusta separarlos y usarlos acorde a su nombre. Así que, al OnNavigatedTo:


protected override void OnNavigatedTo(NavigationEventArgs e){

SettingsPane.GetForCurrentView().CommandsRequested += principal_CommandsRequested;

}

Después de esto el paso es obvio, crear el principal_CommandsRequested :


void principal_CommandsRequested(SettingsPane sender, SettingsPaneCommandsRequestedEventArgs args){

AddSettingsCommands(args);

}

¿Alguien duda del siguiente paso?


public static void AddSettingsCommands(SettingsPaneCommandsRequestedEventArgs args)

{

args.Request.ApplicationCommands.Clear();

SettingsCommand privacyPref = new SettingsCommand("privacyPref", "Política de Privacidad", (uiCommand) =>{Windows.System.Launcher.LaunchUriAsync(newUri("http://danielrozo.es/privacy-policy")); });

args.Request.ApplicationCommands.Add(privacyPref);

}

Y con esto debería estar todo hecho, compiláis y corréis la aplicación y veréis cómo sale “Política de Privacidad” bajo la configuración de vuestra aplicación y cuando hagáis clic os llevará a la página que hayáis configurado al efecto :).