Skocz do zawartości
Qzeer

Zatrzymanie i resetowanie drogomierza

    Rekomendowane odpowiedzi

    Qzeer

    Cześć. Mam pewien problem z aplikacją, która mierzy pokonany dystans. W głównym menu aplikacja ma 4 przyciski - jednym z nich jest przycisk "BIEGNIJ", który przechodzi do nowej aktywności Drogomierz. W tej aktywności mam 3 przyciski - start, stop i pauza. Po wciśnięciu START aplikacja prawidłowo mierzy dystans, problem jest z jej wstrzymanie. Chciałbym aby po wciśnięciu przycisku "pauza" aplikacja przestała mierzyć dystans. Drugim problemem jest zakończenie mierzenia, a później jego ponowne włączenie - gdy zakończe mierzenie dystansu, aplikacja wyświetla okno z informacjami na temat pokonanego dystansu, czasu, prędkości oraz przycisk powrotu do głównego menu. Gdy wróce do głównego menu, po czym  znów wejde w drogomierz i kliknę start to aplikacja zaczyna mierzyć dystans od tego dystansu przy którym wcześniej zakończyłem pomiar. Bardzo prosiłbym o pomoc. 

    Tutaj kod: 

     

    public class runActivity extends AppCompatActivity {
    
        public String speedString;
        public String distanceStr;
        private OdometerService odometer;
        private boolean bound = false;
        private double distance = 0.0;
        private double speed = 0.0;
    
        private int seconds = 0;
        private boolean running;
        public String time;
    
        private ServiceConnection connection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName componentName, IBinder binder) {
                OdometerService.OdometerBinder odometerBinder = (OdometerService.OdometerBinder) binder;
                odometer = odometerBinder.getOdometer();
                bound = true;
            }
    
            @Override
            public void onServiceDisconnected(ComponentName componentName) {
                bound = false;
            }
        };
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_run);
            watchMileage();
            runTimer();
    
    
        }
    
        private void watchMileage(){
            final TextView speedView = findViewById(R.id.speed_view);
            final TextView distanceView = findViewById(R.id.distance);
            final Handler handler = new Handler();
    
            handler.post(new Runnable() {
                @SuppressLint("DefaultLocale")
                @Override
                public void run() {
    
                    if(odometer != null){
    
                            distance = odometer.getDistance();
                            speed = odometer.getSpeed();
    
                    }
                    distanceStr = String.format("%1$,.3f km", distance);
                    distanceView.setText(distanceStr);
                    speedString = String.format("%1$,.3f km/h", speed);
                    speedView.setText(speedString);
                    handler.postDelayed(this, 1000);
    
                }
            });
        }
    
        void bindService(){
            if(bound)
                return;
            Intent intent = new Intent(this, OdometerService.class);
            bindService(intent, connection, Context.BIND_AUTO_CREATE);
            bound = true;
            distance = 0;
        }
    
        void unbindService(){
            if(!bound)
                return;
            Intent intent = new Intent(this, OdometerService.class);
            unbindService(connection);
            bound = false;
        }
    
        public void onClickStart(View view){
            bindService();
            running = true;
    
        }
    
        public void onClickStop(View view){
    
            if(bound) unbindService();
            running = false;
    
            Intent runResultIntent = new Intent(this, runResultActivity.class);
           runResultIntent.putExtra("time", time);
            runResultIntent.putExtra("distanceStr", distanceStr);
            runResultIntent.putExtra("seconds", seconds);
            runResultIntent.putExtra("distance", distance);
            startActivity(runResultIntent);
        }
    
        public void onClickPause(View view){
            unbindService(connection);
            bound = false;
            running = false;
    
        }
    
        private void runTimer(){
            final TextView timeView = findViewById(R.id.time_view);
    
            final Handler handler = new Handler();
            handler.post(new Runnable() {
                @SuppressLint("DefaultLocale")
                @Override
                public void run() {
    
                    int hours = seconds / 3600;
                    int minutes = (seconds%3600)/60;
                    int secs = seconds%60;
    
    
                    time = String.format("%d:%02d:%02d", hours, minutes, secs);
                    timeView.setText(time);
    
                    if(running){
                        seconds++;
                    }
    
                    handler.postDelayed(this, 1000);
                }
            });
    
        }
    
    
    }
    

     

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach

    OdometerService istnieje cały czas. Zachowuje dystans jaki obliczył. Rozwiązaniem Twoich obu problemów będzie wprowadzenie dwóch metod do OdometerService. Zakładam że jest to klasa stworzona przez Ciebie ;) Jedna z tych metod będzie zerować dystans - odometer.stop(), a druga będzie zapamiętywać dystans po kliknięciu na przycisk pauzy odometer.pause(). Jednak żebym mógł pomóc Ci je zaimplementować przydałby się kod klasy OdometerService.

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach
    Qzeer

    Tutaj kod klasy OdometerService

     

     

    public class OdometerService extends Service {
    
        private final IBinder binder = new OdometerBinder();
    
        private static double distanceInMeters;
        private static Location lastLocation = null;
        double currentSpeed;
    
        public class OdometerBinder extends Binder {
            OdometerService getOdometer() {
                return OdometerService.this;
            }
        }
    
    
        @Override
        public IBinder onBind(Intent intent) {
    
            return binder;
        }
    
        public void onCreate() {
            LocationListener listener = new LocationListener() {
                @Override
                public void onLocationChanged(Location location) {
    
                    if (lastLocation == null) {
                        lastLocation = location;
                    }
                    distanceInMeters += location.distanceTo(lastLocation);
                    lastLocation = location;
                    currentSpeed = location.getSpeed();
                }
    
                @Override
                public void onStatusChanged(String s, int i, Bundle bundle) {
    
                }
    
                @Override
                public void onProviderEnabled(String s) {
    
                }
    
                @Override
                public void onProviderDisabled(String s) {
    
                }
            };
    
            LocationManager locManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                // TODO: Consider    calling
                //    ActivityCompat#requestPermissions
                // here to request the missing permissions, and then overriding
                //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                //                                          int[] grantResults)
                // to handle the case where the user grants the permission. See the documentation
                // for ActivityCompat#requestPermissions for more details.
                return;
            }
            locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1, listener);
        }
    
        public double getDistance(){
            return this.distanceInMeters / 1000;
        }
    
        public double getSpeed(){
            return this.currentSpeed *(3.6);
        }
    
    
    }
    

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach

    Dodałem jednak 3 metody:
    - pause(), która ustawia location na null - dzięki czemu po pauzie nie jest brany pod uwagę dystans który przeszliśmy podczas pauzy.
    - stop(), robi podobną robotę jak pause(), ale zeruje jeszcze dystans
    - start(), uruchamia ponownie zczytywanie dystansu.

    public class OdometerService extends Service {
    
        private final IBinder binder = new OdometerBinder();
      
        private boolean stop = false;
    
        private static double distanceInMeters;
        private static Location lastLocation = null;
        double currentSpeed;
    
        public class OdometerBinder extends Binder {
            OdometerService getOdometer() {
                return OdometerService.this;
            }
        }
    
        public void pause() {
          stop = true;  
          lastLocation = null;
          
        }
      
        public void stop() {
          stop = true;
          lastLocation = null;
          distanceInMeters = 0.0;
        }
      
      // i jeszcze potrzebna metoda dodatkowa metoda start
      public void start() {
          stop = false;
      }
    
        @Override
        public IBinder onBind(Intent intent) {
    
            return binder;
        }
    
        public void onCreate() {
            LocationListener listener = new LocationListener() {
                @Override
                public void onLocationChanged(Location location) {
                  if(stop)
                    return;
                  
                    if (lastLocation == null) {
                        lastLocation = location;
                    }
                    distanceInMeters += location.distanceTo(lastLocation);
                    lastLocation = location;
                    currentSpeed = location.getSpeed();
                }
    
                @Override
                public void onStatusChanged(String s, int i, Bundle bundle) {
    
                }
    
                @Override
                public void onProviderEnabled(String s) {
    
                }
    
                @Override
                public void onProviderDisabled(String s) {
    
                }
            };
    
            LocationManager locManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                // TODO: Consider    calling
                //    ActivityCompat#requestPermissions
                // here to request the missing permissions, and then overriding
                //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                //                                          int[] grantResults)
                // to handle the case where the user grants the permission. See the documentation
                // for ActivityCompat#requestPermissions for more details.
                return;
            }
            locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1, listener);
        }
    
        public double getDistance(){
            return this.distanceInMeters / 1000;
        }
    
        public double getSpeed(){
            return this.currentSpeed *(3.6);
        }
    
    
    }
    • Piwko! 1

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach
    Qzeer

    A w jaki sposób odwołać się do tych metod w runActivity? 

     

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach
    8 godzin temu, Qzeer napisał:

    A w jaki sposób odwołać się do tych metod w runActivity? 

    Po prostu:

    odometer.pause();
    odometer.stop();
    odometer.start()

     

    • Piwko! 1

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach
    mmaciejow

    @Qzeer Zobacz na te dwa linki:

    https://myenv.net/blog/metody-komunikacji-miedzy-serwisem-a-aktywnoscia-w-androidzie/

    https://myenv.net/blog/zaawansowane-metody-komunikacji-miedzy-serwisem-a-aktywnoscia-w-androidzie/

    Znajdziesz tam informacje jakie masz mozliwości jeśli chodzi o komunikację między serwisem a aktywnością. 

    Tak jak wspomniał @Coders Lab serwis zapamiętuje tą wartość. Możesz to rozwiazać w ten sposób, że w aktywności z biegiem - metoda onStop() zabijasz usługę. A przy starcie aktywności uruchamiasz serwis. Plusem będzie to, że wpłynie to na wydajność i optymalizację :) 

     

    • Piwko! 1
    • Lubię to! 1

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach
    Qzeer

    @Coders Lab  Dziękuje bardzo za pomoc. Metoda stop i pause działa idelanie. Jedynie problem jest z metodą start bo gdy ją dodam to po naciśnięciu przycisku start aplikacja wyłącza się. Jednak gdy nie dodam tej metody to aplikacja działa prawidłowo tzn zatrzymuje mierzenie gdy jest pauza oraz zeruje pokonany dystans gdy jest stop. 

    @mmaciejow  Dzięki za podesłanie linków, na pewno się przydadzą :D 

    Edytowane przez Qzeer

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach

    Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

    Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

    Zarejestruj nowe konto

    Załóż nowe konto. To bardzo proste!

    Zarejestruj się

    Zaloguj się

    Posiadasz już konto? Zaloguj się poniżej.

    Zaloguj się

    • Ostatnio przeglądający   0 użytkowników

      Brak zarejestrowanych użytkowników przeglądających tę stronę.

    x