Dynamics do Zero ao PRO · Lição 30 de 48 · Módulo 4

LIÇÃO 30App de Campo para Técnicos em Mobilidade

O técnico chega no cliente, abre o celular, vê o caso, tira foto do defeito, capta a localização GPS, assina digitalmente o laudo e sincroniza com o Dynamics — tudo sem abrir o laptop. Esta lição reúne os recursos nativos de mobile do Power Apps para um app de campo completo.

🎯

Resultado desta lição

Ao final, você terá um app mobile com câmera para fotos do defeito, captura de GPS, assinatura digital e salvamento de todos os dados no Dataverse como anotações vinculadas ao caso — funcionando no iOS e Android.

4 funcionalidades nativas de mobile

📷

Camera — fotos do defeito

Captura imagem direto da câmera do celular. Salva como anexo no caso do Dynamics.

📍

Location — GPS automático

Captura latitude/longitude no momento do atendimento. Registra local do serviço no caso.

✍️

Pen Input — assinatura digital

Campo de assinatura touch. Salva como imagem PNG no Dataverse vinculada ao caso.

📶

Offline — sem internet

Salva em coleção local quando sem sinal. Sincroniza quando a conexão volta.


Passo a passo

  1. Configure a câmera para capturar fotos

    → Insert → Media → Camera
    → Renomeie para: camFoto

    Adicione um botão para capturar:

    OnSelect do botão "Fotografar":
    Collect(colFotos, {foto: camFoto.Photo, timestamp: Now()})

    Adicione uma gallery abaixo para mostrar as fotos tiradas:

    Gallery Items: colFotos
    Image dentro da gallery: ThisItem.foto
    camFoto.Photo: A propriedade Photo do componente Camera retorna a última foto tirada como uma imagem base64. Cada clique no botão Fotografar adiciona à coleção — o técnico pode tirar múltiplas fotos do defeito.
  2. Capture a localização GPS

    → Insert → Icons → Location (ou um Button)
    OnSelect do botão "Capturar Localização":
    Set(varLocalizacao, {lat: Location.Latitude, lon: Location.Longitude, precisao: Location.Altitude})

    Exiba as coordenadas na tela:

    Label coordenadas:
    "📍 " & Text(varLocalizacao.lat, "0.000000") & ", " & Text(varLocalizacao.lon, "0.000000")
    Permissão de localização: Na primeira vez que o app pede a localização, o celular exibe um popup de permissão. Se o usuário negar, Location.Latitude retorna 0. Verifique com If(Location.Latitude = 0, "Sem localização", ...)) para dar feedback adequado.
  3. Adicione o campo de assinatura digital

    → Insert → Input → Pen input
    → Renomeie para: penAssinatura
    → Mode: Draw
    Label acima do campo: "Assinatura do cliente — confirmo a conclusão do serviço"

    Botão "Limpar assinatura":
    OnSelect: Reset(penAssinatura)
    penAssinatura.Image: A propriedade Image do Pen Input retorna a assinatura como imagem PNG — igual ao Camera.Photo. Salve com Patch() como anotação no caso do Dynamics.
  4. Salve tudo no Dataverse ao finalizar

    OnSelect do botão "Finalizar Atendimento":
    // 1. Atualizar o caso com localização e resolução Patch( Cases, LookUp(Cases, caseid = SelectedCase.caseid), { description: txtLaudo.Text & " | GPS: " & Text(varLocalizacao.lat) & "," & Text(varLocalizacao.lon), statecode: 1, statuscode: 5 } ); // 2. Salvar assinatura como nota Patch( Annotations, Defaults(Annotations), { subject: "Assinatura do cliente — " & Text(Now()), documentbody: penAssinatura.Image, mimetype: "image/png", objectid_incident: {caseid: SelectedCase.caseid} } ); // 3. Salvar cada foto como nota ForAll( colFotos, Patch( Annotations, Defaults(Annotations), { subject: "Foto do defeito — " & Text(timestamp), documentbody: foto, mimetype: "image/jpeg", objectid_incident: {caseid: SelectedCase.caseid} } ) ); Notify("Atendimento finalizado e sincronizado!", NotificationType.Success); Navigate(ListaScreen, ScreenTransition.UnCover)
  5. Implemente modo offline com detecção de conectividade

    Verificar conexão: Connection.Connected — Boolean, true se tem internet

    Botão "Finalizar" com lógica offline:
    If( Connection.Connected, // Online: salva direto no Dataverse Patch(Cases, LookUp(Cases, caseid = SelectedCase.caseid), {...}), // Offline: salva em coleção local para sincronizar depois Collect(colPendentesSync, {caso: SelectedCase, laudo: txtLaudo.Text, fotos: colFotos, assinatura: penAssinatura.Image, timestamp: Now()}); Notify("Sem conexão — atendimento salvo localmente para sincronização", NotificationType.Warning) )
    Botão "Sincronizar" (aparece quando volta a conexão):
    Visible: Connection.Connected && CountRows(colPendentesSync) > 0

    OnSelect do Sincronizar:
    ForAll(colPendentesSync, Patch(Cases, ...)); Clear(colPendentesSync); Notify(Text(CountRows(colPendentesSync)) & " atendimentos sincronizados!")
    Connection.Connected: É uma propriedade global que muda em tempo real quando a conectividade muda. Você pode usá-la em fórmulas de Visible, Color ou OnSelect para adaptar o app ao estado de conexão atual sem precisar verificar manualmente.

Checklist

Publicar como app nativo — Microsoft Intune e MDM

Para distribuir o app para todos os técnicos sem precisar que cada um acesse o link e instale manualmente, use o Microsoft Intune (gerenciamento de dispositivos móveis). O Power Apps tem integração nativa com Intune: você publica o app para grupos de usuários e ele aparece automaticamente no portal do Intune em cada celular gerenciado pela empresa.

Fluxo de distribuição enterprise:
1. Publique o app no Power Apps
2. Compartilhe com o grupo "Técnicos de Campo" no Microsoft 365
3. Configure no Intune a distribuição automática do app Power Apps
4. Os técnicos abrem o celular corporativo e o app já está instalado

Este é o padrão para implementações enterprise — sem distribu­ição manual por link, sem dependência do técnico saber instalar o app.

🏆

Módulo 4 concluído — Power Apps com Dynamics

Você passou por Canvas App, Patch(), Edit Form, variáveis e coleções, componentes reutilizáveis e um app de campo completo com câmera, GPS, assinatura e offline. O Módulo 5 começa na Lição 33 com Power BI conectado ao Dynamics.

Foto de Pablo Maruk
Pablo Maruk
Analista Funcional de Dynamics · 16 anos de TI · EUA & Europa