DEV Community

Marcos Costa
Marcos Costa

Posted on

Como conectar o Aplicativo MAUI no Emulador Android e WEB Api na mesma máquina

Olá devs, vocês que já estiveram na situação de precisar atualizar o backend direto no servidor para fazer com uma atualização especifica de comportamento de endpoint? E se eu te mostrar que você não precisa fazer isso no seu dia a dia caso você tenha na mesma solução (ou até em diferentes) o aplicativo MAUI e a WEB API? Então, aqui vamos nós. Detalhe: essa dica funciona até para Blazor-MAUI.

Maquina Virtual e Hospedeira (Host)

Primeiro, vamos entender como funciona de forma simplificadíssima uma maquina virtual e o sistema hospedeiro (Host). Nós temos aqui duas entidades, a maquina HOST que é basicamente o seu computador, e a maquina virtual, que nesse caso é a maquina que se comunicará com os recursos de hardware do Host via software. O Emulador Android é simplesmente uma maquina virtual que está consumindo recursos de hardware do HOST via software.

Recursos de redes Emulador Android

Agora, precisamos entender como funciona os recursos de rede do emulador android que está rodando na sua maquina. Como Apresentado na documentação oficial do Google:

Network Address Description
10.0.2.1 Router or gateway address
10.0.2.2 Special alias to your host loopback interface (127.0.0.1 on your development machine)
10.0.2.3 First DNS server
10.0.2.4 / 10.0.2.5 / 10.0.2.6 Optional second, third, and fourth DNS servers
10.0.2.15 The emulated device network or ethernet interface
127.0.0.1 The emulated device loopback interface

O que nos interessa aqui endereço especial 10.0.2.2, eles nos permite se comunicar diretamente com o endereço 127.0.0.1 da maquina HOST (O famoso e famigerado localhost).

Desenvolvendo para ASPNET e acessando no emulador

Como bem sabemos, quando iniciamos um aplicativo web para AspNet Core, ele sempre rodará na nossa localhost (127.0.0.1). Agora tá fácil né, quando você quiser acessar localhost da sua maquina direto do emulador é só usar o 10.0.2.2.

Criei um simples projeto padrão de web api

![Exemplo de um aplicativo aspnet core rodando na maquina host com o endereço https://localhost:7270. Aqui temos apenas uma mensagem de boas vindas que diz 'Bem vindo'](
Image description

Agora vamos acessar o mesmo endereço do meu host no navegador chrome do Emulador Android, observe que eu usei o endereço https://10.0.2.2:7270 que corresponde ao meu https://localhost:7270 da minha maquina host.

Emulador com o chrome aberto no endereço https://10.0.2.2:7270, porém com erro de certificado, na tela tem um desenho de atenção com a mensagem escrita 'Your Connection is not private' com o botão 'Advanced' em baixo

Note que ao acessar esse endereço, você verá um erro de 'Your Connection is not private', isso acontece porque eu estou rodando na minha maquina host uma aplicação que usa https e o seu ceritificado não é compartilhado com o emulador. Então, para não adentrar muito nesse mundo do SSL e HTTPS, vamos somente ignorar essa parte clicando em Advanced e depois em Proceed to 10.0.2.2 (unsafe).

Navegador no endereço 10.0.2.2:7270, onde mostra a mensagem Proceed to 10.0.2.2 (unsafe) onde o usuário deve clicar

Após clicar em Proceed to 10.0.2.2 (unsafe), nossa imagem é finalmente exibida. Então voilá, você tem o seu emulador acessando o seu endereço de api direto da web api rodando no host.

Emulador acessando o endereço 10.0.2.2:7270 que exibe uma mensagem

Agora vamos para a próxima etapa

Executando os dois projetos simuntaneamente pelo visual studio

Essa etapa é bem simples, precisamos apenas configurar a solução para executar os dois projetos simuntaneamente. Tenha em mente que você precisa está rodando o seu aplicativo android no emulador. Primeiro vamos definir que quando rodar a solução, o projeto que será iniciado é o projeto MAUI

Vamos fazer essa pequena configuração.

  • Selecione o projeto do MAUI
  • Botão direito do Mouse em cima desse projeto
  • Então selecione a opção "Set as Startup Project"

bortão direito no projeto do MAUI e selecione a optão

Agora selecione o emulador que você irá executar o MAUI

  • Clique na setinha ao lado do botão de executar
  • Selecione Android Emulators
  • Selecione o seu emulador

Selecionando o emulador mostrando exatamente os textos acima

Agora vamos ajustar a solução para executar o Projeto de API e Projeto do MAUI para executarem simuntaneamente

  • Botão direito na solução
  • Selecione Properties
  • Selecione a opção Multiple startup projects
  • Marque os dois projetos com a action Start como na imagem abaixo
  • Clique no botão OK

Mostrando as propriedades da solution, marcando o checkbox

Ao fazer isso, já temos nossa configuração ideal para o nosso proximo passo. Observe que o botão de executar do visual studio mudou para somente Start

Adicionando a chamada do servidor no Android

aqui vamos adicionar alguns trexos de códigos bem simples no nosso aquivo MainPage.xaml e MainPage.xaml.cs

  • MainPage.xaml
<ContentPage ...>
    <ScrollView>
        <VerticalStackLayout ...>
...
<!-- Adicione esse botão ao final do layout, mas antes do </VerticalStackLayout></ScrollView></ContentPage>  -->
            <Button
                x:Name="ShowWelcomeButton"
                Text="Show welcome message"
                SemanticProperties.Hint="show exacly the message welcome from the ApI"
                Clicked="ShowWelcomeButton_Clicked"
                HorizontalOptions="Center" />

<!-- somente o botão acima -->
...
        </VerticalStackLayout>
    </ScrollView>
</ContentPage>
Enter fullscreen mode Exit fullscreen mode
  • MainPage.xaml.cs
/* Agora vamos adicionar essa implementação */
        private async void ShowWelcomeButton_Clicked(object sender, EventArgs e)
        {
            try
            {
// cria um httpclient que ja conecta com a nossa api 
// usando o endereço https://10.0.2.2:7270
                using var httpClient = new HttpClient()
                {
                    BaseAddress = new Uri("https://10.0.2.2:7270")
                };
// chama o endpoint inicial "/"
                var message = await httpClient.GetStringAsync("/");

                ShowWelcomeButton.Text = $"Message From Server: {message}.";
            }
            catch(Exception ex)
            {
               await DisplayAlert("error", ex.Message, "Ok");
            }
        }
Enter fullscreen mode Exit fullscreen mode

Seu App deve rodar no emulador como na imagem abaixo.
emulador android com os botão

Agora é só clicar no botão "Show welcome message" e... ERROR?!

Alerta mostrando

Esse erro ocorreu devido a um erro de certificado, lembra daquele erro do chrome que ele estava dando em relação ao certificado inválido, a página não era segura e precisaríamos "forçar" o acesso a ela. Então, aqui no app android acontece a mesma coisa. Então vamos mexer em algumas configurações do nosso aplicativo Android e API.

Resolvendo o java.security.cert.CertPathValidatorException

Como dito antes, esse erro de certificado ocorre devido ao acesso a um endereço https onde o certificado não é encontrado ou não é válido. Então nesse momento precisaremos configurar a API para não exigir o certificado quando estivemos trabalhando em desenvolvimento. Para isso precisaremos ajustar o arquivo program.cs da nossa API. Para isso basta verificar se o ambiente que estamos desenvolvendo é o desenvolvimento e então desativar o redirecionamento para o https.

  • program.cs (WebApiExample)

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseHttpsRedirection();
}

Enter fullscreen mode Exit fullscreen mode

Precisamos também mudar a maneira que nossa Api irá rodar, então selecione nossa API como projeto a ser incializado

  • botão direito na API (WebApiExample)
  • Selecione Set as Startup Project
  • Mude na seleção de start para o 'http'.
  • Pronto, agora nossa API estará rodando na http://localhost:5017/

Então na sua mente deve está passando "Ah, agora é so mudar o endereço para http e rodar o projeto!" (lembresse de reconfigurar para rodar os dois Apps juntos)

                using var httpClient = new HttpClient()
                {
                    BaseAddress = new Uri("http://10.0.2.2:5017")
                };
Enter fullscreen mode Exit fullscreen mode

e então... ERROR?! Cleartext HTTP traffic to 10.0.2.2 not permitted. Simplesmente o Android não permite acessar endereços HTTP por padrão.

Mostrando um alerta onde exibe a mensagem no emulador android

Não se desespere, temos a solução para isso logo a seguir

Resolvendo o Cleartext HTTP traffic to 10.0.2.2 not permitted

A gente precisa contornar esse erro atraves da classe MainApplication.cs, precisaremos adicionar a propriedadeDebuggableeUsesCleartextTraffic`. dessa maneira conseguiremos contornar a verificação https. Então acesse o arquivo "Platforms/Android/MainApplication.cs"

Exibindo as pastas da solução com o endereço

Adicione as propriedades Debuggable e UsesCleartextTraffic no atributo [Application] ele deverá ficar assim:

`

[Application(Debuggable = true, UsesCleartextTraffic = true)]
Enter fullscreen mode Exit fullscreen mode

`

e assim ficará o código da MainApplication.cs.

`
[Application(Debuggable = true, UsesCleartextTraffic = true)]
public class MainApplication : MauiApplication
{
public MainApplication(IntPtr handle, JniHandleOwnership ownership)
: base(handle, ownership)
{
}

    protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
   }
Enter fullscreen mode Exit fullscreen mode

`

Ao executar novamente... SEM ERROS!

Exibindo o emulador android com o botão funcionando mostrando a mensagem

Considerações finais e sugestões

Publicação em produção

Quando estiver executando o aplicativo em desenvolvimento, faz sentido você definir esse atributo [Application(Debuggable = true, UsesCleartextTraffic = true)] na classe MainApplication.cs. Porém, o ideal é seu app não ser publicado na loja com isso, e for, provavelmente vai ser rejeitado por essa falha de segurança que você deixou. Para evitar isso, a gente pode usar as variaveis de Build DEBUG onde você consegue definir o codigo que irá somente executado quando você estiver rodando pelo visual studio ou somente rodando na maquina de desenvolvimento.

`

#if DEBUG
  [Application(Debuggable = true, UsesCleartextTraffic = true)]
#else
  [Application]
#endif
  public class MainApplication : MauiApplication
{
    public MainApplication(IntPtr handle, JniHandleOwnership ownership)
        : base(handle, ownership)
    {
    }

    protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
   }
}
Enter fullscreen mode Exit fullscreen mode

`

E rodando para o windows?

O endereço de api que voce colocou na sua HttpClient so faz sentido para rodar no android. Porém, MAUI é multiplataforma. Felizmente MAUI também trás outras variaveis de build que identificam a plataforma que o App esta executando. Então usaremos a ANDROID para esse caso. Ou seja, sempre que estivemos executando no Android um trexo de código espefico irá executar

csharp
using var httpClient = new HttpClient()
{
#if ANDROID
BaseAddress = new Uri("http://10.0.2.2:5017")
#else
BaseAddress = new Uri("http://localhost:5017")
#endif
};

Obrigado!

Obrigado por ter chegado até aqui. Aqui está o código fonte dessas aplicação no Github. Commente aqui se você tiver dúvidas ou quiser compartilhar informações sobre o desenvolvimento no MAUI!

Top comments (0)