2

I am implementing an Android app in Java using Android Studio. We are following the MVVM architecture with Jetpack Compose, and we have a navigation bar with various fragments, including a home fragment and others. In the home fragment, I have a map implemented using OsmDroid.

My problem is that after organizing project with homefragment.xml, HomeFragment.java, HomeViewModel.java, MainActivity.java, and MainActivity.xml, I tried to manage permission requests through the MainActivity and performed the necessary operations into the other classes. The application works, but when I move the map to a specific location and then i change the fragment using the navigation bar, returning to the map resets its value to the default position where my active location is.

To resolve this, I attempted to implement the appropriate corrections using the onSaveInstanceState(Bundle outState) and onCreate() methods. However, during debugging, I noticed that the code section in onCreate where savedInstanceState is not null is never reached, making my attempt seem futile.

This is my homefragment.java class, maybe im not getting how the relation between Bundle outState and Bundle savedInstanceState works:

package com.seaguard.ui.home;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;

import com.seaguard.databinding.FragmentHomeBinding;

import org.osmdroid.api.IGeoPoint;
import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapController;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider;
import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay;


public class HomeFragment extends Fragment {
    private FragmentHomeBinding binding;
    private MapView map;

    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        if(savedInstanceState == null) {
            System.out.println("BBB");
            HomeViewModel homeViewModel = new ViewModelProvider(requireActivity()).get(HomeViewModel.class);

            binding = FragmentHomeBinding.inflate(inflater, container, false);
            View root = binding.getRoot();

            // Map
            map = binding.map;
            map.setTileSource(TileSourceFactory.MAPNIK);
            map.setBuiltInZoomControls(false);
            map.setMultiTouchControls(true);

            MapController mapController = (MapController) map.getController();
            mapController.setCenter(new GeoPoint(41.8902, 12.4922)); // Rome
            mapController.setZoom(16);

            homeViewModel.setCallBack(() -> {
                //provider.addLocationSource(LocationManager.NETWORK_PROVIDER);
                MyLocationNewOverlay location = new MyLocationNewOverlay(new GpsMyLocationProvider(map.getContext()), map);
                location.enableMyLocation();
                map.getOverlays().add(location);

                location.runOnFirstFix(() -> {
                    requireActivity().runOnUiThread(() -> map.getController().animateTo(location.getMyLocation()));
                });
                return location;
            });
            if (homeViewModel.permissionsRequested()) homeViewModel.setLocation();
            return root;
        }else{

            System.out.println("AAAA");

            View root = binding.getRoot();

            double latitude = savedInstanceState.getDouble("latitude", 41.8902);
            double longitude = savedInstanceState.getDouble("longitude", 12.4922);
            int zoom_level = savedInstanceState.getInt("zoom_level", 16);
            float map_orientation = savedInstanceState.getFloat("map_orientation", 0);

            GeoPoint restoredCenter = new GeoPoint(latitude, longitude);

            map.getController().setCenter(restoredCenter);
            map.getController().setZoom(zoom_level);
            map.setMapOrientation(map_orientation);

            return root;
        }
    }


    @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);

            IGeoPoint center = map.getMapCenter();
            outState.putDouble("latitude", center.getLatitudeE6() / 1e6);
            outState.putDouble("longitude", center.getLongitudeE6() / 1e6);

            outState.putInt("zoom_level", map.getZoomLevel());

            outState.putFloat("map_orientation", map.getMapOrientation());

    }

}

Note that i used those println for debugging and it seems like AAA never gets printed in logcat so that code never gets executed

1 Answer 1

0

it is a different solution if you want one

I think for now you can try doing it by shared preferences eg:-

//to set data

 SharedPreferences data = getSharedPreferences("MapData", MODE_PRIVATE);
  SharedPreferences.Editor data_editor =data.edit();
  //putting double in string as it does not store double value
  data_editor.putString("latitude", String.valueOf(data1 / 1e6));
  data_editor.putString("longitude", String.valueOf(data2 / 1e6));
  data_editor.putInt("zoom_level", map.getZoomLevel());
  data_editor.putFloat("map_orientation", map.getMapOrientation());
  data_editor.apply();

//to get data

 SharedPreferences data = getSharedPreferences("MapData", MODE_PRIVATE);
    lat= Double.valueOf(data.getString("latitude","0.0"));
    lon= Double.valueOf(data.getString("longitude","0.0"));
    //do it for others too 

then load the map if you get data

be sure to reset the data each time you open the app

SharedPreferences data = getSharedPreferences("MapData", MODE_PRIVATE);
    SharedPreferences.Editor data_editor =data.edit();
    data_editor.clear();
    data_editor.commit();

other vise it will load the old data that was saved the last time

you can aslo clear the data when you are done with it

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.