BroadcastReceiver no Android, Executando Tarefas no Background

Receba em primeira mão, e com prioridade, os conteúdos Android exclusivos do Blog. Você receberá um email de confirmação. Somente depois de confirma-lo é que poderei lhe enviar os conteúdos exclusivos.

Email inválido.
Blog /Android /BroadcastReceiver no Android, Executando Tarefas no Background

BroadcastReceiver no Android, Executando Tarefas no Background

Vinícius Thiengo
(12975) (14)
Go-ahead
"É fácil decidir o que fazer. O difícil é decidir o que não fazer."
Michael Dell
Kotlin Android
Capa do livro Desenvolvedor Kotlin Android - Bibliotecas para o dia a dia
TítuloDesenvolvedor Kotlin Android - Bibliotecas para o dia a dia
CategoriasAndroid, Kotlin
AutorVinícius Thiengo
Edição
Capítulos19
Páginas1035
Acessar Livro
Treinamento Oficial
Android: Prototipagem Profissional de Aplicativos
CursoAndroid: Prototipagem Profissional de Aplicativos
CategoriaAndroid
InstrutorVinícius Thiengo
NívelTodos os níveis
Vídeo aulas186
PlataformaUdemy
Acessar Curso
Receitas Android
Capa do livro Receitas Para Desenvolvedores Android
TítuloReceitas Para Desenvolvedores Android
CategoriaDesenvolvimento Android
AutorVinícius Thiengo
Edição
Ano2017
Capítulos20
Páginas936
Acessar Livro
Código Limpo
Capa do livro Refatorando Para Programas Limpos
TítuloRefatorando Para Programas Limpos
CategoriaEngenharia de Software
AutorVinícius Thiengo
Edição
Capítulos46
Páginas599
Acessar Livro
Quer aprender a programar para Android? Acesse abaixo o curso gratuito no Blog.
Conteúdo Exclusivo
Receba em primeira mão, e com prioridade, os conteúdos Android exclusivos do Blog.
Email inválido

Tudo bem?

Na vídeo aula acima vamos passo a passo ao estudo de uma das APIs que mais perderam "força" ao longo da evolução do Android e da chegada de novas regras de negócio. Porém continua sendo uma importante API: BroadcastReceiver.

Se você ainda não conhece o termo broadcast, basicamente ele significa, na TI: transmissão para todos.

Sendo assim, não é difícil imaginar que um objeto do tipo BroadcastReceiver (RecebedorTransmissao - eu sei, a tradução não ficou nada legal) é basicamente uma entidade configurada para receber informações.

No caso do Android é para:

  • Receber informações das quais ela foi registrada, a entidade BroadcastReceiver. Podendo ser informações, mensagens, de outros aplicativos ou do sistema Android.
  • E também para enviar informações em modo broadcast.

A API BroadcastReceiver é muito similar a um trigger, gatilho, de banco de dados, isso devido a limitação de 10 segundos que temos de processamento quando a API é acionada e o método onReceiver() é invocado com os dados em mensagem broadcast (na vídeo aula você entenderá muito bem sobre isso).

Ou seja, somente se você tiver certeza que o algoritmo que será executado a partir de BroadcastReceiver.onReceiver() não chegará, em hipótese alguma, aos temidos 10 segundos de execução.

Somente nesta circunstância é que recomendo não utilizar um objeto BroadcastReceiver como um mero acionador de alguma outra entidade mais completa para execução, um Service, por exemplo.

Mas já lhe adianto: apesar de a API BroadcastReceiver não ter sido desenvolvida somente para algoritmos que executam em background, ela é comumente utilizada para aciona-los e esses algoritmos tendem a ter um tempo de processamento não consistente (não conhecido), ou seja, muitas vezes é arriscado deixar o algoritmo principal de execução no onReceiver().

A configuração de um BroadcastReceiver pode ser dinâmica:

public class MainActivity extends AppCompatActivity {

private CustomBroadcastReceiver customBroadcast;

@Override
protected void onCreate( Bundle savedInstanceState ) {
super.onCreate( savedInstanceState );

customBroadcast = new CustomBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter( Intent.ACTION_AIRPLANE_MODE_CHANGED );
registerReceiver( customBroadcast, intentFilter );

...
}

@Override
protected void onDestroy() {
unregisterReceiver( customBroadcast );
super.onDestroy();
}
}

 

Ou estática:

<?xml version="1.0" encoding="utf-8"?>
<manifest
...>
...

<application
...>

<receiver
android:name=".CustomBroadcastReceiver"
android:exported="true">

<intent-filter>
<action android:name="android.intent.action.ACTION_AIRPLANE_MODE_CHANGED"/>
</intent-filter>
</receiver>

...
</application>
</manifest>

 

Em ambas as definições têm duas entidades que são extremamente importantes para o funcionamento de mensagens broadcast: Intent e IntentFilter.

São elas que permitem ao sistema Android saber quais são os aplicativos que devem receber, por exemplo, uma mensagem broadcast disparada pelo app XYZ.

Fluxo de registro de um BroadcastReceiver

Você deve ter notado que a API BroadcastReceiver nos permite ter contato com as mensagens públicas do mundo exterior ao nosso app, certo? Para mensagens internas, podemos utilizar o irmão mais novo de BroadcastReceiver, o LocalBroadcastManager.

E é isso, a vídeo aula está bem completa e eu fortemente recomendo que você também estude pelos links oficiais indicados em "Fontes".

Antes de finalizar, vou deixar a seguir alguns links de outros conteúdos do Blog, com vídeos, que lhe colocarão em dia com o que há de atual no mundo do desenvolvimento Android:

E caso você tenha o interesse de aprender a criar apps Android, ou evoluir nesta área, também com o conteúdo gratuito do Blog, então não deixe de acessar a lista de estudos em: Estudando Android - Lista de Conteúdos do Blog.

Não esqueça de se inscrever 📫 na lista de e-mails do Blog para receber os conteúdos Android, liberados semanalmente.

Se inscreva também no canal do Blog no YouTube para acompanhar as últimas novidades disponibilizadas em vídeo aula.

Surgindo dúvidas ou dicas, pode colocar abaixo na área de comentários que logo eu lhe retorno.

Obs. 1: o link para download do projeto apresentado em vídeo se encontra logo abaixo no artigo, na seção "Download".

Obs. 2: foram inevitáveis os erros com o terceiro objeto BroadcastReceiver na vídeo aula, eu preferi não remove-los pois foram corrigidos no vídeo mesmo.

Abraço.

Eclipse IDE vs Android Studio IDE

Apesar de o conteúdo da vídeo aula acima estar utilizando o Eclipse IDE 😱, tudo que é apresentado, tanto a parte teórica quanto a parte prática, é ainda válido nos dias de hoje com o desenvolvimento Android utilizando o Android Studio 😁.

Ou seja, independente da linguagem oficial (Java, Kotlin, C ou C++), IDE ou framework que você esteja utilizando, o conteúdo acima é ainda muito útil.

Fontes

BroadcastReceiver - documentação oficial Android

<receiver> - documentação oficial Android

Broadcasts overview

BroadcastReceiver declared in manifest is not receiving the Broadcast

Receba em primeira mão, e com prioridade, os conteúdos Android exclusivos do Blog.
Email inválido

Relacionado

TextToSpeech: Fazendo Sua APP Android FalarTextToSpeech: Fazendo Sua APP Android FalarAndroid
onSaveInstanceState, Bitmap e Serializable no Android. CorreçãoonSaveInstanceState, Bitmap e Serializable no Android. CorreçãoAndroid
Acessando Imagens do SDCard e Colocando na APP AndroidAcessando Imagens do SDCard e Colocando na APP AndroidAndroid
Simples Formulário na APP Android Comunicando com Servidor Web PHPSimples Formulário na APP Android Comunicando com Servidor Web PHPAndroid

Compartilhar

Comentários Facebook

Comentários Blog (14)

Para código / script, coloque entre [code] e [/code] para receber marcação especifica.
Forneça seu nome válido.
Forneça seu email válido.
Forneça o comentário.
Enviando, aguarde...
24/05/2018
Olá Thiengo, tenho uma dúvida, não sei se utilizaria esse recurso. Mas queria abrir uma chamada via notificação, basicamente o que o uber faz com os motoristas quando recebem uma chamada,  fazer com que o celular "chame" abrindo uma tela. Você sabe qual recurso utilizaria dentro do app??
Responder
Vinícius Thiengo (1) (0)
24/05/2018
Yuri, tudo bem?

Estou assumindo que o algoritmo de notificação push você já tem domínio e até mesmo já o adicionou em seu projeto, certo?

Caso não, veja o conteúdo do link a seguir: https://www.thiengo.com.br/fcm-android-dominio-do-problema-implementacao-e-testes-com-servidor-de-aplicativo-parte-1

Se quiser que a chamada telefônica ocorra assim que a notificação chegue ao device, ou seja, sem necessidade de interação do usuário, coloque algum dos algoritmos do link a seguir dentro do método onMessageReceived() da classe que estende FirebaseMessagingService:

https://stackoverflow.com/a/45790561/2578331

Realize testes com ACTION_CALL e ACTION_DIAL, veja qual action melhor se encaixa em seu domínio do problema.

Se quiser que a ligação ocorra somente depois da interação do usuário com a notificação, coloque algum dado no JSON de notificação push (JSON preenchido no lado servidor) para que este dado possa ser lido na atividade de seu app assim que o usuário acionar a notificação.

Com um simples condicional, if(), na atividade que será acionada pela notificação, é possível saber se o dado está na Intent vinculada a notificação e então acionar o ACTION correto de acordo com o link do StackOverflow compartilhado anteriormente.

Yuri, escolha alguma das estratégias anteriores e siga com o dev de seu aplicativo Android. Não há necessidade de uso do BroadcastReceiver.

Abraço.
Responder
18/06/2018
Olá Thiengo, eu entendi o que você disse, mas a idéia não era abrir uma chama telefônica, e sim uma notificação personalizada, tipo um popup, como se fosse um alarme, e isso teria que ocorrer até com o celular bloqueado.
Responder
Vinícius Thiengo (0) (0)
19/06/2018
Yuri, se entendi bem, agora, é algo similar ao que o WhatsApp faz com ligações telefônicas (VoIP) utilizando as tecnologias deles, certo?

Pergunto isso, pois não sou usuário do Uber.

Se confirmado, é sim uma ligação no modelo do WhatsApp, a seguir deixo alguns links de tecnologia VoIP para aplicativos Android:

-> https://developer.android.com/reference/android/net/sip/package-summary

-> https://developer.android.com/samples/

-> https://www.twilio.com/client/mobile

Sobre a apresentação em pop-up, caixa de diálogo: como envolverá, provavelmente, um controle de outras APIs, ao menos a API de VoIP, recomendo o uso do DialogFragment que tem o próprio ciclo de vida e consequentemente não irá "inflar" a atividade (ou fragmento) principal de seu projeto com algumas mais centenas de linhas de código:


-> https://www.thiengo.com.br/dialogfragment-no-android-entendendo-e-utilizando

Abraço.
Responder
Anthony (2) (0)
22/11/2017
Ótima explicação.
Estou iniciando estudos com BradcasReceiver e fiz esse exemplo seu no android studio. BroadcastReceiver pela API foi de boa, agora pelo XML (mainfest) não funciona. Não da erro mas também não aparece a mensagem no log. Sabe me dizer o porque? o código xml esta assim:
<receiver
            android:name="br.meuprojeto.BroadcastReceiver1"
            android:label="BroadcastReceiver1"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="BROADCAST_RECEIVER_XML" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>

Obrigado.
Responder
Vinícius Thiengo (0) (0)
24/11/2017
Anthony, tudo bem?

Como está a lógica de negócio? Digo, está tentando acionar o BroadcastReceiver por meio de uma Intent de algum outro aplicativo? Como está, incluindo o código de acionamento?

Abraço.
Responder
Giovanni (1) (0)
04/04/2018
o meu tbm nao funciona pelo XML, o codigo eh o mesmo pro da API, eu so faco um log e um toast dizendo que deu certo.

tenho esse receiver:
public class MyReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub
        Log.i("Script", "BroadcastReceiver1");
        Toast.makeText(context, "deu certo", Toast.LENGTH_LONG).show();
    }

}

isso daqui no xml:

<receiver android:label="MyReceiver"
            android:name="com.example.giovanni.broadcast_receivers.MyReceiver">
            <intent-filter>
                <category android:name="android.intent.category.DEFAULT"/>
                <action android:name="HAHAHA"/>
            </intent-filter>
        </receiver>

e a mesma funcao que vc usa:

public void chamarBR(View view){
        Intent intent = new Intent("HAHAHA");
        sendBroadcast(intent);
    }

so reforcando que pro metodo API da certo, quando cria o intent filter no onCreate() e etc.. Sera que pelo XML nao foi desativado? pq ja tentei mil vezes e nunca funciona
Responder
Vinícius Thiengo (0) (0)
05/04/2018
Giovanni, tudo bem?

O Android, nas versões mais atuais, adicionou algumas regras de negócio para APIs como BroadcastReceiver e Service, modificando assim o modo de uso destas.

Em seu método chamarBR() coloque o código a seguir e realize novos testes:

Intent intent = new Intent( this, MyReceiver.class );
intent.setAction( "HAHAHA" );
sendBroadcast( intent );

Abraço.
Responder
ARMANDO SOARES (1) (0)
14/12/2016
bom dia, vc comentou de o servidor mandar msg para os app cadastrados no seu banco de dados, que vc utiliza quando tem novo post, com o recurso GcN  do Google, eu preciso fazer esta mesma proposta para um projeto meu poderia me enviar o projeto, ou dicas como fazer. muito obrigado Armando.
Responder
Vinícius Thiengo (0) (0)
14/12/2016
Armando, tudo bem?

Dê uma olhada nos itens 4, 5 e 6 da lista de itens desse tópico: http://www.thiengo.com.br/estudando-android-lista-de-conteudos-do-blog#title-10 (Alertas, notificações e push message).

Com isso terá o suficiente para implementar o mesmo que informei aqui, porém em seu projeto.

Veja também se o OneSignal é uma possibilidade para seu projeto, pois ele é ainda mais simples de implementar. Segue link do artigo dele:

http://www.thiengo.com.br/onesignal-para-notificacoes-em-massa-no-android

Abraço.
Responder
13/11/2014
Exite uma versão mínima do android para a utilização do broadcast receiver?
Responder
07/09/2014
Oi, tudo bem? Me tira uma dúvida? É o seguinte, estou capturando o momento em que uma ligação é iniciada (não é recebida). Gostaria de saber, como eu capturo o número digitado pelo usuário? O método onReceive está assim:

@Override
public void onReceive(Context ctx, Intent it) {

String estado = it.getStringExtra("state");

String num =  it.getStringExtra("incoming_number");

String msg = null;

if (estado.equals("OFFHOOK"))
    msg = "Em ligação." + num;

Toast.makeText(ctx, msg,   Toast.LENGTH_LONG).show();
}

Funciona, mas o número vem null.

Muito bom o vídeo, você tem uma ótima didática.
Responder
Vinícius Thiengo (0) (0)
07/09/2014
Fala Rafael, blz?
Então, tb nunca fiz um script assim, mas encontrei duas publicações (com respostas) no stackoverflow que acho que podem lhe ajudar. Abraço.

http://stackoverflow.com/questions/12659536/incoming-number-during-a-call-in-android

http://stackoverflow.com/questions/6388168/how-to-get-phone-number-of-the-person-im-dialing

Veja a primeira resposta de cada link.
Responder