Mostrando una Snackbar desde dentro de un Servicio
Cuando muestro una SnackBar desde dentro de una Actividad, tengo el rootView disponible. Pero tengo que mostrar una SnackBar desde dentro de un servicio, donde no tengo una vista disponible. ¿Cómo podría lograr esto?
Como backstory: una actividad inicia un servicio para hacer una tarea. El Servicio necesita mostrar una SnackBar dependiendo de las situaciones. No quiero unirme al servicio sólo por eso. Entonces, ¿cómo puedo lograr esto? Normalmente podría mostrar un brindis, pero necesito que el usuario pueda leer el mensaje y confirmarlo.
- Android jobScheduler no se detendrá con jobFinished (params, false)
- Transmisión recibida dos veces
- ¿Necesita un ejemplo de código sobre cómo ejecutar un servicio Android para siempre en segundo plano incluso cuando el dispositivo está durmiendo, como Whatsapp?
- ¿Por qué obtengo una InstantiationException si intento iniciar un servicio?
- Android Speech Reconocimiento de voz: Llamada repetida de SpeechRecognizer.startListening () falla en JB 4.1.2
- Implementar receptor de difusión dentro del servicio
- El servicio androide deja de funcionar después de que la aplicación no esté en uso por un tiempo
- Servicio de Android e hilo de la interfaz de usuario
- Servicio de fondo en Android - Necesita ayuda
- Android startService Synchronous?
- Android API21: VoiceInteractionService onReady () no se llama
- ¿Cómo puedo eliminar una notificación de primer plano en Android Lollipop?
- Cómo enviar datos de IntentService a clase Non-Activity
La Snackbar
necesita una View
para que se muestre, así que si quieres mostrar barras de aperitivos en tu aplicación dependiendo del estado de tu Service
tendrás que LocalBroadcastManager
a tu Activity
o transmitir un mensaje a través de LocalBroadcastManager
y mostrar un mensaje en tu cuenta View
.
No creo que haya otra forma de evitarlo, tendrás que comunicarte con tu Activity
o Fragment
alguna manera.
Snackbars no son como tostadas que sólo necesitan un contexto , así que si quieres mostrarlo fuera de su aplicación, creo que no puede con la clase proporcionada por Android.
A partir de las directrices de diseño :
Colocación
Snackbars aparecen por encima de la mayoría de los elementos en la pantalla, y son iguales en elevación al botón de acción flotante. Sin embargo, son más bajos en la elevación que los cuadros de diálogo, las hojas inferiores y los cajones de navegación.
No es explícito, pero puedes llegar a la conclusión de que solo se mostrará en las vistas de tu aplicación. Por lo tanto, de nuevo, tendrá que comunicarse con su vista visible de alguna manera.
Snippets en la difusión de un mensaje:
Remitente (en su Servicio)
private void doSendBroadcast(String message) { Intent it = new Intent("EVENT_SNACKBAR"); if (!TextUtils.isEmpty(message)) it.putExtra(EXTRA_RETURN_MESSAGE,message); LocalBroadcastManager.getInstance(mContext).sendBroadcast(it); }
Receptor (en su actividad)
private BroadcastReceiver mMessageReceiver = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Other stuff. mMessageReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // Do something } }; } @Override public void onResume() { super.onResume(); LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, new IntentFilter("EVENT_SNACKBAR")); }
Más información sobre servicios enlazados aquí .
Y sobre LocalBroadcastManager
aquí en esta pregunta .
Siempre se puede enviar una emisión a través de LocalBroadcastManager
en su Service
LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("SERVICE_DID_SOMETHING"));
Y luego en la Activity
use un BroadcastReceiver
para mostrar la Snackbar
private final ServiceReceiver _serviceReceiver = new ServiceReceiver(); @Override protected void onResume() { super.onResume(); final IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction("SERVICE_DID_SOMETHING"); LocalBroadcastManager.getInstance(this).registerReceiver(_serviceReceiver, intentFilter); } @Override protected void onPause() { super.onPause(); try { LocalBroadcastManager.getInstance(this).unregisterReceiver(_serviceReceiver); } catch (Exception ex) { Log.e(TAG, "Error unregistering ServiceReceiver", ex); } } // region ServiceReceiver private class ServiceReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // TODO: Show your Snackbar here... } } // endregion
Puede utilizar la Intent
que envía para pasar datos adicionales si es necesario y, a continuación, extraerlo en BroadcastReceiver.onReceive(Context context, Intent intent)
No es posible hacerlo con el SnackBar
predeterminado proporcionado por el SDK, ya que siempre requerirá una vista.
Para servir a su propósito, puede utilizar alguna biblioteca externa que imita a una SnackBar como ésta
Cómo crear una Snackbar con el contexto de la aplicación que es visible en varias actividades: https://stackoverflow.com/a/37707741/1185087
- Cómo habilitar la depuración USB para el Samsung S7
- Cambiar el tema de TimePickerDialog para usar AppTheme