Como se comunicar entre o Serviço e a Atividade de Mensagens do Firebase? Android

Sei que a pergunta sobre como se comunicar entre um serviço e uma atividade foi respondida várias vezes, mas também quero que minha própria maneira de fazer isso seja revisada e saiba se é uma maneira aceitável e correta de fazer isso e quais são as desvantagens de como eu lidei com isso. Primeiro, declararei a declaração do problema com o máximo de detalhes possível.

Preciso criar um aplicativo em que estou usando o Firebase Messaging Service para me comunicar entre dois dispositivos. Digamos que é um sistema semelhante ao Uber. Um aplicativo é para o provedor de serviços (motorista) e outro para o cliente (passageiro). Quando o passageiro solicitar a viagem com sua localização, os motoristas em um determinado raio receberão uma notificação por push com uma carga útil usando o Firebase. O serviço Firebase está sendo executado em segundo plano. Quando o serviço recebe uma notificação por push,onMessageReceived O método é chamado. Um evento é gerado. Não estou usando o Firebase aqui para gerar notificações, mas na verdade transfiro dados entre dispositivos quando preciso usar odata campo de notificação por push do Firebase. Agora, o aplicativo de drivers receberá as coordenadas de onde o usuário deseja o carro na carga útil da notificação por push do Firebase. Eu posso simplesmente iniciar uma atividade com esses dados nos extras e mostrar ao motorista que uma solicitação foi recebida.

Agora, no lado do cliente, depois que o cliente envia a solicitação, ele é levado para a próxima atividade, onde está sendo mostrada uma espécie de tela de carregamento, pedindo para aguardar que um dos drivers aceite a solicitação. Quando um dos drivers aceitar a solicitação deste usuário, ele receberá uma notificação push do Firebase com as informações do driver designado na carga útil da notificação push. Novamente, o objetivo não é gerar notificações, mas transferir dados entre dispositivos.

Agora que você entendeu o caso de uso, passarei ao problema.

O problema surge quando o usuário envia a solicitação e passa para a próxima tela de espera, onde é exibida uma tela de carregamento solicitando que esperem enquanto a solicitação está aguardando para ser aceita por um dos drivers. Quando um driver aceita a solicitação, como eu disse, o usuário receberá uma notificação push do Firebase com as informações do driver na carga útil da notificação push. Como me comunico entre o serviço e a Atividade, para dizer à atividade para parar de exibir a tela de carregamento e preencher o TextView com os dados recebidos na carga útil da notificação por push.

Aqui está como eu lidei com isso. Suponha que eu tenha uma atividade com o nomeAwaitingDriver, que possui TextView para ser preenchido pelos dados do driver. Mas atualmente a atividade está mostrando uma tela de carregamento porque a solicitação ainda não foi aceita. Agora, o usuário recebe uma notificação por push com as informações do motorista no serviço em execução em segundo plano, não conectada à atividade de forma alguma. Aqui está o meuonMessageReceived método

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

Aqui,AwaitingDriver.requestAccepted() é um método estático deAwaitingDriver atividade. Dentro deAwaitingDriver própria atividade, que está mostrando uma caixa de diálogo de progresso para pedir ao cliente que aguarde, eis o métodoAwaitingDriver.requestAccepted() está fazendo.

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

AquistaticActivity é um objeto estático deAwaitingDriver classe de atividade declarada dentro desta classe. Estou definindo seu valor emonResume eonPause métodos. Ou seja, se a atividade estiver na frente, mostrando na tela, somente então o valor destaticActivity Não sejanull. Aqui está oonResume eonPause métodos.

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

Aqui,TaskFindSetValues é um AsyncTask definido dentroAwaitingDriver classe de atividade. Aqui está o código paraTaskFindSetValues

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

Por favor, reveja este código e conte-me as desvantagens de fazer isso em vez de outras soluções, e se você também pudesse explicar a maneira sugerida com o mesmo exemplo, ficaria muito grato.

questionAnswers(4)

yourAnswerToTheQuestion