Отображение закуски изнутри службы

Когда вы показываете SnackBar изнутри Activity, у меня есть rootView. Но мне нужно показать SnackBar внутри службы, где у меня нет View. Как я могу это сделать?

В качестве предыстории: действие запускает службу для выполнения задачи. Служба должна показывать SnackBar в зависимости от ситуаций. Я не хочу привязываться к Службе только для этого. Итак, как я могу это сделать? Обычно я мог показывать тост, но мне нужно, чтобы пользователь мог прочитать сообщение и подтвердить это.

Для Snackbar нужен View для отображения, поэтому, если вы хотите показать snackbars в своем приложении в зависимости от состояния вашего Service вам придется либо привязать его к своей Activity либо передать сообщение через LocalBroadcastManager и показать сообщение на вашем View .

Я не думаю, что есть какой-то другой способ, вам придется как-то общаться с вашей Activity или Fragment .

Закуски не похожи на тосты, которым нужен только контекст , поэтому, если вы хотите отобразить его из своего приложения, я считаю, что вы не можете с классом, предоставляемым Android.

Как из руководства по проектированию :

размещение

Закуски отображаются над большинством элементов на экране, и они равны по высоте для кнопки с плавающим действием. Однако они ниже по высоте, чем диалоги, нижние листы и ящики для навигации.

Он не является явным, но вы можете прийти к выводу, что он будет отображаться только в ваших приложениях. Так что, опять-таки, вам придется как-то общаться с вашим видимым видом.


Фрагменты трансляции сообщения:

Отправитель (на вашей службе)

 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); } 

Приемник (по вашей деятельности)

 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")); } 

Подробнее о связанных службах здесь .

А насчет LocalBroadcastManager здесь по этому вопросу .

Вы всегда можете отправлять трансляцию через LocalBroadcastManager в своей Service

 LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("SERVICE_DID_SOMETHING")); 

И затем в Управлении используйте BroadcastReceiver чтобы показать 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 

Вы можете использовать Intent вы отправляете, для передачи дополнительных данных, если это необходимо, а затем вытащить его в BroadcastReceiver.onReceive(Context context, Intent intent)

Это невозможно сделать с помощью SnackBar по умолчанию, предоставляемого SDK, поскольку для этого всегда требуется представление.

Чтобы служить вашей цели, вы можете использовать некоторую внешнюю библиотеку, которая имитирует SnackBar, подобную этой

Как создать Snackbar с контекстом приложения, который отображается в нескольких действиях: https://stackoverflow.com/a/37707741/1185087