Exercício: crie o aplicativo de conversão de número de telefone

Concluído

Neste exercício, você construirá a interface do usuário para o aplicativo de discagem telefônica e implementará a lógica por trás dessa interface do usuário.

Você criará uma interface do usuário que aproveitará os recursos da interface do usuário do .NET MAUI e do pacote .NET MAUI Essentials para discar o telefone.

O aplicativo permitirá que o usuário digite texto em um campo de entrada e traduzirá esse texto para dígitos numéricos. Ele usará as letras que aparecem em um teclado de telefone como base para a tradução. Por exemplo, as letras cab traduzem para 222 porque o dígito 2 tem 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

  1. Abra a solução Phoneword no Visual Studio se ainda não a tiver aberta.

  2. Na janela Gerenciador de Soluções, clique com o botão direito do mouse no projeto Phoneword, selecione Adicionar e selecione Classe.

  3. Na caixa de diálogo Adicionar Novo Item, nomeie o arquivo de classe PhonewordTranslator.cs e selecione Adicionar.

    A screenshot of the Add new item dialog box. The user has named the class file PhonewordTranslator.cs

Adicionar a lógica de tradução

Substitua o conteúdo do arquivo de classe pelo código a seguir e salve o arquivo. O método ToNumber estático na PhonewordTranslator classe traduz o número de texto alfanumérico em um número de telefone numérico regular.

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

  1. Abra o arquivo MainPage.xaml no projeto Phoneword .

  2. Remova o controle e seu conteúdo, deixando apenas o ScrollViewContentPage controle:

    <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Phoneword.MainPage">
    
    </ContentPage>
    
  3. Adicione um controle com orientação vertical e um VerticalStackLayout espaçamento de 15 unidades e preenchimento de 20 unidades à ContentPage:

    <ContentPage ... >
        <VerticalStackLayout Spacing="15" Padding="20">
    
        </VerticalStackLayout>
    </ContentPage>
    
  4. Adicione um Label controle ao StackLayout:

    <ContentPage ... >
        <VerticalStackLayout ...>
            <Label Text = "Enter a Phoneword"
                   FontSize ="20"/>
        </VerticalStackLayout>
    </ContentPage>
    
  5. Adicione um Entry controle ao StackLayout, abaixo do rótulo. Um Entry controle fornece uma caixa de texto na qual o usuário pode inserir dados. Neste código, a propriedade x:Name dá um nome ao controle. Você fará referência a esse controle no código do aplicativo mais tarde:

    <ContentPage ... >
        <VerticalStackLayout ...>
            <Label .../>
            <Entry x:Name = "PhoneNumberText"
                   Text = "1-555-NETMAUI" />
        </VerticalStackLayout>
    </ContentPage>
    
  6. Adicione dois Button controles ao VerticalStackLayout, após o controle Entry. Ambos os botões atualmente não fazem nada, e o segundo está desativado inicialmente. Você adicionará o código para manipular o Clicked evento 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>
    

Responda ao toque no botão TranslateButton

  1. Na janela Gerenciador de Soluções, expanda a entrada MainPage.xaml e abra o arquivo code-behind MainPage.xaml.cs.

  2. MainPage Na classe, remova a count variável e o OnCounterClicked método. A classe deve ter esta aparência:

    namespace Phoneword;
    
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
        }
    }
    
  3. Adicione a translatedNumber variável string e o seguinte método à MainPage classe, após o OnTranslate construtor. O OnTranslate método recupera o número de telefone da Text propriedade do Entry controle e o passa para o método estático ToNumber da PhonewordTranslator classe que você criou 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:
            }
        }
    }
    

    Nota

    Você preencherá os bits TODO ausentes deste código na próxima etapa.

  4. OnTranslate No método, adicione código para alterar a Textpropriedade do botão Call para incluir o número de telefone quando ele for traduzido com êxito. Você pode usar o valor armazenado no campo TranslatedNumber. Além disso, ative e desative o botão com base na tradução bem-sucedida. Por exemplo, se retornado nulo, desative o botão, mas se TranslateNumber ele foi bem-sucedido, 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

  1. Adicione o OnCall método de manipulação de eventos ao final da MainPage classe. Este método fará uso de operações assíncronas, portanto, marque-o como async:

    public partial class MainPage : ContentPage
    {
    
        ...
        async void OnCall(object sender, System.EventArgs e)
        {
    
        }
    }
    
  2. OnCall No método, peça ao usuário, usando o método Page.DisplayAlert, para perguntar se deseja discar o número.

    Os parâmetros são DisplayAlert um título, uma mensagem e duas cadeias de caracteres usadas para o texto do botão Aceitar e Cancelar. Ele retorna um booleano indicando se o botão Aceitar foi pressionado para descartar 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 a aplicação

  1. Na barra de ferramentas do Visual Studio, selecione o perfil do Windows Machine e inicie a depuração.

  2. Toque no botão Traduzir para converter o texto padrão em um número de telefone válido. A legenda no botão Ligar deve mudar para Ligar para 1-555-6386284:

    A screenshot of the Phoneword UI. The user has translated the text to a valid phone number.

  3. Toque no botão Ligar . Verifique se aparece um prompt solicitando que você confirme a operação. Selecione Não.

    A screenshot of the PhoneWord user interface's Dial a Number prompt.

  4. Retorne ao Visual Studio e pare a depuração.

Disque o número de telefone

  1. No arquivo code-behind .cs MainPage.xaml, edite o método OnCall e substitua o comentário TODO pelos seguintes try/catch blocos:

    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 telefônica (e outras) para as plataformas Windows, Android, iOS (e iPadOS) e macOS. O método Open estático tenta usar o discador telefônico para chamar 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 do telefone. Os aplicativos Windows, iOS e MacCatalyst seguem o mesmo princípio geral, exceto que você especifica um recurso dependente do sistema operacional diferente no manifesto.

  2. 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>o Seletor Automático de Editor (XML). Selecione OK.

  3. Adicione o seguinte trecho XML dentro do 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>
    
  4. Guarde o ficheiro.

  5. Na barra de ferramentas do Visual Studio, selecione o perfil Android Emulators/Pixel 3a - API 30 (ou similar) e inicie a depuração.

  6. Quando o aplicativo aparecer no emulador (isso pode levar alguns minutos), digite um número de telefone (ou aceite o padrão), selecione Traduzir e, em seguida, selecione Ligar.

  7. No alerta Discar um Número, selecione Sim. Verifique se o discador do telefone Android aparece com o número que você forneceu no aplicativo.

    The Android phone dialer containing the number provided by the app.

  8. Retorne ao Visual Studio e pare a depuração.

Resumo

Neste exercício, você adicionou uma interface do usuário personalizada ao seu aplicativo usando páginas e modos de exibição. Você também adicionou suporte para fazer uma chamada usando APIs específicas da plataforma disponíveis no Android.