2016-01-18 3 views
5

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

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

+0

Чтобы уточнить, вы спрашиваете о том, чтобы показать Snackbar, когда пользователь использует приложение, или в любое время, даже если приложение закрыто? – Phil

ответ

9

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

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

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

Как из design guidelines:

Размещение

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

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


Отрывки на транслирует сообщение:

отправителя (на службу)

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

Больше на связанно услуги here.

И около LocalBroadcastManagerhere on this question.

Update: Вы можете также использовать в EventBus для связи с видимой зрения, как это работает на Издатель/Подписчик моды. Вы могли бы даже использовать концепцию Sticky events, чтобы убедиться, что Snackbar будет отображаться, как только приложение будет видно снова.

Посмотрите на мой номер this answer о том, как использовать автобус событий.

2

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

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

А потом в Activity использовать 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)

+0

Спасибо за помощь. +1. Я могу принять только один ответ, поэтому я перевернул монету. Благодарю. –

1

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

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

+2

был бы признателен за причину, когда кто-то занижает, если только это не связано с конкурирующими ответами, требующими внимания. :) – AndroidMechanic

+0

Это, как правило, много здесь. Я ненавижу, это неконструктивно. – Mauker

+0

Нет, @AndroidMechanic, вам необходимо передать представление SnackBar, предоставленное SDK или этой библиотекой. Вы сможете найти 2 конструктора. # 1 'new SnackBar.Builder (this)' - 'this' как активность. # 1 'new SnackBar.Builder (getActivity(). GetApplicationContext(), root)' - 'root' как view root –

0

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

+0

Похоже, что это сработает, позвольте мне проверить это. –