Em minha última postagem um dos comentários me chamou atenção para o comportamento do botão físico Voltar. Ele não está sendo considerado no tratamento que fizemos.

Com base nesse comentário, do leitor Tiago preparei a postagem de hoje apenas para tratar esse comportamento do botão de hardware e assim complementar a postagem anterior: DELPHI XE7 ANDROID E DIALOGS, O QUE MUDOU?

Qual é o problema?

Tiago notou que ao pressionar o botão Voltar disponibilizado pelo Android via hardware, a aplicação exibia a mensagem rapidamente e se fechava em seguida, independente da resposta do usuário… nem mesmo esperava que este respondesse à pergunta.

Veja no vídeo abaixo:

E como resolver a questão?

Bem vamos manter o evento  OnCloseQuery que fizemos na postagem anterior, e vamos recorrer ao evento OnKeyUp do formulário  que será codificado como abaixo:

procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; var KeyChar: Char;
  Shift: TShiftState);
var
  Fechar : Boolean;
begin
  if Key = vkHardwareBack then
      begin
        key := 0;
        FormCloseQuery(Sender, Fechar);
      end;
end;

Vamos conferir como ficou neste próximo vídeo:

É isso, simples assim! Até a próxima pessoal!

 

23 Replies to “Controlando o botão físico Voltar do Android com Delphi XE7”

  1. Ola Landerson, não tive tempo ainda de colocar na minha aplicação mais pelos videos e pelo que eu li funcionou perfeitamente parabéns e obrigado pela postagem completa. Estou com uma grande dificuldade e já conversei com outros desenvolvedores e eles não souberam me responder. Hoje o delphi xe7 não controla o teclado do Android ou IOS se colocamos um edit abaixo da linha aonde sobe o teclado quando entrar no edit o teclado sobe e ele ficará escondido atras do teclado. Tem alguma maneira de controlar pela aplicação o subir e o descer do teclado tanto em Android como para IOS? O Android estúdio faz isso automaticamente quando sobe o teclado ele sobe o layout para não cobrir as informações mais no delphi não encontrei, nos blogs de ajuda e de desenvolvederes e a maioria não sabia como fazer e queria ajuda pois estão com esse problema. Queria controlar o subir e o descer do teclado e se teria como o layout subir pra não cobrir essas informações, qualquer duvida passei meu email no campo acima. Obrigado pela postagem novamente sera de grande valia.

    1. Olá Tiago… na verdade o evento em si não tem muito a ver com o que você está dizendo:
      OnKeyUp ocorre quando a tecla é solta e o OnKeyDown quando a mesma é pressionada! Para o caso exposto por você o ideal é tratar no momento, se o teclado está ativo ou não, dê uma pesquisada em TVirtualKeyboardState, daí você passa a tratar o caso para quando o teclado estiver visível e para quando isso não ocorrer.

      Bons códigos aí!

  2. muito útil suas dicas, parabéns!
    Gostaria de fazer uma pergunta sobre outro assunto, mas pelo q percebi para me registrar preciso ter conta de face ou twitter, e nao tenho de nenhum, tem outra maneira de me registrar para poder fazer um pedido?
    abs,

    1. Olá Vinicius, seja bem vindo!
      Que bom que as postagens têm te ajudado! Bem com relação ao registro, basta usar seu e-mail não precisa ser pelo Face ou Twitter e ao registrar-se você passa a receber atualizações de conteúdo.
      Obrigado por sua participação!

      1. olá Landerson, estou um app demo que cria um serviço (código fonte), está funcionando legal, porém quero fazer o mesmo num app meu e nao estou conseguindo. Preciso gerar um serviço para que mantenha meu app, processo principal, sempre em execucao. Meu aplicativo apos um tempo, alumas horas, se fecha sozinho (nunca dura mais que 24h) e pelo que conseguir entender o SO que esta fazendo isso com ele e, até agora, a única solucao q me parece viável é gerar um servico. Você ja passou por algo semelhante? na maior parte do tempo meu aplicativo fica so verificando se chegou uma determinada hora para ai sim ele realizar suas tarefas, fico verificando isso dentro de um TTimer. Sevoce tem interesse no meu codigo demo, me envie um email me dizendo para onde devo mandar. Grande abraço.

          1. ai Landerson, claro q posso compartilhar este exemplo sim, mas este meu link – http://we.tl/Dc0xMxqb87 – dura somente por 7 dias, espero q de tempo de vc baixar e se possível colocar num link definitivo para q outros possam usufruir tbm. Abs.

  3. gostaria de saber , o pq toda app que gero no xe7 fica tudo escuro, e a demora, to apanhando muito com esse negocio, se for possivel gostaria uma aonde achar auxilio para operar ele da melhor forma possivel.

    1. Olá Adriano! Primeiramente seja bem vindo!!!
      Com relação a seu problema, precisamos apurar um pouco mais de informações:
      Seu Delphi XE7 é com updtate 1? Você está rodando a aplicação para que plataforma de destino (Android, Win, iOS)???
      Versão do dispositivo para qual o deploy está sendo feito?

      Não se preocupe, após tudo configurado esses problemas não te acompanharão!
      Fico no aguardo de seu feedback!

  4. Fala Landerson, blz?
    Cara estou com o meu app pronto e já publicado, na Play Store liberado em poucas hora, já na App Store estou esperando há alguns dias. Bom, depois disso me deparei com problema inesperado… Na fase de teste eu os realizava em alguns disposivos, um Xperia Z1, alguns modelos da LG e Samsung e também num Asus ZenFone 5, tudo correndo certo. Porém para a minha surpresa, quando baixo o app da Play Store para o ZenFone 5, na hora de rodar o app aparece a mensagem “app não surportado por este dispositivo”, para todos os outros esta funcionando legal. Então percebi que quando compilo em modo Debug funciona legal, mas no modo Application Store acontece esse problema. Você tem alguma informação sobre o assunto?
    Meu amigo não sei se esse é o melhor caminho de lhe fazer esse tipo de pergunta, se tiver uma meio melhor me avise por e-mail por favor.
    Grande abraço.

    1. Olá Vinícius… que boa notícia rapaz! Parabéns!!! Bem com relação ao ZenFone, é a questão do processador. Isso foi reportado no XE5 e desde então a Embarcadero trabalha com a Intel para resolver. Tente contato com o suporte da embarcadero atendimento@embarcadero.com.br ou 55 11 5643 1333 para informações mais apuradas.

      Espero que a dica ajude e que já haja solução!
      Peço que poste um feedback com seus passos no processos.

      Grande abraço!

      1. ae grande MVP Embarcadero, mais uma vez parabéns…

        como vejo seus post “mais” voltados para android, (posso estar errado) tenho um desafio pra vc no iOS – hahahaha brincadeira, estou precisando de um help mesmo.

        Cara já tentei 5 vezes q a Apple aprove o meu app, porem nada, preciso resolver o seguinte erro que é lancado no início do programa:
        SpringBoard[364] : CGContextSaveGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.

        esse erro é observado no log do Xcode

        este erro surge 6x em sequencia, já encontrei algumas soluções relacionadas com StatusBar, porém não serviram para mim, até pq não uso nenhuma barra de status.

        O mais estranho é o seguinte, iniciei um app do zero, nao coloqei nada nele simplesmente salvei e fiz um deploy, repito, nao coloqei nada no app, nenhum componente, nenhuma linha de código, adivinha… o mesmo erro é lançado, as mesmas 6x em sequencia.

        Cara, outra coisa chata nisso tudo é q o app funciona normalmente, esses erros lançados somente no inicio da execução, nao atrapalham em nada meu aplicativo.

        Se você já está de saco cheio dos meus problemas me ajude a contatar outra pessoa como o Victory Fernandes, nao encontrei um canal de acesso dele como esse seu para, para q eu possa sugá-lo tbm e te poupar um pouco.

        mais uma vez vlw ai pelas dicas e ajudas de sempre.
        abs,

          1. ae Landerson, vou procurar contato com o Adriano. Acredito q vc tenha pessoas bem qalificadas para te ajudar, mas se eu puder retribuir as suas ajudas, vc tem meu email. Muito obrigado pela atenção e até a minha próxima necessidade – rsssss.

          2. ae Landerson,
            O problema era com a Apple mesmo, eu tinha praticamente certeza disso, depois de 30 dias de relato de bug meu e de outros desenvolvedores, a Apple reconheceu o problema e solucionou, na real pelo que percebi não solucionaram, passaram a aceitar este erro na revisão. Eu relatei que outros app que eu já tinha instalado antes do iOS 9.0 como Facebook, WahtsApp, Waze, Team Viewer…, lançavam o mesmo erro ao serem iniciados. Infelizmente perdi 30 dias de publicação do meu app e passei esse tempo todo tentando achar uma solução. Mas menos mal que agora está tudo resolvido.
            Abs,

          3. Grande Vinícius!!! Sócio proprietário aqui já não é mesmo meu camarada!!! (risos)
            Amigão que bom que resolveu aí, vou tentar passar suas informações sim!

            Obrigado por compartilhar o seu sucesso aqui com os demais leitores e por engrandecer o nosso ambiente com suas participações sempre valiosas!

            Até a próxima!

  5. Landerson, tudo bem?
    Queria parabenizá-lo pelas dicas, que são sempre muito uteis e de grande valia em nossas aplicações..
    Mas queria tirar uma dúvida, aproveitando o assunto, eu queria saber se você tem algum exemplo para fazer a mesma coisa do exemplo no IOS… pois como explicou antes.. este exemplo é somente para Android…

    Desde já agradeço…

    1. Olá Felipe, pelo q eu estudei isso não é possível no iOS, a Apple não permite. Nos meus app instalados nenhum faz isso. Mas se vc conseguir não deixe de compartilhar aqui. Aproveitando, vc já enviou seu app para App Store? foi aprovado? abs.

    2. Olá Felipe,
      eu estava relendo alguns post agora e reli este seu, q na época que vc perguntou respondi que nao era possivel. Pois bem, a Apple não permite isso na teoria, mas na pratica sim, depois de ter um aplicativo meu aprovado pela App Store, resolvi arriscar uma nova versão com uma funcao “Fechar” e essa versao foi aprovada, de lá pra cá tenho colocado em todos os meus app que acho isso importante.
      A minha tentativa foi colocar um um “Application.Free” no meu código, esta funcao gera um erro , uma mensagem de erro para o usuario, mas o app se fecha, entao coloquei-a dentro de um try e deu certo, segue um procedimento simples como exemplo:

      procedure TForm1.FechariOS;
      begin
      try
      Applicaction.Free;
      except
      end;
      end;

      Espero que ainda esteja em tempo de te ajudar.

      abraços.

  6. Olá.
    Gostaria de aproveitar o assunto teclado do android e te pedir uma ajuda .
    Ex.tenho um formulário de cadastros.
    quando clico em um campo de texto o teclado aparece e fica por cima do campo …
    Gostaria de saber, como fazer, para que quando o teclado aparecesse, o campo texto continuasse visível acima do teclado

    1. Olá Leandro,

      provavelmente o Landerson deve ter uma solução melhor, mas vou colocar aqui como eu faço isso.

      Eu utilizo o componente VertScrollBox (aAlign = Client) para rolar a tela com todos os meus componentes do form dentro dele (óbvio né – rsssssss).

      Dica: eu coloco um componente posicionado no minimo meia tela abaixo do último componente visível que desejo interagir, para isso utilizo um Timage, que fica vazio e não atrapalha em nada, mas poderia ser um TLabel sem texto tbm ou coisa parecida, assim garanto q vou poder rolar a tela até ele.
      tipo
      Image1.Position.Y:=round(Ultimocomponente.Position.Y + (ClientHeight * 0.5));

      Crio a seguinte procedure que é shamado quando o teclado é aberto na tela
      procedure RollKeyBoard(VSBx:TVertScrollBox);

      procedure TForm1.RollKeyBoard(VSBx: TVertScrollBox);
      begin
      if VSBx.Tag > 0 then
      VSBx.ViewportPosition:=pointf(0,VSBx.Tag);
      end;

      coloco todos os eventos CanFocus do Edits do form com este evento, assim cada um pode passar a sua posição Y para o VertScrollBox poder rolar até ele.

      procedure TForm1.Edit1CanFocus(Sender: TObject; var ACanFocus: Boolean);
      begin
      // assim como está o VertScrollBox vai rolar e colocar o seu TEdit no topo da tela, você deve personalizar esta conta que estou fazendo para posicionar onde achar melhor.
      VertScrollBox1.Tag:=round((sender as TEdit).Position.Y) + round((sender as TEdit).Height);
      end;

      No evendo FormVirtualKeyBoard chamo a procedure RollKeyBoard, assim toda vez que o teclado for aberto este procedimento é executa.

      procedure TForm1.FormVirtualKeyboardShown(Sender: TObject;
      KeyboardVisible: Boolean; const Bounds: TRect);
      begin
      RollKeyBoard(VestScrollBox1);
      end;

      Você pode e deve fazer suas adaptações.

      Atenção, tenho certeza que o Landerson deve ter uma solução melhor.

      Att.
      Vinicius

Deixe um comentário