Capture in Loop the value of a variable of another Activity

Asked

Viewed 73 times

0

In my app, I have an activity called "GpsTrackerActivity" which is constantly calculating the distance travelled by the method onLocationChanged, of Interface LocationListener.

My problem is that I need to open a new activity and I want it, while active, to be able to capture in Loop the value of the public variable "distancia", who is in the activity "GpsTrackerActivity".
I’ve tried a cycle While infinity to constantly capture the value of the variable "distance", but this way the app blocks! Someone can help me?

public class GpsTrackerActivity extends AppCompatActivity implements OnMapReadyCallback, LocationListener {
public static double distancia;
....
}

Second Activity:

public class SegundaActivity extends AppCompatActivity {
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

while (true){
            double distancia = GpsTrackerActivity.distancia;
            Log.i("Tag", "Distância: " + distancia + " Km");
        }

}
....
}

1 answer

1


What you are trying to do, as far as I know, is not possible, as each Activity has its own context ( feature set and own classes), moreover, it is only possible to run one Activity at a time, so it is impossible to capture the events of a Activity A that is "closed" inside a Activity B that is open. So, if you want some Activity to capture the "location changed" event, it is up to you to "listen" and handle the changes in the location.

As in your case the two activities need to receive changes in location, you have two options:

  1. When getting the new location on GPSTrackerActivity, initiating the second Activity by passing the location obtained through a Bundle

    In this case, when obtaining the new location with the method onLocationChanged(Location location) in GPSTrackerActivity, you would do:

    @Override
    public void onLocationChanged(Location location) {
    
        // Calcule a sua distancia   
        // double distancia = ?     
    
        Bundle mBundle = new Bundle();
        mBundle.putDouble("distancia",distancia);
    
        Intent mIntent = new Intent(this, SegundaActivity.class)    
               mIntent.putExtras(mBundle);
    
        startActivity(mIntent);
    }
    

    And in the SegundaActivity you would take the distance passed in the method onCreate() using the following code

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        double distancia = getIntent().getExtras().getDouble("distancia");
    
        /* ... */
    }
    

    OBS.: Note that, in this case, your SegundaActivity only receives a single distance, which was obtained from the last location received by GPSTrackerActivity. This means that if your location changes while the SegundaActivity is open, it will not receive this new distance, because who receives and treats the distance is the GPSTrackerActivity. If you want her SegundaActivity constantly receive a new location as there are changes, you can use the second approach.

  2. Create a class " MeuLocationManager " who will be responsible for monitoring changes in the location and providing them to a "requester"

    In this case, you will transfer all the logic of tracking changes in location to the class " MeuLocationManager ". So every time a class wants to receive location change information, simply request the " MeuLocationManager " send her the obtained locations. It looks like this:

     public class MeuLocationManager implements LocationListener /*, etc. */ {
    
         // Classe que vai requisitar a localização
         private LocationListener requisitorLocalizacao;  
    
         /* Vamos implementar o padrão Singleton para evitar que 
            um novo LocationManager seja criado a cada vez que for
            necessário chamá-lo*/
    
         private static MeuLocationManager instance;
    
         private MeuLocationManager() {
    
         /* Implemente e/ou crie todos os métodos necessários 
            para obtenção de localização, como:
    
            Criação e inicialização do Google Services
            Callbacks para escutar a conexão com o Google Services, etc. */
         }
    
         public static MeuLocationManager getInstance(){
    
             if(instance == null){
                 return new MeuLocationManager();
             }else{
                 return instance;
             }
         }
    
        /* Método que será usado por outra classe para solicitar
         a localização */
        public void requestLocationUpdates(LocationListener requisitorLocalizacao){
    
            this.requisitorLocalizacao = requisitorLocalizacao;
        }
    
        /* Repassa a localização obtida para o requisitor da
        localização */
        @Override
        public void onLocationChanged(Location location){
    
             // Repassa a localização obtida para o requisitor da
             // localizacao
             requisitorLocalizacao.onLocationChanged(location);
        }
    }
    

    Now, any class that wants to receive changes in location, must implement the interface LocationListener and request the MeuLocationManager send it the new obtained locations. We will use as an example your class SegundaActivity. First, you must make her implement the interface LocationListener, then you will do the following in your method onCreate():

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        MeuLocationManager locationManager = MeuLocationManager.getInstance();
    
        // Solicita localização
        locationManager.requestLocationUpdates(this);
    }
    
    // No método `onLocationChanged` faça o que você quiser 
    // com a localização que foi recebida do MeuLocationManager
    @Override
    public void onLocationChanged(Location location) {
    
        /* ... */
    }
    

These are only two possible solutions, there are many others, such as using the library Reactive Location, which is the one I use in my projects :)

  • regmorais, thank you so much for your help, as your explanation was excellent. I will opt for the second approach.

  • regmorais, I just didn’t notice in the Meulocationmanager class the public configuration Static Meulocationlistener getInstance(){...}? When inserting it into the Class I get an error because of the name Meulocationlistener?

  • @Vitormendanha I’m sorry, I put the wrong name, the right is Meulocationmanager. I’ve already fixed the answer :)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.