Wiem, że pytanie o sposób komunikacji między usługą a działaniem zostało wielokrotnie potwierdzone, ale chcę również, aby mój własny sposób sprawdzania tego był sprawdzany i wiedzieć, czy jest to akceptowalny i właściwy sposób, aby to zrobić i jakie są wady tego, jak sobie z tym poradziłem. Najpierw opiszę stwierdzenie problemu tak szczegółowo, jak tylko mogę.Jak komunikować się między usługą przesyłania wiadomości Firebase a działaniem? Android
Muszę zbudować aplikację, w której używam usługi przesyłania komunikatów Firebase do komunikacji między dwoma urządzeniami. Powiedzmy, że jest to system podobny do Ubera. Jedna aplikacja jest dla usługodawcy (sterownik) i jedna dla klienta (pasażera). Kiedy pasażer zażąda podróży ze swoją lokalizacją, kierowcy w określonym promieniu otrzymają powiadomienie push z ładunkiem za pomocą Firebase. Usługa Firebase działa w tle. Gdy usługa otrzymuje powiadomienie push, wywoływana jest metoda onMessageReceived
. Wydarzenie jest generowane. Nie używam tutaj Firebase do generowania powiadomień, ale w rzeczywistości przesyłam dane między urządzeniami, gdy potrzebuję skorzystać z pola powiadomień wypychania Firebase. Teraz aplikacja sterowników otrzyma współrzędne miejsca, w którym użytkownik chce, aby samochód znajdował się w ładowności powiadomienia wypychania Firebase. Mogę po prostu rozpocząć działanie z tymi danymi w dodatkach i pokazać sterownikowi, że odebrano żądanie.
Teraz po stronie klienta, po tym jak klient przesyła wniosek, przechodzi do następnej czynności, w której wyświetla się rodzaj ekranu ładowania, w którym oczekuje, że jeden z kierowców zaakceptuje ich prośbę. Gdy jeden z sterowników zaakceptuje żądanie tego użytkownika, ten użytkownik otrzyma powiadomienie push z Firebase z informacjami o wyznaczonym kierowcy w ładunku powiadomienia wypychania. Ponownie celem nie jest generowanie żadnych powiadomień, ale przesyłanie danych między urządzeniami.
Teraz, gdy zrozumiesz przypadek użycia, przejdę do problemu.
Problem pojawia się, gdy użytkownik przesyła żądanie i przechodzi do następnego ekranu oczekiwania, na którym jest wyświetlany ekran ładowania, nakazujący mu czekać, gdy żądanie oczekuje na przyjęcie przez jednego z kierowców. Kiedy kierowca zaakceptuje żądanie, jak już powiedziałem, użytkownik otrzyma powiadomienie push od Firebase z informacjami o kierowcy w ładunku powiadomienia wypychania. W jaki sposób mogę komunikować się między usługą a działaniem, aby powiadomić aktywność, aby przestała wyświetlać ekran ładowania i wypełniła pola tekstowe danymi odebranymi w treści powiadomienia wypychania.
Oto, jak sobie z tym poradziłem. Załóżmy, że mam działanie o nazwie AwaitingDriver
, które ma tekstView do wypełnienia danymi kierowcy. Ale obecnie działanie pokazuje ekran ładowania, ponieważ żądanie nie zostało jeszcze zaakceptowane. Teraz użytkownik otrzymuje powiadomienie push z informacjami o sterowniku w usłudze działającej w tle, bez połączenia z działaniem w żaden sposób. Oto moja metoda onMessageReceived
@Override
public void onMessageReceived(RemoteMessage remoteMessage){
SharedPreferences rideInfoPref = getSharedPreferences(getString(R.string.rideInfoPref), MODE_PRIVATE);
SharedPreferences.Editor rideInfoPrefEditor = rideInfoPref.edit();
String msgType = remoteMessage.getData().get("MessageType");
if (msgType.equals("RequestAccepted")){
rideInfoPrefEditor.putBoolean(getString(R.string.is_request_accepted), true);
rideInfoPrefEditor.putString(getString(R.string.driver_phone), remoteMessage.getData().get("DriverPhone"));
rideInfoPrefEditor.putString(getString(R.string.driver_lat), remoteMessage.getData().get("DriverLatitude"));
rideInfoPrefEditor.putString(getString(R.string.driver_lng), remoteMessage.getData().get("DriverLongitude"));
rideInfoPrefEditor.commit();
AwaitingDriver.requestAccepted(); // A static method in AwaitingDriver Activity
}
}
tutaj, AwaitingDriver.requestAccepted()
jest statyczną metodą AwaitingDriver
działalności. Wewnątrz samej aktywności AwaitingDriver
, która pokazuje okno dialogowe postępu informujące klienta o konieczności oczekiwania, oto, co robi metoda AwaitingDriver.requestAccepted()
.
public static void requestAccepted(){
try{
awaitingDriverRequesting.dismiss(); //ProgressDialog for telling user to wait
}catch (Exception e){
e.printStackTrace();
}
if (staticActivity != null){
staticActivity.new TaskFindSetValues().execute();
}
}
Tutaj staticActivity
jest statycznym obiektem AwaitingDriver
klasy działalności zadeklarowanej wewnątrz tej klasy. Ustalam jego wartość w metodach onResume
i . Znaczenie, jeśli aktywność jest z przodu, pokazując na ekranie, tylko wtedy wartość staticActivity
nie będzie null
. Oto metody onResume
i .
@Override
public void onResume(){
super.onResume();
staticActivity = this;
Boolean accepted = rideInfoPref.getBoolean(getString(R.string.is_request_accepted), false);
if (accepted){
new TaskFindSetValues().execute();
}
}
@Override
protected void onPause(){
super.onPause();
staticActivity = null;
}
Tutaj TaskFindSetValues
jest AsyncTask zdefiniowane wewnątrz AwaitingDriver
klasy aktywności. Oto kod dla TaskFindSetValues
public class TaskFindSetValues extends AsyncTask<String, Void, String>{
String phone;
String lat;
String lng;
@Override
protected void onPreExecute(){
SharedPreferences pref = getSharedPreferences(getString(R.string.rideInfoPref), MODE_PRIVATE);
phone = pref.getString(getString(R.string.driver_phone), "");
lat = pref.getString(getString(R.string.driver_lat), "");
lng = pref.getString(getString(R.string.driver_lng), "");
}
@Override
protected String doInBackground(String... arg0){
return null;
}
@Override
protected void onPostExecute(String returnValue){
awaitingDriverPhone.setText(phone); //setting values to the TextViews
awaitingDriverLat.setText(lat);
awaitingDriverLng.setText(lng);
}
}
Przejrzyj ten kod i powiedz mi o wad w ten sposób zamiast innych rozwiązań, jeśli można również wyjaśnić sugerowany sposób z tym samym przykład byłbym naprawdę wdzięczny .
jaka jest potrzeba wyrejestrowania? Aka, co się stanie, jeśli nie wyrejestrujesz się? –
Moja metoda onCreate w FirebaseMessagingService nigdy nie jest wywoływana. Każdy pomysł, dlaczego? – eskalera
zastąpiłeś metodę 'onCreate'? I sprawdź czy masz literówkę, nazwa metody to 'onCreate()', a nie 'OnCreate()' –