Neste guia, mostramos como informar o status de uma solicitação de trabalho executada em um serviço em segundo plano
ao componente que enviou a solicitação. Isso permite, por exemplo, informar o status
a solicitação na interface de um objeto Activity
. A maneira recomendada de enviar
receber status é usar um LocalBroadcastManager
, que
limita objetos Intent
de transmissão a componentes no seu próprio app.
Relatar o status a partir de um JobIntentService
Para enviar o status de uma solicitação de trabalho em uma
JobIntentService
para outros
componentes, primeiro crie um Intent
que contenha o status em seu
dados estendidos. Como opção, você pode adicionar um URI de ação e dados a essa
Intent
:
Em seguida, envie Intent
chamando
LocalBroadcastManager.sendBroadcast()
. Isso envia o Intent
para qualquer
no aplicativo que foi registrado para recebê-lo.
Para acessar uma instância de LocalBroadcastManager
, chame
getInstance()
.
Exemplo:
Kotlin
... // Defines a custom Intent action const val BROADCAST_ACTION = "com.example.android.threadsample.BROADCAST" ... // Defines the key for the status "extra" in an Intent const val EXTENDED_DATA_STATUS = "com.example.android.threadsample.STATUS" ... class RSSPullService : JobIntentService() { ... /* * Creates a new Intent containing a Uri object * BROADCAST_ACTION is a custom Intent action */ val localIntent = Intent(BROADCAST_ACTION).apply { // Puts the status into the Intent putExtra(EXTENDED_DATA_STATUS, status) } // Broadcasts the Intent to receivers in this app. LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent) ... }
Java
public final class Constants { ... // Defines a custom Intent action public static final String BROADCAST_ACTION = "com.example.android.threadsample.BROADCAST"; ... // Defines the key for the status "extra" in an Intent public static final String EXTENDED_DATA_STATUS = "com.example.android.threadsample.STATUS"; ... } public class RSSPullService extends JobIntentService { ... /* * Creates a new Intent containing a Uri object * BROADCAST_ACTION is a custom Intent action */ Intent localIntent = new Intent(Constants.BROADCAST_ACTION) // Puts the status into the Intent .putExtra(Constants.EXTENDED_DATA_STATUS, status); // Broadcasts the Intent to receivers in this app. LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent); ... }
A próxima etapa é processar os objetos Intent
de transmissão de entrada no
o componente que enviou a solicitação de trabalho original.
Receber transmissões de status a partir de um JobIntentService
Para receber objetos Intent
de transmissão, use uma subclasse de
BroadcastReceiver
. Na subclasse, implemente a
Chamada de retorno de BroadcastReceiver.onReceive()
, que LocalBroadcastManager
invoca quando recebe
um Intent
. LocalBroadcastManager
transmite o Intent
de entrada para
BroadcastReceiver.onReceive()
Exemplo:
Kotlin
// Broadcast receiver for receiving status updates from the IntentService. private class DownloadStateReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { ... /* * Handle Intents here. */ ... } }
Java
// Broadcast receiver for receiving status updates from the IntentService. private class DownloadStateReceiver extends BroadcastReceiver { // Called when the BroadcastReceiver gets an Intent it's registered to receive @Override public void onReceive(Context context, Intent intent) { ... /* * Handle Intents here. */ ... } }
Depois de definir o BroadcastReceiver
, é possível definir filtros
que correspondem a ações, categorias e dados específicos. Para isso, crie
um IntentFilter
. Este primeiro snippet mostra como definir o filtro:
Kotlin
// Class that displays photos class DisplayActivity : FragmentActivity() { ... override fun onCreate(savedInstanceState: Bundle?) { ... super.onCreate(savedInstanceState) ... // The filter's action is BROADCAST_ACTION var statusIntentFilter = IntentFilter(BROADCAST_ACTION).apply { // Adds a data filter for the HTTP scheme addDataScheme("http") } ...
Java
// Class that displays photos public class DisplayActivity extends FragmentActivity { ... public void onCreate(Bundle stateBundle) { ... super.onCreate(stateBundle); ... // The filter's action is BROADCAST_ACTION IntentFilter statusIntentFilter = new IntentFilter( Constants.BROADCAST_ACTION); // Adds a data filter for the HTTP scheme statusIntentFilter.addDataScheme("http"); ...
Para registrar o BroadcastReceiver
e o
IntentFilter
com o sistema, receba uma instância de
LocalBroadcastManager
e chamar
registerReceiver()
. O próximo snippet mostra como registrar o BroadcastReceiver
e IntentFilter
:
Kotlin
// Instantiates a new DownloadStateReceiver val downloadStateReceiver = DownloadStateReceiver() // Registers the DownloadStateReceiver and its intent filters LocalBroadcastManager.getInstance(this) .registerReceiver(downloadStateReceiver, statusIntentFilter) ...
Java
// Instantiates a new DownloadStateReceiver DownloadStateReceiver downloadStateReceiver = new DownloadStateReceiver(); // Registers the DownloadStateReceiver and its intent filters LocalBroadcastManager.getInstance(this).registerReceiver( downloadStateReceiver, statusIntentFilter); ...
Um único BroadcastReceiver
pode processar mais de um tipo de transmissão
Objeto Intent
, cada um com a própria ação. Esse recurso permite que você
executar códigos diferentes para cada ação, sem precisar definir
BroadcastReceiver
para cada ação. Para definir outro
IntentFilter
igual
BroadcastReceiver
, crie a IntentFilter
e
Repita a chamada para
registerReceiver()
.
Exemplo:
Kotlin
/* * Instantiates a new action filter. * No data filter is needed. */ statusIntentFilter = IntentFilter(ACTION_ZOOM_IMAGE) // Registers the receiver with the new filter LocalBroadcastManager.getInstance(this) .registerReceiver(downloadStateReceiver, statusIntentFilter)
Java
/* * Instantiates a new action filter. * No data filter is needed. */ statusIntentFilter = new IntentFilter(Constants.ACTION_ZOOM_IMAGE); // Registers the receiver with the new filter LocalBroadcastManager.getInstance(this).registerReceiver( downloadStateReceiver, statusIntentFilter);
O envio de uma transmissão Intent
não inicia nem retoma uma
Activity
. O BroadcastReceiver
de um
O Activity
recebe e processa objetos Intent
, mesmo
quando o app está em segundo plano, mas não o força a ficar em primeiro plano. Se você
querem notificar o usuário sobre um evento que ocorreu em segundo plano enquanto o app não estava
visível, use um Notification
. Nunca inicie uma
Activity
em resposta a uma transmissão recebida
Intent
.