Como conectar o Aplicativo MAUI no Emulador Android e WEB Api na mesma máquina
Marcos Costa
Posted on October 14, 2023
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'](
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.
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)
.
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.
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"
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
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
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>
- 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");
}
}
Seu App deve rodar no emulador como na imagem abaixo.
Agora é só clicar no botão "Show welcome message" e... ERROR?!
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();
}
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")
};
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.
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 propriedade
Debuggablee
UsesCleartextTraffic`. dessa maneira conseguiremos contornar a verificação https. Então acesse o arquivo "Platforms/Android/MainApplication.cs"
Adicione as propriedades Debuggable
e UsesCleartextTraffic
no atributo [Application]
ele deverá ficar assim:
`
[Application(Debuggable = true, UsesCleartextTraffic = true)]
`
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();
}
`
Ao executar novamente... SEM ERROS!
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();
}
}
`
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!
Posted on October 14, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
October 14, 2023