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.