6

Я знаю, что вопрос о том, как общаться между службой и деятельностью, ответил много раз, но я также хочу, чтобы мой собственный способ сделать это, чтобы его пересмотреть, и знать, является ли его приемлемым и правильным способом для этого и каковы недостатки того, как я справился с этим. Во-первых, я сформулирую заявление о проблеме как можно подробнее.Как взаимодействовать между службой обмена сообщениями Firebase и активностью? Android

Мне нужно создать приложение, в котором я использую службу сообщений Firebase для обмена данными между двумя устройствами. Скажем, его система, подобная Uber. Одно приложение предназначено для поставщика услуг (водителя) и для клиента (пассажира). Когда пассажир просит путешествовать с их местоположением, водители в определенном радиусе получат push-уведомление с полезной нагрузкой с использованием Firebase. Служба Firebase работает в фоновом режиме. Когда служба получает push-уведомление, вызывается метод onMessageReceived. Генерируется событие. Я не использую Firebase здесь для генерации уведомлений, но фактически передаю данные между устройствами, когда мне нужно использовать поле уведомлений Firebase data. Теперь приложение-драйвер получит координаты того, где пользователь хочет, чтобы автомобиль находился в полезной нагрузке Push-уведомления Firebase. Я могу просто начать работу с этими данными в дополнительных функциях и показать драйверу, что запрос получен.

Теперь, со стороны клиента, после того, как клиент отправил запрос, они переходят к следующему действию, где им показывают вид экрана загрузки, который говорит им ждать, пока один из драйверов примет их запрос. Когда один из драйверов принимает запрос этого пользователя, этот пользователь теперь получит уведомление Push-Firebase с информацией о назначенных драйверах в полезной нагрузке push-уведомления. Опять же, целью является не генерировать никаких уведомлений, а передавать данные между устройствами.

Теперь, когда вы понимаете прецедент, я перейду к проблеме.

Проблема возникает, когда пользователь отправляет запрос и переходит к следующему экрану ожидания, на котором показан экран загрузки, который говорит им ждать, пока запрос ожидает, чтобы его принял один из драйверов. Когда водитель принимает запрос, как я уже сказал, пользователь получит уведомление Push-Firebase с информацией водителя в полезной нагрузке push-уведомления. Как мне установить связь между сервисом и активностью, чтобы сообщить активности прекратить показ экрана загрузки и заполнить TextView данными, полученными в полезной нагрузке push-уведомления.

Вот как я справился с этим. Предположим, что у меня есть активность с именем AwaitingDriver, в котором TextView должен быть заполнен данными водителя. Но в настоящее время активность показывает экран загрузки, потому что запрос еще не принят. Теперь пользователь получает push-уведомление с информацией о драйвере в службе, работающей в фоновом режиме, и никак не связан с ней. Вот мой 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 
     }    
    } 

Здесь AwaitingDriver.requestAccepted() статический метод AwaitingDriver деятельности. Внутри самой операции AwaitingDriver, которая показывает диалог прогресса, чтобы сообщить клиенту ждать, вот что делает метод 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(); 
    } 
} 

Здесь staticActivity статический объект AwaitingDriver класса активности объявленной внутри этого класса. Я устанавливаю его значение в методах onResume и . Значение, если активность находится впереди, показывая на экране, только тогда значение staticActivity не будет null. Вот методы onResume и .

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

Здесь TaskFindSetValues является AsyncTask определена внутри AwaitingDriver класса активности. Вот код для 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); 
    } 
} 

Пожалуйста, ознакомьтесь этот код и скажите мне о недостатках делать это вместо других решений, и если вы могли бы также объяснить, предложенный способ с тем же примером я был бы очень благодарен ,

ответ

18

Почему вы используете AsyncTask? Не имеет смысла. В любом случае, если вы хотите общаться с Управлением, вы можете сделать это с помощью BroadcastReceiver.

public class MyFirebaseMessagingService extends FirebaseMessagingService{ 
    private LocalBroadcastManager broadcaster; 

    @Override 
    public void onCreate() { 
     broadcaster = LocalBroadcastManager.getInstance(this); 
    } 

    @Override 
    public void onMessageReceived(RemoteMessage remoteMessage) { 
     Intent intent = new Intent("MyData"); 
     intent.putExtra("phone", remoteMessage.getData().get("DriverPhone")); 
     intent.putExtra("lat", remoteMessage.getData().get("DriverLatitude")); 
     intent.putExtra("lng", remoteMessage.getData().get("DriverLongitude")); 
     broadcaster.sendBroadcast(intent); 
    } 
} 

и в вашей деятельности

@Override 
    protected void onStart() { 
     super.onStart(); 
     LocalBroadcastManager.getInstance(this).registerReceiver((mMessageReceiver), 
       new IntentFilter("MyData") 
     ); 
    } 

    @Override 
    protected void onStop() { 
     super.onStop(); 
     LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver); 
    } 

    private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      awaitingDriverRequesting.dismiss(); 
      awaitingDriverPhone.setText(intent.getExtras().getString("phone")); //setting values to the TextViews 
      awaitingDriverLat.setText(intent.getExtras().getDouble("lat")); 
      awaitingDriverLng.setText(intent.getExtras().getDouble("lng")); 
     } 
    }; 
+0

что нужно для регистрации? Ака, что произойдет, если вы не отмените регистрацию? –

+0

мой метод onCreate в FirebaseMessagingService никогда не вызывается. Любая идея почему? – eskalera

+0

Вы переопределили метод 'onCreate'? И проверьте, есть ли у вас опечатка, имя метода - 'onCreate()' not 'OnCreate()' –

2

В методе onMessageReceived вы можете отправить широковещательную передачу приложения, передав данные драйвера. Принятый метод запроса затем будет заменен приемником широковещательной передачи onReceive. Таким образом, нет необходимости писать в общие настройки или использовать aSyncTask, который в основном ничего не делает, поскольку метод doinbackground просто возвращает null. Вы используете только методы onPreExecute и onPostExecute, которые выполняются в основном потоке.

+0

Я использовал AsyncTask, потому что я не мог получить доступ к переменным-членам своей деятельности в и TextViews через статический метод 'requestAccepted()', но я мог бы через AsyncTask выполнен из static method –

0

Почему бы вам просто не создать намерение в методе onMessageReceived, перезапустить действие и передать данные драйвера в дополнительных?

+0

Потому что я не хочу, чтобы клиент видел перезапуск активности. В случае использования клиент фактически просматривает экран загрузки. –

+0

Хорошо, это имеет смысл. – Cuculus

Смежные вопросы