Exercício: criar o aplicativo conversor de número de telefone
Neste exercício, você criará a interface do usuário do aplicativo discador e implementará a lógica relacionada.
Você criará uma interface do usuário que aproveita as funcionalidades de interface do usuário do .NET MAUI (Multi-Platform App UI) e do pacote .NET MAUI Essentials para discar o telefone.
O aplicativo permite que o usuário digite um texto em um campo de entrada e converta esse texto em dígitos numéricos. Ele usa as letras que aparecem em um teclado numérico do telefone como base para a conversão. Por exemplo, as letras cab se convertem em 222 porque o dígito 2 possui todas as três letras a, b e c.
Você continuará com a solução Phoneword criada no exercício anterior.
Adicionar um novo arquivo de origem C# ao aplicativo
Abra a solução noPhoneword no Visual Studio se ela ainda não estiver aberta.
Na janela Gerenciador de Soluções, clique com o botão direito do mouse no projeto Phoneword, selecione Adicionar e selecione Classe.
Na caixa de diálogo Adicionar novo item, nomeie o arquivo de classe PhonewordTranslator.cs e selecione Adicionar.
Adicionar a lógica de conversão
Substitua o conteúdo do arquivo de classe pelo código a seguir e salve o arquivo. O método estático ToNumber
na classe PhonewordTranslator
converte o número de texto alfanumérico em um valor de telefone numérico normal.
using System.Text;
namespace Core;
public static class PhonewordTranslator
{
public static string ToNumber(string raw)
{
if (string.IsNullOrWhiteSpace(raw))
return null;
raw = raw.ToUpperInvariant();
var newNumber = new StringBuilder();
foreach (var c in raw)
{
if (" -0123456789".Contains(c))
newNumber.Append(c);
else
{
var result = TranslateToNumber(c);
if (result != null)
newNumber.Append(result);
// Bad character?
else
return null;
}
}
return newNumber.ToString();
}
static bool Contains(this string keyString, char c)
{
return keyString.IndexOf(c) >= 0;
}
static readonly string[] digits = {
"ABC", "DEF", "GHI", "JKL", "MNO", "PQRS", "TUV", "WXYZ"
};
static int? TranslateToNumber(char c)
{
for (int i = 0; i < digits.Length; i++)
{
if (digits[i].Contains(c))
return 2 + i;
}
return null;
}
}
Criar a interface do usuário
Abra o arquivo MainPage.xaml no projeto Phoneword.
Remova o controle
ScrollView
e o conteúdo dele, deixando apenas o controleContentPage
:<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Phoneword.MainPage"> </ContentPage>
Adicione um controle
VerticalStackLayout
com orientação vertical e um espaçamento de 15 unidades e preenchimento de 20 unidades a ContentPage:<ContentPage ... > <VerticalStackLayout Spacing="15" Padding="20"> </VerticalStackLayout> </ContentPage>
Adicione um controle
Label
ao StackLayout:<ContentPage ... > <VerticalStackLayout ...> <Label Text = "Enter a Phoneword" FontSize ="20"/> </VerticalStackLayout> </ContentPage>
Adicione um controle
Entry
ao StackLayout, abaixo do rótulo. Um controleEntry
fornece uma caixa de texto na qual o usuário pode inserir dados. Nesse código, a propriedadex:Name
dá um nome ao controle. Você referenciará esse controle no código do aplicativo mais tarde:<ContentPage ... > <VerticalStackLayout ...> <Label .../> <Entry x:Name = "PhoneNumberText" Text = "1-555-NETMAUI" /> </VerticalStackLayout> </ContentPage>
Adicione dois controles
Button
ao VerticalStackLayout, após o controle Entry. No momento, ambos os botões não fazem nada, e o segundo está desabilitado inicialmente. Você adicionará o código para manipular o eventoClicked
para esses dois botões na próxima tarefa:<ContentPage ... > <VerticalStackLayout ...> <Label .../> <Entry ... /> <Button x:Name = "TranslateButton" Text = "Translate" Clicked = "OnTranslate"/> <Button x:Name = "CallButton" Text = "Call" IsEnabled = "False" Clicked = "OnCall"/> </VerticalStackLayout> </ContentPage>
Responder ao toque no botão TranslateButton
Na janela do Gerenciador de Soluções, expanda a entrada MainPage.xaml e abra o arquivo code-behind MainPage.xaml.cs.
Na classe
MainPage
, remova a variávelcount
e o métodoOnCounterClicked
. A classe deve ter esta aparência:namespace Phoneword; public partial class MainPage : ContentPage { public MainPage() { InitializeComponent(); } }
Adicione a variável de cadeia de caracteres
translatedNumber
e o métodoOnTranslate
a seguir à classeMainPage
, após o construtor. O métodoOnTranslate
recupera o número de telefone da propriedadeText
do controleEntry
e o transmite ao métodoToNumber
estático da classePhonewordTranslator
criada anteriormente.public partial class MainPage : ContentPage { ... string translatedNumber; private void OnTranslate(object sender, EventArgs e) { string enteredNumber = PhoneNumberText.Text; translatedNumber = Core.PhonewordTranslator.ToNumber(enteredNumber); if (!string.IsNullOrEmpty(translatedNumber)) { // TODO: } else { // TODO: } } }
Observação
Você preencherá os bits TODO ausentes desse código na próxima etapa.
No método
OnTranslate
, adicione o código para alterar a propriedadeText
do botão Chamar para acrescentar o número de telefone convertido com sucesso. Você pode usar o valor armazenado no campo translatedNumber. Além disso, habilite e desabilite o botão com base na conversão bem-sucedida. Por exemplo, seTranslateNumber
retornou nulo, desabilite o botão, mas se tiver êxito, habilite-o.private void OnTranslate(object sender, EventArgs e) { string enteredNumber = PhoneNumberText.Text; translatedNumber = Core.PhonewordTranslator.ToNumber(enteredNumber); if (!string.IsNullOrEmpty(translatedNumber)) { CallButton.IsEnabled = true; CallButton.Text = "Call " + translatedNumber; } else { CallButton.IsEnabled = false; CallButton.Text = "Call"; } }
Criar o método de evento para o botão CallButton
Adicione o método de manipulação de eventos
OnCall
ao final da classeMainPage
. Esse método faz uso de operações assíncronas, portanto, marque-o comoasync
:public partial class MainPage : ContentPage { ... async void OnCall(object sender, System.EventArgs e) { } }
No método
OnCall
, use o método Page.DisplayAlert para perguntar ao usuário se ele deseja discar o número.Os parâmetros para
DisplayAlert
são um título, uma mensagem e duas cadeias de caracteres usadas para o texto de botão Aceitar e Cancelar. Ele retorna um valor booliano que indica se o botão Aceitar foi pressionado para ignorar a caixa de diálogo.async void OnCall(object sender, System.EventArgs e) { if (await this.DisplayAlert( "Dial a Number", "Would you like to call " + translatedNumber + "?", "Yes", "No")) { // TODO: dial the phone } }
Testar o aplicativo
Na barra de ferramentas do Visual Studio, selecione o perfil Computador Windows e comece a depurar.
Toque no botão Converter para converter o texto padrão em um número de telefone válido. A legenda no botão Chamar mudará para Chamar 1-555-6386284:
Toque no botão Chamar. Verifique se é exibido um prompt solicitando que você confirme a operação. Selecione Não.
Retorne ao Visual Studio e interrompa a depuração.
Discar o número de telefone
No arquivo code-behind MainPage.xaml.cs, edite o método OnCall e substitua o comentário TODO pelos seguintes blocos
try/catch
:async void OnCall(object sender, System.EventArgs e) { if (await this.DisplayAlert( "Dial a Number", "Would you like to call " + translatedNumber + "?", "Yes", "No")) { try { if (PhoneDialer.Default.IsSupported) PhoneDialer.Default.Open(translatedNumber); } catch (ArgumentNullException) { await DisplayAlert("Unable to dial", "Phone number was not valid.", "OK"); } catch (Exception) { // Other error has occurred. await DisplayAlert("Unable to dial", "Phone dialing failed.", "OK"); } } }
A classe PhoneDialer no namespace Microsoft.Maui.ApplicationModel.Communication fornece uma abstração da funcionalidade de discagem (e outras) para as plataformas Windows, Android, iOS (e iPadOS) e macOS. O método Open estático tenta usar o discador do telefone para fazer uma chamada para o número fornecido como parâmetro.
As etapas a seguir mostram como atualizar o manifesto do aplicativo Android para permitir que o Android use o discador de telefone. Os aplicativos para Windows, iOS e MacCatalyst seguem o mesmo princípio geral, exceto pelo fato de que você especifica uma funcionalidade diferente no manifesto, dependendo do sistema operacional.
Na janela Gerenciador de Soluções, expanda a pasta Plataformas, expanda a pasta Android, clique com o botão direito do mouse no arquivo AndroidManifest.xml e selecione Abrir com>Seletor Automático de Editor (XML). Selecione OK.
Adicione o snippet XML a seguir no nó de manifesto, após o conteúdo existente para esse nó.
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"> ... <queries> <intent> <action android:name="android.intent.action.DIAL" /> <data android:scheme="tel"/> </intent> </queries> </manifest>
Salve o arquivo.
Na barra de ferramentas do Visual Studio, selecione o perfil Emuladores Android/Pixel 3a – API 30 (ou semelhante) e inicie a depuração.
Quando o aplicativo aparecer no emulador (isso pode levar alguns minutos), insira um número de telefone (ou aceite o padrão), selecione Converter e, em seguida, Chamar.
No alerta Discar um Número, selecione Sim. Verifique se o discador de telefone do Android é exibido com o número que você forneceu no aplicativo.
Retorne ao Visual Studio e interrompa a depuração.
Resumo
Neste exercício, você adicionou uma interface do usuário personalizada a seu aplicativo usando páginas e exibições. Você também adicionou suporte para fazer uma chamada por meio de APIs específicas de plataforma disponíveis no Android.