Diferenças entre Intent e PendingIntent

97

Li alguns artigos e ambos parecem fazer a mesma coisa e fiquei imaginando qual é a diferença entre iniciar o serviço assim:

Intent intent = new Intent(this, HelloService.class);
startService(intent);

ou assim:

Calendar cal = Calendar.getInstance();
Intent intent = new Intent(this, MyService.class);
PendingIntent pintent = PendingIntent.getService(this, 0, intent, 0);
AlarmManager alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 30*1000, pintent); 

Conforme eu leio, esses dois fazem a mesma coisa, se no serviço você retornar um parâmetro START_STICKY;

user3629316
fonte
Não há diferença. O que te faz pensar que haveria? No primeiro caso você está iniciando 'agora' e no segundo você está apenas agendando para um horário / data posterior.
Squonk de
Possível duplicata de What is an Android PendingIntent?
James Moore

Respostas:

150

Intenção

Um Android Intent é um objeto que carrega um intent, ou seja, uma mensagem de um componente para outro componente, dentro ou fora do aplicativo. Os intents podem comunicar mensagens entre qualquer um dos três componentes principais de um aplicativo - Activities, Services e BroadcastReceivers.

A própria intenção, um objeto Intent, é uma estrutura de dados passiva. Ele contém uma descrição abstrata de uma operação a ser executada.

Por exemplo: digamos que você tenha uma atividade que precisa iniciar um cliente de email e enviar um email. Para fazer isso, sua Activity enviaria um Intent com a ação ACTION_SEND, junto com o seletor apropriado, para o Android Intent Resolver:

Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:")); // only email apps should handle this

O seletor especificado fornece a interface adequada para o usuário escolher como enviar seus dados de e-mail.

INTENÇÕES EXPLICITAS

// Explicit Intent by specifying its class name
   Intent i = new Intent(this, TargetActivity.class);
   i.putExtra("Key1", "ABC");
   i.putExtra("Key2", "123");

// Starts TargetActivity
   startActivity(i);

INTENÇÕES IMPLÍCITAS

// Implicit Intent by specifying a URI
   Intent i = new Intent(Intent.ACTION_VIEW, 
   Uri.parse("http://www.example.com"));

// Starts Implicit Activity
   startActivity(i); 

Intenção Pendente

Um PendingIntent é um token que você dá a um aplicativo externo (por exemplo, NotificationManager, AlarmManager, Home Screen AppWidgetManager ou outros aplicativos de terceiros), que permite ao aplicativo externo usar as permissões de seu aplicativo para executar um trecho predefinido de código.

Ao fornecer um PendingIntent a outro aplicativo, você está concedendo a ele o direito de realizar a operação especificada como se o outro aplicativo fosse você (com as mesmas permissões e identidade). Como tal, você deve ter cuidado sobre como construir o PendingIntent: quase sempre, por exemplo, o Intent de base que você fornece deve ter o nome do componente explicitamente definido para um de seus próprios componentes, para garantir que seja enviado para lá e para nenhum outro lugar.

Exemplo de intenção pendente: http://android-pending-intent.blogspot.in/

Fonte: Android Intents e Android Pending Intents

Espero que isto ajude.

Siddharth_Vyas
fonte
26

PendingIntenté um invólucro de Intent. O aplicativo estrangeiro que recebe o PendingIntentnão sabe o conteúdo do Intentqual está envolvido PendingIntent. A missão do aplicativo estrangeiro é enviar de volta a intenção ao proprietário quando algumas condições forem atendidas (por exemplo: alarme com programação ou notificação com clique ...). As condições são fornecidas pelo proprietário, mas processadas pelo aplicativo externo (por exemplo: alarme, notificação).

Se o aplicativo estrangeiro enviou uma intenção para o seu aplicativo, significa que o aplicativo estrangeiro conhece o conteúdo da intenção. e o aplicativo externo toma a decisão de enviar a intenção, então seu aplicativo deve processar a intenção para atender a algumas condições => seu aplicativo obtém o recurso de desempenho do sistema.

HungNM2
fonte
5

Outra diferença simples:

  • A intenção normal morrerá assim que o aplicativo for encerrado.

  • As intenções pendentes nunca morrem. Eles estarão vivos enquanto for necessário pelo serviço de alarme, serviço de localização ou quaisquer outros serviços.

Zumry Mohamed
fonte
1

Iniciando serviços regularmente através do AlarmManager

Tal como acontece com as atividades, o sistema Android pode encerrar o processo de um serviço a qualquer momento para economizar recursos. Por esse motivo, você não pode simplesmente usar um TimerTaskno serviço para garantir que ele seja executado regularmente.

Assim, para o correto agendamento do Serviço utilize a AlarmManageraula.

ATUALIZAR:

Portanto, não há diferença real entre os dois. Mas dependendo se você quer garantir a execução do serviço ou não, você pode decidir o que usar, pois para o primeiro não há garantia e para o posterior sim.

Mais informações em AndroidServices .

Meu Deus
fonte
2
Na verdade, isso não responde à pergunta do OP, que é "qual é a diferença" entre iniciar um serviço diretamente e iniciar um serviço com um alarme. Além disso, o OP provavelmente viu o artigo para o qual você vincula, pois o código do artigo é quase idêntico ao que o OP postou.
Squonk de
Você quer dizer que iniciar um serviço do AlarmManager é mais seguro e menos provável de ser encerrado do que devido a uma atividade? Eu acho isso errado. Você pode explicar, por favor. @VedPrakash. Além disso, acho que o contexto que você passa ao criar uma intenção para iniciar o serviço é mais importante. Usar o contexto do aplicativo (getApplicationContext ()) em vez de uma atividade (this), deve ser mais seguro.
Parth Kapoor
@ Eu.Dr. Recomendo que você use o gerenciador de alarmes que será disparado a cada vez que X ... executar a tarefa .. Por quê? porque se você usar serviços ele pode ser fechado em algum momento e você pode acabar pulando algumas atualizações em um determinado momento (desconhecido). Para dúvidas de contexto, nunca use getApplicationContext()ou use quando quiser estritamente, apenas leia - when-to-call-activity-context-or-application-context ( stackoverflow.com/questions/7298731/… ).
Meu Deus
1

Funcionalmente, não há diferença.

O significado de PendingIntent é que você pode manipulá-lo para outro aplicativo que mais tarde poderá usá-lo como se o outro aplicativo fosse você. Aqui está a explicação relevante da documentação :

Ao fornecer um PendingIntent a outro aplicativo, você está concedendo a ele o direito de realizar a operação especificada como se o outro aplicativo fosse você (com as mesmas permissões e identidade). Como tal, você deve ter cuidado sobre como construir o PendingIntent: quase sempre, por exemplo, o Intent de base que você fornece deve ter o nome do componente explicitamente definido para um de seus próprios componentes, para garantir que seja enviado para lá e para nenhum outro lugar.

Um próprio PendingIntent é simplesmente uma referência a um token mantido pelo sistema que descreve os dados originais usados ​​para recuperá-lo.

Portanto, PendingIntent é apenas uma referência aos dados que representam o Intent original (que foi usado para criar o PendingIntent).

Kupsef
fonte
4
Dizer que funcionalmente não há diferença é incorreto. Se as funções de ambos são iguais, por que ter dois em primeiro lugar? A diferença mais importante é que PendingIntent é executado por componente remoto (como NotificationManager) com as mesmas permissões do componente que o entrega (aquele que cria a notificação).
Aniket Thakur,