Tanto em desktop quanto mobile, no desenvolvimento por diversas vezes temos a necessidade de nossa aplicação interagir com outras aplicações da plataforma alvo de nosso desenvolvimento.
Aquele relatório que precisa ser exportado e visualizado em Excel na plataforma Desktop é um exemplo que quase todo desenvolvedor já teve implementar.
Intent, aqui bate o coração
Quando falamos de mobile, em Android sendo mais específico, poder interagir com os recursos do sistema por si só, já pode dar ao usuário de nossa aplicação um ganho significativo de experiência de uso. Já citamos aqui alguns casos de como fazer nossa aplicação interagir com o Android, porém na postagem de hoje traremos a tona a classe que é tida como o coração do sistema Android: a Classe Intent.
A classe Intent (android.content.Intent) está presente em todos os lugares e representa uma mensagem da aplicação para o sistema operacional solicitando a este que realize algo. Através dela é possível integrar diferentes aplicações trocando essas mensagens e resultados entre si. O sistema operacional por sua vez interpreta essas mensagens efetuando o que está sendo solicitado, desde a abertura de uma aplicação até mesmo efetuar uma chamada telefônica.
Delphi: criando a interface da aplicação.
Inicie um novo projeto Mobile em branco, nele vamos inserir 1 Label, 1 ComboBox, 1 Button. Vamos alterar as propriedades dos componentes como abaixo:
- Label1
- Text –> Intent’s no Delphi
- TextAling = taCenter
- ComboBox1
- Itens
- Mapa
- Telefone
- Navegador
- Contatos
- Itens
- Button1
- Text –> Executar
Em nosso projeto iremos utilizar alguns namespaces para utilizarmos funções do Android, para isso na clausula Uses da seção implementation vamos incluir:
uses IdURI, FMX.Helpers.Android, Androidapi.Jni.GraphicsContentViewText, Androidapi.Jni.Net, Androidapi.Jni.JavaTypes;
Ao final desta etapa teremos nossa aplicação visualmente parecendo-se com a imagem abaixo:
E como usar as Intents na prática? E no Delphi como seria isso?
Nossa aplicação enviará chamadas ao sistema operacional invocando os aplicativos do Google através de pares Ação / URI que definem qual aplicativo está sendo chamado e seu comportamento ao receber a intenção de chamada. A lista completa de Intents para invocar aplicativos do Google em dispositivos Android pode ser checada no link:
http://developer.android.com/guide/appendix/g-app-intents.html.
Então vamos fazer as coisas acontecerem por aqui!
No evento OnClick do nosso Button1 vamos inserir umas variáveis:
var uri : string; Intent : JIntent; idContato : Integer;
Basicamente ao clicar no botão o usuário estará solicitando ao dispositivo que execute uma intent pré-selecionada no ComboBox1. Sendo assim o iremos verificar qual a intent chamada e passar os comandos para a aplicação do Google que desejamos executar. Veja o código (que deve vir imediatamente após a declaração das variáeis acima):
begin
case ComboBox1.ItemIndex of
-1:
begin
ShowMessage('Selecione uma Intent');
ComboBox1.SetFocus;
end;
0: //Mapa
begin
uri :='geo://0,0?q=Maracana, Rio de Janeiro';
try
Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_VIEW, TJnet_Uri.JavaClass.parse(StringToJString(TIdURI.URLEncode(uri))));
SharedActivity.startActivity(Intent);
except on E: Exception do
ShowMessage(E.Message);
end;
end;
1: // Telefone
begin
uri :='tel://98390170';
try
Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_CALL, TJnet_Uri.JavaClass.parse(StringToJString(TIdURI.URLEncode(uri))));
SharedActivity.startActivity(Intent);
except on E: Exception do
ShowMessage(E.Message);
end;
end;
2:
begin
uri:= 'content://com.android.contacts/contacts/';
try
Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_PICK, TJnet_Uri.JavaClass.parse(StringToJString(TIdURI.URLEncode(uri)))); SharedActivity.startActivityForResult(Intent, 0);
except on E: Exception do
ShowMessage(E.Message);
end;
end;
3: // Navegador
begin
uri :='https://landersongomes.com.br';
try
Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_VIEW, TJnet_Uri.JavaClass.parse(StringToJString(TIdURI.URLEncode(uri))));
SharedActivity.startActivity(Intent);
except on E: Exception do
ShowMessage(E.Message);
end;
end;
end; // case
end;
Agora basta executar o programa no dispositivo ou no emulador que já temos nossa aplicação interagindo com as aplicações do Google que acompanham os dispositivos Android.
Explicando os pares: Ação / Uri
Os aplicativos do têm sua chamada e comportamentos estabelecidos através dos pares Ação/ Uri. Abaixo vamos descrever cada um dos pares utilizados por nós em cada Intent de nossa aplicação:
A Intent Action (Ação) View combinada com a Intent URI (Uri) Geo abre o Google Maps do dispositivo passando a ele as coordenadas ou endereço contidos no restante da URI. Este par foi utilizado então por nossa aplicação quando clicamos no Button1 e o ComboBox teve a opção Mapa selecionada.
Fica bem claro quando separamos o código que inicializa nossa variável Intent, veja:
Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_VIEW,
TJnet_Uri.JavaClass.parse(StringToJString(TIdURI.URLEncode(uri))));
Os demais casos, acabam tornando-se óbvios, temos:
ACTION_CALL combinada com a URI Tel acrescida de um número de telefone, com isso nossa aplicação efetuará a chamada telefônica para o número informado.
Enfim, tudo fica bem mais claro após o entendimento do primeiro caso.
Dê à sua aplicação a “intenção” de interagir com o Android.
Agora, vale a pena dar uma olhada na Lista de Intents para invocar aplicativos do Google e adaptar sua aplicação para essas possíveis interações com o Android.
Até a próxima.


Landerson excelente artigo, estou aprendendo muito com seus artigos sobre android + delphi xe5, estou desenvolvendo um aplicativo que fica executando algumas tarefas em background e gostaria que ele fornecesse informações para outros aplicativos, isso é, estou querendo criar uma intent na minha aplicação, já procurei algum artigo sobre criação de intents e não encontrei, você poderia me dar uma luz sobre o assunto.
Olá João Daniel… acredito que a questão das Intents a melhor maneira para buscar informações seja utilizando o material de referência do Android.
Segue aqui o link: .
Vale lembrar que o propósito das Intents é exatamente passar informação para outra aplicação.
Dê uma olhada nessa parte do link: String EXTRA_TEXT A constant CharSequence that is associated with the Intent, used with ACTION_SEND to supply the literal data to be sent.
Parece que é por aí.
Abraço
Obrigado Landerson Gomes, vou pesquisar mais ja achei em java, mas nada em delphi xe5
João como fazer isso?
A o app ficar rodando em background, estou atas disto
João me ajuda aí, conseguiu criar app rodando em background? Como fez isso?
Olá, muito legal seu blog, serio! E achei expetacular este intent, nunca havia ouvido falar, agora minha duvida é a seguinte, entrei no link onde lista todos os intents do Android, e gostaria de usar um em particular, que seria o de configurar a Localização do GPS(ligar/desligar).
“android.settings.LOCALE_SETTINGS” Seria isso, mas não consegui entender como implementar no Delphi, se puder me ajudar, agradeço.
Att, Yuri.
Yuri… realmente seria o caso de pesquisar a implementação. Seguindo a linha de meu raciocínio, você chegou a notar que em outras postagens utilizei o Location Sensor do Delphi? Ele trata exatamente o sensor de GPS dos aparelhos Android. Enfim, pode ser mais prático fazer a utilização deste componente.
Pode ver na postagem https://landersongomes.com.br/delphi/sensor-de-localizacao-de-dispositivos-moveis-com-delphi-xe5 que é bem simples.
No exemplo desta postagem sobre intent a linha que realmente cria a nossa intent está aqui:
Você já tentou substituir ACTION_VIEW pelo LOCATE_SETTINGS ???
Abraço.
Gostaria de saber se alguem já implementou envio de email android com delphi xe5
Alexandre… já li a respeito, vou tentar produzir algo a respeito e publicar.
Mais uma vez obrigado pela participação!
Envio de Email:
CreateEmail(‘ &EmailDestinatario ‘, ‘ &AssuntoEmail ‘, ‘&ConteudoMensagem ‘);
Bem básico, lembrando que o mesmo aceita STRING, e para quebra de linha é o comando sLineBreak.
Até
Olá Felipe… bem vindo ao Blog.
Você cita a função CreateMail, entretanto apenas a chamada.
Tente enviar a declaração da função como um todo por favor… acredito que vá ajudar a galera.
Estou com uma postagem iniciada sobre o envio de e-mail direto pela SDK do Android, em breve estarei publicando. Se você já tiver a declaração da sua função aí fique a vontade para compartilhá-la, afinal a galera tem sempre urgência.
Mais uma vez obrigado por sua participação e principalmente pela contribuição.
Abraço.
Bom dia caro Landerson.
Estou iniciando desenvolvimento para android e estou com um problema muito grave.
Estou compilando num tablet de 7 polegadas da samsung, o smasung lite 3.
O meu problema, é que quando eu compilo, a tela do meu tablet fica inteira branca, os componentes não aparecem.
Eu fiz um teste colocando um botão no canto superior da tela com um showmessage e aparece a mensagem, mas o componente continua não aparecendo. Você teria alguma idéia do que poderia ser?
Obrigado desde já
Olá Vitor… se você não estiver usando uma versão superior ao XE5 Upd1, existe uma incompatibilidade reportada com esse aparelho.
Se sua versão for superior, teste a aplicação em outro dispositivo apenas por comprovação mesmo.
Poste aqui se funcionar em outro dispositivo.
Obrigado aí pela participação e espero poder ajudá-lo.
Boa noite, Landerson, ví seu post sobre a leitura de código de barras.
Percebi que tem de instalar um software de terceiro..,gostaria de saber se vc tem algo direto.., , preciso fazer a aplicação do zero com todos os fontes nativos..
É possivel?, gostaria de falar mais detalhes com vc.
Aguardo retorno por favor.
Obrigado e sucesso.
Loester
Olá Rodrigo… acredito que tenha como sim. Procure por “zbar delphi android” talvez já tenham evoluído um pouco mais. É que quando fiz uso do conteúdo da postagem em uma aplicação era tudo muito novo em tratando-se de Delphi X Android e a minha urgência pegou! rs
Enfim, busque aí, caso tenha sucesso compartilhe conosco.
Um grande abraço, boa sorte e acima de tudo obrigado pela participação.
Bom dia Landerson,
Ótimo artigo!
Estou tentando rodar uma aplicação simples (um label e um botão) em um Galaxy SIII Mini, porém a tela fica toda branca e não aparece nenhum componente que criei na tela, saberia me informar alguma possível explicação para isso?
Olá Alexandre! Obrigado por sua participação aqui no blog.
Bem meu caro, em primeiro lugar é necessário saber qual versão do Delphi você está utilizando. E a partir daí fazer uma série de verificações, a primeira delas é a compatibilidade da versão com o aparelho em questão, em caso de compatibilidade parta para as verificações no aparelho como GPU, etc…
Verifique e poste aqui caso não consiga.
Abraço.
Parabéns pelas excelentes dicas!!! Estou tentando rodar o exemplo no XE6, porém aparece a seguinte mensagem de erro :
[DCC Error] unit1.pas(45): E2003 Undeclared identifier: ‘StringToJString’
Que é a linha : Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_VIEW, TJnet_Uri.JavaClass.parse(StringToJString(TIdURI.URLEncode(uri))));
Será que falta algo no uses ?
Olá Antonio! Seja bem vindo.
O tutorial tem como base o Delphi XE5, não tenho nenhum feito no XE6 e sinceramente não sei se seria alguma incompatibilidade.
A função acusada pelo compilador na sua mensagem é declarada no seguinte Namespace: Androidapi.Jni.JavaTypes.
Inclua aí e rode! Não se esqueça de postar o resultado aqui!
Um abraço e obrigado por sua participação!
Landerson, a Androidapi.Jni.JavaTypes já estava adicionada. Para funcionar, é necessário adicionar também a Androidapi.Helpers. Agora está funcionando perfeitamente. Obrigado.
Otimo artigo!
Estou usando o XE6 e neste exato momento estou tentando fazer o seguite: tenho que me comunicar com um dipositivo ligado via bluetooth, e estou fazendo isto via B4A (um VB que gera java) no android e funciona maravilha. To pensando em deixar ele rodando como um servico.
Para enviar dados para ele poderia usar o que voce disse aqui, um intent. Porem eu preciso enviar alguns retornos de status para minha aplicacao Delphi.
Como é possivel fazer isto?
Olá Eduardo, primeiramente obrigado pelo elogio e acima de tudo pela participação!
Existem Activity’s que captam o resultado da Intent, a startActivityForResult usada na postagem LEITURA DE CÓDIGO DE BARRAS EM ANDROID COM DELPHI XE5 pode servir de norte para você na busca da solução.
Espero que ajude, e não se esqueça de postar aqui um feedback!
Abraço!
Olá Landerson,
Bom dia, cara, estou quebrando a cachola aqui, em listar os contatos do celular em um listview, vc fez pelo intent foi abrir a lista de contatos, até ae ..blz., eu entendi.., mas o que eu queria fazer era justamente eu pegar todos os nomes e detalhes de cada contato para minha aplicação, e assim, eu poder fazer o que bem quizer com eles. Consegue me dar uma mão nessa parada?
No mais, obrigado e sucesso..,
Loester Silva
Rodrigo bom dia!
Primeira coisa será um loop repetindo n vezes o procedimento de leitura do contato.
Um pouco de leitura desse tópico http://developer.android.com/reference/android/provider/ContactsContract.html e seus relacionados, principalmente ContactsContract.ContactsColumns deve auxiliá-lo na resolução do caso.
Não se esqueça de postar seu feedback, espero que de sucesso, aqui depois!
Abraço!
Mas isso funciona em delphi xe6 também?, tem algum exemplo para ajudar um entusiasta em delphi?
no mais, obrigado e sucesso.
att
Loester Silva
Loester… acredito eu que funcione no XE6 sim, uma vez que na verdade você apenas está utilizando código Delphi para interagir diretamente no Android.
Existem comentários de pessoas que estão utilizando o XE6 e fora uma ou outra função que tenha mudado de Namespace (Unit) ninguém reportou mais nada.
Tente executar o código e veja no que resulta. Não se esqueça de postar aqui um feedback!
Abraço e boa sorte!
OK, obrigado
Amigo, como faço para abrir o WhatsApp em meu app? Quero na minha aplicação chamar o WhatsApp como faço com o Shellexecute no VLC
Olá Pedro… bem vindo!
Acredito que fazendo um chamada explicita de intent você consiga resolver o caso.
O pacote do WhatsApp é com.whatsapp.
Assim sendo a chamada seria algo semelhante a linha abaixo.
intent.setAction(stringtojstring('com.whatsapp'));Vale lembrar que o ideal é dar uma pesquisada se o Whtas possui algo a mais para essa interação, com ele.
Veja se dá certo aí, e não esqueça de nos dar um feedback em caso de sucesso!
Boa sorte!
Sera que é possivel eu manda uma message direta sem abri o whatapp pelo delphi… Obrigado desde já
Teria como no exemplo de intents acima, na opção mapa eu enviar via sms a latitude e longitude do celular para outro celular através do número ou imei?
Olá José seja bem vindo ao Blog!
Sua resposta é sim! Basta você pegar as coordenadas e enviar… você pode fazer a leitura de mais 2 artigos aqui do blog e juntando-os terá a solução para a sua questão:SENSOR DE LOCALIZAÇÃO DE DISPOSITIVOS MÓVEIS COM DELPHI XE5 e DELPHI XE5 ENVIANDO SMS DIRETO DE SUA APLICAÇÃO ANDROID.
Na verdade meu caro José a sua pergunta acerta a essência do blog, ele é dividido em pequenas “soluções” para problemas cotidianos e que quando juntas podem chegar a quem sabe um aplicativo de grande utilidade!
Com base na sua leitura aguardo seu feedback com, espero eu, sucesso para seu caso!
Sem perder a piada, te pergunto: “E agora José???”
Agora, eu gostaria de agradecer sua participação desejar-lhe sucesso aí no seu projeto.
Um cordial abraço.
Laderson, ótimo post !
É possível abrir a calculadora também ? Não achei ela na lista Common Intents. Se sim, há como capturar o valor do visor?
Abraço amigo !
Olá Alexandre, bom tê-lo de volta! Possível é… precisamos descobrir qual é Intent da “criança”… vamos fechar o seguinte: Quem achar primeiro avisa aqui pode ser?
Vou procurar a partir de agora, encontrando post e te sinalizo.
Abração!
Olá Alexandre… já achei: com.android.calculator2.Calculator.
Tente aí depois poste se deu tudo certo por favor!
Amigo, de volta não. Estou sempre acompanhado seu muito útil blog. Parabéns !
Sobre a infeliz calculadora, se eu desenvolver uma acho que é mais em conta, rs.
begin
comando :=’com.android.calculator2.Calculator’;
try
Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_MAIN,
TJnet_Uri.JavaClass.parse(StringToJString(TIdURI.URLEncode(comando))));
SharedActivity.startActivity(Intent);
except
on E: Exception do begin
ShowMessage(E.Message);
end;
end;
end;
Retorno: Protocol Field is empty.
Onde estou errado, se possível me ajudar. Grande abraço.
Tentei seguir esse exemplo, mas não vai também.
http://www.intertech.com/Blog/android-intents-for-app-integration-call-a-calculator-play-video-open-an-editor/
Amigo vc conseguiu achar alguma coisa que funcione para chamar a calculadora?
Putz… Ainda não consegui evoluir nem uma linha…
Tô com essa aqui nas dívidas… como é ano eleitoral, posso até prometer olhar hein?!
Abraço meu caro e até a próxima, saindo eu posto!
As informações sobre o desenvolvimento android aqui publicadas me deu base para iniciar meu aprendizado.
Olá,
Parabéns pelo seu trabalho, já me ajudou muito.
Você sabe se tem como fazer algum Listener para o Adnroid no delphi ?
Eu precisava disparar um processo, sempre que receber uma ligação.
Olá Claudemir ainda não pesquisei sobre o tema, realmente não saberei te responder. Entretanto vou incluí-lo em minhas pautas de pesquisa, achando algo eu posto. Se você achar primeiro sinalize!
Obrigado por sua participação e seja bem vindo ao blog, lamento não ter a resposta para auxiliá-lo mais.
Cordialmente.
Mais uma vez parabéns pelo seu trabalho e pelo tempo q vc dedica com o mesmo. Ja q vi varias duvidas aqi neste post q fogem um tanto do assunto, ai vai a minha: Preciso deixar meu app sempre rodando, como muitos, como whatsapp, ate mesmo como o Viber, que mesmo depois de mandar sair dele ele continua recebendo novas mensagens. E tbm como fazer meu app iniciar apos o boot do aparelho, ja le bastante a respeito mas infelizmente nao cosegui por em pratica ainda.
abs,
Opa… você voltou e conseguiu registrar-se presumo eu!
Tenho pesquisado sobre o tema… na verdade o que você procura é uma forma de fazer sua aplicação rodar em background no Android.
Ainda não consegui implementar isso, minhas buscas por esse conhecimento persistem e conseguindo disponibilizarei aqui, entretanto por enquanto ainda não obtive sucesso!
Mais uma vez, obrigado por sua participação e pelas palavras de apreço ao trabalho!
Valeu mesmo, pena não conseguir te ajudar efetivamente nesse caso!
Até a próxima!
Blz Landerson,
se por acaso eu conseguir antes de vc, disponiblizarei aqui para vc testar e avaliar.
Grande abraço
Oi Landerson,
tive um progresso que por hora me ajuda a manter meu app em background.
Juntei suas dicas de sair da app após responder uma “MessageBoxSys” no CloseQuery com o suporte do FormKeyUp do form .
Então fiz assim, mesmo o usuário clicando no botão voltar do dispositivo consegui manter minha app rodando em background, como se o usuário tivesse clicado no botão Home do dispositivo.
segue o código:
procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; var KeyChar: Char;
Shift: TShiftState);
begin
if Key = vkHardwareBack then
begin
key := 0;
BotaoHome;
end;
end;
procedure TForm1.BotaoHome;
var
startMain: JIntent;
begin
startMain:=TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_MAIN);
startMain.addCategory(TJIntent.JavaClass.CATEGORY_HOME);
startMain.setFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK);
SharedActivity.startActivity(startMain);
end;
declarando a “uses”
Androidapi.JNI.GraphicsContentViewText;
teste e avalie por favor
abs,
Olá, eu instalei o Delphi XE8 e tentei rodar um exemplo de Acelerometro e fala a falta de uma unit a “FMX.Sensors”, procurei essa unit ja na pasta de codigos do Delphi e nao tem nada.. Onde posso encontrar essa unit? Obrigado.
Prezado Landerson,
Estou usando Delphi XE 8, porem o compilador nao entende as Units. Ela mudaram no Delhi XE 8?
Olá Alexandre, você pode ter aí algum problema de instalação, já que a Androidapi.Helpers é componente da instalação inicial.
Não tive até então nenhuma ocorrência de algo parecido com o descrito por você.
Caso necessite de ajuda podemos tentar olhar juntos…
Poste quando puder um feedback.
vc ja fez algum chmando o comando imprimir pra usar ? o google print?
Olá Marcos… infelizmente ainda não utilizei nada nesse sentido.
Tente verificar como seria no Android, e converter para ambiente Delphi.
Obrigado por sua participação e até a próxima!
Boa Noite Landerson.
Eu estava precisando abrir os contatos, conforme você mostrou em seu post e selecionar um contato para importar o numero e o nome do contato para a minha aplicação.
Consegui uma função que le todos os contatos, mas não consigo fazer ela escolher apenas um contato especifico.
se conseguir me ajudar, fico grato.
segue função:
function GetContact: TStringList;
var
cursorContacts, cursorContactsPhone: JCursor;
hasPhoneNumber: Integer;
id: Int64;
displayName, phoneNumber, contactID: string;
begin
Result := TStringList.Create;
cursorContacts := SharedActivity.getContentResolver.query(TJContactsContract_Contacts.JavaClass.CONTENT_URI, nil, nil, nil, nil);
if (cursorContacts.getCount > 0) then
begin
while (cursorContacts.moveToNext) do
begin
id := cursorContacts.getLong(cursorContacts.getColumnIndex(StringToJString(‘_ID’)));
displayName := JStringToString(cursorContacts.getString(cursorContacts.getColumnIndex(StringToJString(‘DISPLAY_NAME’))));
hasPhoneNumber := cursorContacts.getInt(cursorContacts.getColumnIndex(StringToJString(‘HAS_PHONE_NUMBER’)));
if (hasPhoneNumber > 0) then
begin
cursorContactsPhone := SharedActivity.getContentResolver.query(TJCommonDataKinds_Phone.JavaClass.CONTENT_URI, nil,StringToJString(‘CONTACT_ID = ‘ + IntToStr(id)),nil, nil);
while (cursorContactsPhone.moveToNext) do
begin
phoneNumber := JStringToString(cursorContactsPhone.getString(cursorContactsPhone.getColumnIndex(StringToJString(‘DATA1’))));
contactID := JStringToString(cursorContactsPhone.getString(cursorContactsPhone.getColumnIndex(StringToJString(‘CONTACT_ID’))));
Result.Add(displayName + ‘: ‘ + phoneNumber);
end;
cursorContactsPhone.close;
end;
end;
end;
cursorContacts.close;
end;
Boa tarde, gostaria de saber como poderia usar intents para abrir arquivos pdf com aplicações externa.
Agradeço a atenção.
Olá Fernando!
Pode usar uma ACTION_VIEW… passe o endereço do PDF e deixe que o SO verifique quais apps ele tem instalado que se candidatam à operação, Isso trabalhando com intent Implicita, claro.
intent.setDataAndType({camimnho arquivo}, “application/pdf”);
Esse vídeo pode ajudar: https://www.youtube.com/watch?v=ZCQ1y3qi92s