Por Helder Ferreira para o PPLWARE.COM
Utilização dos recursos do dispositivo
Após no último artigo termos analisado os principais controlos disponibilizados para esta plataforma de desenvolvimento, vamos neste artigo utilizar recursos do dispositivo.
Nos dispositivos Windows Phone 7, temos acesso a vários sensores que são incluídos de base nos mesmos, aqui a vantagem dada pela Microsoft é que do lado de quem desenvolve aplicações não é necessário preocupar com questões mais técnicas relativamente aos sensores visto existirem regras do lado dos fabricantes para que todos os dispositivos funcionem da mesma forma.
Deste modo a equipa de desenvolvimento pode focar os esforços nas regras de negócio das suas aplicações e não na criação de vários métodos para funcionarem em dispositivos distintos.
Introdução aos Launchers e Choosers
Nas aplicações Silverlight para Windows Phone são utilizadas estas duas opções para aceder a funcionalidades build-in dos dispositivos, quando executamos um destes métodos a aplicação é desactivada e a aplicação seleccionada é executada. Quando a aplicação termina a nossa aplicação é reactivada. Este processo é chamado de tombstoning em artigos futuros iremos falar mais sobre este processo e do impacto que pode ter nas nossas aplicações visto estarmos a falar de um sistema sem multitasking.
Os Launchers e Choosers estão no namespace Microsoft.Phone.Tasks, por isso temos que incluir uma directiva Using no nosso código para utilizar estes recursos.
Launchers
A forma de utilizar estas classes é comum, ou seja:
- Criar uma nova instância da classe;
- Atribuir as propriedades à mesma;
- Executar o método Show.
Vamos então ver alguns exemplos:
PhoneCallTask – Usado para efectuar chamadas indicando o número a ser marcado, ou podemos também exibir a lista de contactos a partir da qual o utilizador pode seleccionar o contacto para o qual deseja fazer a chamada.
Vamos adicionar no XAML um simples botão para efectuar a chamada,
<Button Name="ButtonDialer" Content="Efectuar chamada"
VerticalAlignment="Bottom" Click="ButtonDialer_Click"
Height="79" Margin="0,0,0,10" />
E no código vamos então adicionar o comportamento,
private void ButtonDialer_Click(object sender, RoutedEventArgs e)
{
// launcher.
PhoneCallTask phoneCallTask = new PhoneCallTask();
// Informação de contacto para o qual desejamos efectuar a chamada
phoneCallTask.PhoneNumber = "(352)-555-5555";
phoneCallTask.DisplayName = "pplware";
// Lançamento do objecto.
phoneCallTask.Show();
}
Corremos o projecto e quando o utilizador clicar no botão a chamada é efectuada.
SmsComposeTask – Assim como para efectuar uma chamada, temos também o launcher para enviar mensagens de texto.
XAML
<Button Name="ButtonSmsr" Content="Enviar sms"
VerticalAlignment="Bottom" Click="ButtonSms_Click"
Height="79" Margin="0,0,0,10" />
CODE
private void ButtonSms_Click(object sender, RoutedEventArgs e)
{
// launcher.
SmsComposeTask smsComposeTask = new SmsComposeTask();
// Informação de contacto para o qual desejamos enviar o sms
smsComposeTask.Body = "Mensagem";
smsComposeTask.To = "(352)-555-5555";
// Lançamento do objecto.
smsComposeTask.Show();
}
EmailComposeTask – Vamos terminar esta secção apresentando o Launcher de envio de email.
XAML
<Button Name="ButtonEmail" Content="Enviar email"
VerticalAlignment="Bottom" Click="ButtonEmail_Click"
Height="79" Margin="0,0,0,10" />
CODE
private void ButtonEmail_Click(object sender, RoutedEventArgs e)
{
// launcher.
EmailComposeTask emailComposeTask = new EmailComposeTask();
// Informação de contacto para o qual desejamos efectuar a chamada
emailComposeTask.To = "xpto@hotmail.com";
emailComposeTask.Subject = "Exemplo de email";
emailComposeTask.Body = "Corpo da mensagem";
// Lançamento do objecto.
emailComposeTask.Show();
}
De notar que se executarmos este launcher no emulador, o sistema vai apresentar uma mensagem indicando que a conta de correio electrónico não se encontra configurada. Mas no caso de estarmos a executar a aplicação directamente num dispositivo é apresentado um ecrã em que podemos seleccionar a conta de correio electrónico a utilizar e após isso a mensagem pronta a ser enviada.
Choosers
A principal diferença dos launchers em relação aos choosers prendesse no facto de neste último caso o sistema lança um evento quando o utilizador efectua uma intervenção.
Vamos ver o caso em que a aplicação não sabe o número para o qual deve efectuar uma chamada e pede a intervenção do utilizador para seleccionar um número da sua lista de contactos.
PhoneNumberChooserTask – Se pretendermos que o utilizador seleccione um contacto existente na sua lista, apenas temos que instanciar o chooser PhoneNumberChooserTask.
Neste caso já é lançado um evento quando o utilizador selecciona o contacto para o qual deseja efectuar a chamada. Nesse evento obtemos o número para o qual o utilizador deseja efectuar a chamada e lançamos o launcher PhoneCallTask da mesma forma que já fizemos anteriormente.
XAML
<Button Name="ButtonDialerChooser" Content="Lançar contactos"
VerticalAlignment="Bottom" Click="ButtonDialerChooser_Click"
Height="79" Margin="0,0,0,10" />
CODE
private void ButtonDialerChooser_Click(object sender, RoutedEventArgs e)
{
PhoneNumberChooserTask phoneNumberChooser = new PhoneNumberChooserTask();
phoneNumberChooser.Completed += new EventHandler<PhoneNumberResult>(phoneNumberChooser_Completed);
phoneNumberChooser.Show();
}
void phoneNumberChooser_Completed(object sender, PhoneNumberResult e)
{
if (e.TaskResult == TaskResult.OK)
{
// Chooser.
PhoneCallTask phoneCallTask = new PhoneCallTask();
// Informação de contacto para o qual desejamos efectuar a chamada
phoneCallTask.PhoneNumber = e.PhoneNumber;
// Lançamento do objecto.
phoneCallTask.Show();
}
}
CameraCaptureTask – Com este método podemos tirar proveito das capacidades da câmara fotográfica presente nos dispositivos. Por exemplo, com um simples botão na nossa aplicação invocamos a aplicação built in do sistema para tirar uma foto ou um vídeo e podemos logo de seguida efectuar o tratamento ou apresentação da mesma.
XAML
<Button Name="ButtonCamera" Content="Tirar foto"
VerticalAlignment="Bottom" Click="ButtonCamera_Click"
Height="79" Margin="0,0,0,10" />
<Image Height="400" x:Name="ContainerImagem" />
CODE
private void ButtonCamera_Click(object sender, RoutedEventArgs e)
{
// Chooser.
CameraCaptureTask cameraCaptureTask = new CameraCaptureTask();
cameraCaptureTask.Completed += new EventHandler<PhotoResult>(cameraCaptureTask_Completed);
// Lançamento do objecto.
cameraCaptureTask.Show();
}
void cameraCaptureTask_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
//simply use the picture.
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.SetSource(e.ChosenPhoto);
ContainerImagem.Source = bitmapImage;
}
}
De notar neste exemplo, que declaramos o evento cameraCaptureTask.Completed, o que faz com que após o utilizador tirar a foto um evento é lançado na nossa aplicação com o resultado que neste caso corresponde a uma foto.
Nesse evento apenas aplicamos a foto a um BitmapImage (using System.Windows.Media.Imaging;) e após este passo atribuímos a imagem ao controlo de imagem ContainerImagem para conseguirmos visualizar o resultado.
Nota: Caso estejam a utilizar o emulador, a câmara é substituída por uma Webcam instalada no vosso sistema para que seja mais fácil testar a nossa aplicação.
Estes são apenas alguns exemplos de como utilizar Launcher e Choosers, para uma referência completa de todos os métodos existentes podem aceder à ajuda do namespace tasks em namespace Microsoft.Phone.Tasks
Para terminar vamos verificar como utilizar um componente muito em voga nos dispositivos mais actuais e que pode marcar a diferença nas vossas aplicações.
Acelerómetro
Resumindo, não passa de um sensor que consegue detectar alterações à posição actual do dispositivo normalmente em 3 eixos, x,y e z.
A utilização deste tipo de sensores pode ser bastante interessante no âmbito de utilização da nossa aplicação, um dos exemplos mais típicos é por exemplo mudar a música em execução com um shake ao dispositivo.
Vamos ver um exemplo.
XAML
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Transparent">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="50" />
<RowDefinition Height="50" />
<RowDefinition Height="618*" />
</Grid.RowDefinitions>
<TextBlock Grid.Column="1" Grid.Row="0" Text="X" />
<TextBlock x:Name="txt_x" Grid.Column="2" Grid.Row="0"/>
<TextBlock Grid.Column="1" Grid.Row="1" Text="Y" />
<TextBlock x:Name="txt_y" Grid.Column="2" Grid.Row="1"/>
<TextBlock Grid.Column="1" Grid.Row="2" Text="Z" />
<TextBlock x:Name="txt_z" Grid.Column="2" Grid.Row="2"/>
<Button Content="Iniciar" x:Name="btnIniciar" Grid.Column="2" Margin="50,35,129,494" Grid.Row="3" Click="btnIniciar_Click" />
</Grid>
CODE
// Construtor
Accelerometer accelerometer = new Accelerometer();
public MainPage()
{
InitializeComponent();
}
private void btnIniciar_Click(object sender, RoutedEventArgs e)
{
accelerometer.Start();
accelerometer.ReadingChanged += new EventHandler<AccelerometerReadingEventArgs>(accelerometer_ReadingChanged);
}
void accelerometer_ReadingChanged(object sender, AccelerometerReadingEventArgs e)
{
Deployment.Current.Dispatcher.BeginInvoke(() => ProcessAccelerometerReading(e));
}
private void ProcessAccelerometerReading(AccelerometerReadingEventArgs e)
{
// Actualiza os controlos
txt_x.Text = e.X.ToString("0.00");
txt_y.Text = e.Y.ToString("0.00");
txt_z.Text = e.Z.ToString("0.00");
}
Neste exemplo, colocamos algumas caixas de texto numa página e um botão para que o sistema inicie a captura dos dados do acelerómetro.
Quando clicamos no botão o sistema inicia a captura dos dados relativos à sua posição, x,y e z e no evento accelerometer_ReadingChanged delegamos o objecto AccelerometerReadingEventArgs e para a função ProcessAccelerometerReading que por sua vez trata de preencher as caixas de texto com os dados da posição do dispositivo.
Fazemos esta delegação, visto o processo de captura de dados estar a executar numa thread extra, e nestes casos não conseguimos efectuar o binding directo dessa thread à nossa camada de UI (caixas de texto).
Executando o projecto no dispositivo podemos observar a posição actual do mesmo sendo reflectiva nas caixas de texto no ecrã.
Espero que esta breve introdução à utilização dos recursos que são disponibilizados pelos dispositivos vos tenha dado algumas ideias para as vossas aplicações.
Uma vez mais, caso tenham alguma questão não hesitem em enviar mensagem.
Até à próxima e boa programação em Windows Phone 7.
Artigos relacionados: