当前位置: 首页 > 知识库问答 >
问题:

Android MapFragment,无法在地图上绘制

唐元凯
2023-03-14

我正在开发一个应用程序,它有一个应用程序功能,可以在谷歌地图上显示团队作为标记。

我可以把自己显示为移动时更新的标记

问题是,标记仅在我第一次转到MapFragment时显示。当我导航到另一个片段并返回到地图时,我看到一个没有标记的空地图

尝试#3,请查看以前实现的历史记录,这些实现略有不同:

我的片段布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
    <fragment xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/incident_map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        />
    <ProgressBar
        android:id="@+id/incident_map_progress_bar"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="visible"/>
    <!--<com.google.android.gms.maps.MapView
        android:id="@+id/incident_map"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />-->

</RelativeLayout>

我的IncidentMapFragment代码,现在根据用户反馈进行更新。更新很少。请参阅下面的更新代码,而不是使用onActivityCreated()打开onResume()im,也不是使用onSaveInstanceState()打开onPause()im

    package com.xyz.fragments;

//i did not include imports 
//Based  on https://developers.google.com/maps/documentation/android-sdk/map-with-marker
public class IncidentMapFragment extends Fragment implements OnMapReadyCallback {

    public static final String TAG = "IncidentMapFragment";
    private static  IncidentMapFragment incidentMapFragment = null;
    public static IncidentMapFragment instance() {
        if (incidentMapFragment==null)
        {
            incidentMapFragment =   new IncidentMapFragment();
        }
        return incidentMapFragment;
    }

    private MapView mapView;
    private static GoogleMap map;
    private ProgressBar progressBar;
    private SupportMapFragment mapFragment;
    public static final int UPDATE_MY_CURRENT_LOCATION = 0;
    public static final int UPDATE_MY_TEAMS_CURRENT_LOCATIONS = 1;
    public static final int UPDATE_ALL_TEAMS_CURRENT_LOCATIONS = 2;
    public static final int UPDATE_ALL_LOCATION_BASED_EVENTS = 3;
    private static Context context;
    private int MY_DEFINED_ACCESS_COARSE_LOCATION_CALLBACK_RESULT = 1;
    private int MY_DEFINED_ACCESS_FINE_LOCATION_CALLBACK_RESULT = 2;
    boolean flagCoarseLocation = false;
    boolean flagFineLocation = false;
    private WamsUnitVehicleUnitRelationshipDao vehicleUnitRelationshipDao = new WamsUnitVehicleUnitRelationshipDaoImpl();
    private static WamsUnitVehicleUnitRelationship newVehicleUnitRelationship = null;
    private static CameraPosition cp;
    private static Bundle markersBundle = new Bundle();
    private static Bundle saveStateBundle = new Bundle();
    private boolean createdStateInDestroyView = false;
    private static final String SAVED_BUNDLE_TAG = "IncidentMapFragment_SAVE_STATE";

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.incident_map_fragment, container, false);
        context = rootView.getContext();
        progressBar = rootView.findViewById(R.id.incident_map_progress_bar);
        try {

            FragmentManager fm = getActivity().getSupportFragmentManager();
            if (savedInstanceState == null) {
                mapFragment = SupportMapFragment.newInstance();
                fm.beginTransaction().replace(R.id.incident_map, mapFragment,TAG).commit();
            }
            else {
                mapFragment = (SupportMapFragment) fm
                        .findFragmentByTag(TAG);
            }

            if (savedInstanceState!=null) {
                saveStateBundle = savedInstanceState.getBundle(SAVED_BUNDLE_TAG);
                //restore camera
                cp = saveStateBundle.getParcelable("cp");
                //restore bundle of markers
                markersBundle = saveStateBundle.getParcelable("markersBundle");

                if (cp!=null && markersBundle!=null)
                {
                    reDrawMarkers(markersBundle);
                }
            }



        } catch (Exception exc) {
            Log.e(TAG, exc.getMessage());
            exc.printStackTrace();
        }
        return rootView;
    }


    @Override
    public void onActivityCreated(Bundle bundle) {
        super.onActivityCreated(bundle);
        Log.i(TAG,"onActivityCreated()");
        newVehicleUnitRelationship = vehicleUnitRelationshipDao.getWamsUnitVehicleUnitRelationship(NgfrApp.getInstance().getUniqueDeviceId());


        if (mapFragment!=null) {
            mapFragment.getMapAsync(this);
        }

    }

    @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
        Log.i(TAG,"onSaveInstanceState()");
        outState.putBundle(SAVED_BUNDLE_TAG, saveState());
        createdStateInDestroyView = false;
        super.onSaveInstanceState(outState);
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        saveStateBundle = saveState();
        createdStateInDestroyView = true;
        cp = null;
        markersBundle = null;

    }

    private Bundle saveState() {
        Bundle state = new Bundle();
        state.putParcelable("cp", cp);
        state.putParcelable("markersBundle", markersBundle);
        return state;
    }

    /*Handler used by outside class such as MqttBroker.
    1) UPDATE_MY_CURRENT_LOCATION. When my location service send a update location(lat,long) call updateMarkersOnMap() which creates a new AsyncTask to update teh display
    2) UPDATE_MY_TEAMS_CURRENT_LOCATIONS. When the MQTT dservice gets new location(lat,long) call updateMarkersOnMap() which creates a new AsyncTask to update teh display
    3) UPDATE_ALL_TEAMS_CURRENT_LOCATIONS, not implemented.
     */
    public static final Handler updateIncidentMap = new Handler(Looper.getMainLooper()) {
        public void handleMessage(Message msg) {
            //if the context is null then the MapFragment & GoogleMap objects are NOT instantiated and updating the maps non-existant UI will cause exceptions, NPE, and crashes!
            if (context != null) {
                Location myCurrentLocation = null;
                final int what = msg.what;
                switch (what) {
                    case UPDATE_MY_CURRENT_LOCATION:
                        Log.i(TAG,"UPDATE_MY_CURRENT_LOCATION");
                        myCurrentLocation = (Location) msg.obj;
                        if (map != null) {
                            updateMarkersOnMap(map,markersBundle, myCurrentLocation.getLatitude(),myCurrentLocation.getLongitude(),newVehicleUnitRelationship.getWamsId(), newVehicleUnitRelationship.getVehicleUnitId());
                        }

                        break;
                    case UPDATE_MY_TEAMS_CURRENT_LOCATIONS:
                        Log.i(TAG,"UPDATE_MY_TEAMS_CURRENT_LOCATIONS");
                        if (map != null) {
                            WamsLocationMarker wamsLocationMarker = (WamsLocationMarker) msg.obj;
                            updateMarkersOnMap(map, markersBundle,wamsLocationMarker.getLat(),wamsLocationMarker.getLon(), wamsLocationMarker.getClientId(), wamsLocationMarker.getVehicleId());
                            //mock team
                            mockTeam(map,markersBundle,  wamsLocationMarker.getLat(),wamsLocationMarker.getLon());
                        }
                        break;
                    case UPDATE_ALL_TEAMS_CURRENT_LOCATIONS:
                        break;
                    default:
                        break;
                }
            } //end if context  is NOt null
        } //end handleMessage
    };

    /*I added the @SuppressLint("MissingPermission") because we are handling this in permissionHelper(getActivity()),
    and the IDE is too naive to know*/
    @SuppressLint("MissingPermission")
    @Override
    public void onMapReady(GoogleMap googleMap) {
        Log.i(TAG, "onMapReady()");
        try {

            //remove progress bar
            progressBar.setVisibility(GONE);
            //initially zoom in my location
            map = googleMap;
            if (permissionHelper(getActivity()))
            {
                map.setMyLocationEnabled(true);
                map.getUiSettings().setZoomControlsEnabled(true);
                map.getUiSettings().setCompassEnabled(true);
            }
            if (cp != null) {
                map.moveCamera(CameraUpdateFactory.newCameraPosition(cp));
                cp = null;
            }

            reDrawMarkers(markersBundle);

        }
        catch (NullPointerException exc)
        {
            exc.printStackTrace();
        }
    }


    private static void updateMarkersOnMap(GoogleMap map,Bundle bundle, double lat,double log, String id, String vehicleId) {

        final GoogleMap _map = map;
        final double _lat = lat;
        final double _log = log;
        final String _id = id;
        final String _vehicleId = vehicleId;

        new AsyncTask < Void, Void, WamsLocationMarker > () {

            boolean update = false;
            @Override
            protected WamsLocationMarker doInBackground(Void...voids) {

                Marker marker = null;
                WamsLocationMarker wamsLocationMarker=null;
                try {
                    Log.i(TAG,"async map: "+map);
                    if (_map != null && bundle!=null)
                    {
                        Log.i(TAG,_map.toString());
                        //if the wamsLocationMarker exists,  then UPDATE
                        if (bundle.containsKey(_id)) {

                            Log.i(TAG,"markersBundle.containsKey(_id): "+ bundle.containsKey(_id));
                            Log.i(TAG,"update true");
                            //get from hashmap
                            wamsLocationMarker = (WamsLocationMarker)bundle.get(_id);
                            update = true;
                        } else {
                            //add to map
                            //if the ids are equal then this is YOU
                            wamsLocationMarker = new WamsLocationMarkerFactory().createWamsLocationMarker(_id, _vehicleId, _lat, _log);
                            Log.i(TAG,"WamsLocationMarker");
                            Log.i(TAG,"update false");
                        }
                    } else {

                        Log.e(TAG, " updateMarkersOnMap() map is " + _map);
                    }

                }
                catch (NullPointerException exc)
                {
                    exc.printStackTrace();
                }
                return wamsLocationMarker;
            }

            @Override
            protected void onPostExecute(WamsLocationMarker wamsLocationMarker) {
                super.onPostExecute(wamsLocationMarker);
                try {
                    if (wamsLocationMarker != null) {
                        Log.i(TAG,"onPostExecute() update:"+update+",wamsLocationMarker:"+wamsLocationMarker);

                        if (update) {

                            Log.i(TAG,"onPostExecute() update:"+update);

                            //UPDATE wth new lat & long if the markers coordinates have change, else dont redraw, beacuse the draw causes a refresh affect & its also a waste computationally
                            if (wamsLocationMarker.getMarker().getPosition().latitude != _lat && wamsLocationMarker.getMarker().getPosition().longitude != _log) {

                                LatLng latLng = new LatLng(_lat, _log);
                                //UPDATE THE MARKER POSITION
                                wamsLocationMarker.getMarker().setPosition(latLng);
                            }

                        } else {
                            //ADD A NEW MARKER
                            Marker marker = _map.addMarker(wamsLocationMarker.getMakerOptions());
                            Log.i(TAG,"ASYNC MARKER:"+marker.getId());
                            wamsLocationMarker.setMarker(marker);
                            markersBundle.remove(wamsLocationMarker.getClientId());
                            markersBundle.putParcelable(wamsLocationMarker.getClientId(), wamsLocationMarker);
                        }
                    }
                }
                catch (NullPointerException exc)
                {
                    exc.printStackTrace();
                }

            }
        }.execute();

    }


      public void reDrawMarkers(Bundle bundle) {
    Log.i(TAG,"reDrawMarkers()");
    if (bundle!=null) {
        Set<String> keys = bundle.keySet();
        WamsLocationMarker wamsLocationMarker = null;
        for (String k : keys) {
            Log.i(TAG, "key:" + k);
            wamsLocationMarker = (WamsLocationMarker) bundle.getParcelable(k);
            updateMarkersOnMap(map, bundle, wamsLocationMarker.getLat(), wamsLocationMarker.getLon(), wamsLocationMarker.getClientId(), wamsLocationMarker.getVehicleId());
        }
    }
}


    //Just for test - Im mocking some there points to represent other teams mates on the map, this is just for testing
    private static void mockTeam(GoogleMap map, Bundle bundle, double _lat, double _log) {

        updateMarkersOnMap(map,bundle, _lat+0.001, _log , "mock111111111", newVehicleUnitRelationship.getVehicleUnitId());


        updateMarkersOnMap(map,bundle,_lat, _log+0.001 ,"mock222222222", newVehicleUnitRelationship.getVehicleUnitId());


        updateMarkersOnMap(map,bundle, _lat-0.001, _log,"mock33333333", newVehicleUnitRelationship.getVehicleUnitId());

        updateMarkersOnMap(map,bundle, _lat, _log-0.001,"mock444444444", newVehicleUnitRelationship.getVehicleUnitId());


    }

    //Ask the user if  required & attempt to grant required location services
    private boolean permissionHelper(Activity activity) {

        String permission = Manifest.permission.ACCESS_COARSE_LOCATION;
        int res = getContext().checkCallingPermission(permission);
        //if the required coarse & fine permissions are granted then return true else proceed to get the permissions
        if (res == PackageManager.PERMISSION_GRANTED) {
            Log.i(TAG, "ACCESS_COARSE_LOCATION GRANTED");

            permission = Manifest.permission.ACCESS_FINE_LOCATION;
            res = getContext().checkCallingPermission(permission);
            if (res == PackageManager.PERMISSION_GRANTED) {
                Log.i(TAG, "ACCESS_FINE_LOCATION GRANTED");
                flagFineLocation = true;
            } else {
                Log.i(TAG, "ACCESS_FINE_LOCATION NOT GRANTED");
            }

            flagCoarseLocation = true;
        }
        //prompt user for COARSE location permission. If the user cancel then display toast & navigate back
        if (!flagCoarseLocation) {

            if (ActivityCompat.shouldShowRequestPermissionRationale(activity,
                    Manifest.permission.ACCESS_COARSE_LOCATION)) {

                dialogForCoarsePermission();

            } else {
                ActivityCompat.requestPermissions(activity,
                        new String[] {
                                Manifest.permission.ACCESS_COARSE_LOCATION
                        },
                        MY_DEFINED_ACCESS_COARSE_LOCATION_CALLBACK_RESULT);
                flagCoarseLocation = true;

            }
        }
        //prompt user for FINE location permission. If the user cancel then display toast & navigate back
        if (!flagFineLocation) {




            if (ActivityCompat.shouldShowRequestPermissionRationale(activity,
                    Manifest.permission.ACCESS_FINE_LOCATION)) {

                dialogForFinePermission();

            } else {
                ActivityCompat.requestPermissions(activity,
                        new String[] {
                                Manifest.permission.ACCESS_COARSE_LOCATION
                        },
                        MY_DEFINED_ACCESS_FINE_LOCATION_CALLBACK_RESULT);
                flagFineLocation = true;


            }
        }

        if (!flagCoarseLocation)
        {
            Log.i(TAG, "ACCESS_COARSE_LOCATION NOT GRANTED");
        }
        else
        {

            Log.i(TAG, "ACCESS_COARSE_LOCATION GRANTED");
        }
        if (!flagFineLocation)
        {
            Log.i(TAG, "ACCESS_FINE_LOCATION NOT GRANTED");
        }
        else
        {
            Log.i(TAG, "ACCESS_FINE_LOCATION GRANTED");
        }

        return (flagCoarseLocation && flagFineLocation);
    }

    private void dialogForCoarsePermission() {
        DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                switch (which) {
                    case DialogInterface.BUTTON_POSITIVE:
                        //Yes button clicked
                        ActivityCompat.requestPermissions(getActivity(),
                                new String[] {
                                        Manifest.permission.ACCESS_COARSE_LOCATION
                                },
                                MY_DEFINED_ACCESS_COARSE_LOCATION_CALLBACK_RESULT);
                        break;

                    case DialogInterface.BUTTON_NEGATIVE:
                        //No button clicked
                        break;
                }
            }
        };

        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setMessage("The map requires coarse location permission.Please it by pressing Yes. ").setPositiveButton("Yes", dialogClickListener)
                .setNegativeButton("No", dialogClickListener).show();
    }

    private void dialogForFinePermission() {
        DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                switch (which) {
                    case DialogInterface.BUTTON_POSITIVE:
                        //Yes button clicked
                        ActivityCompat.requestPermissions(getActivity(),
                                new String[] {
                                        Manifest.permission.ACCESS_FINE_LOCATION
                                },
                                MY_DEFINED_ACCESS_FINE_LOCATION_CALLBACK_RESULT);
                        break;

                    case DialogInterface.BUTTON_NEGATIVE:
                        //No button clicked
                        break;
                }
            }
        };

        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setMessage("The map ALSO requires fine location permission.Please it by pressing Yes. ").setPositiveButton("Yes", dialogClickListener)
                .setNegativeButton("No", dialogClickListener).show();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        Log.i(TAG, "onRequestPermissionsResult() request code:" + requestCode); // Log printed
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == MY_DEFINED_ACCESS_COARSE_LOCATION_CALLBACK_RESULT) {
            flagCoarseLocation = true;
            Toast.makeText(context, "Coarse location permission granted.", Toast.LENGTH_SHORT).show();

        }
        if (requestCode == MY_DEFINED_ACCESS_FINE_LOCATION_CALLBACK_RESULT) {
            flagFineLocation = true;
            Toast.makeText(context, "Fine location permission granted.", Toast.LENGTH_SHORT).show();
        }

    }
}

我提供了GUI

我第一次导航到片段。一切正常,您可以看到“转到我的位置”按钮

现在,当我导航到名为“服务”的第一个片段时,或者如果将应用程序留在后台一段时间,问题就会出现。我再也看不到标记了

08-16 08:06:03.358 1314-1314/com.xyz I/IncidentMapFragment: onSaveInstanceState()

08-16 08:06:03.836 1314-1314/com.xyz I/IncidentMapFragment: reDrawMarkers()
    key:015140000100161
    key:mock33333333
    key:mock444444444
    key:mock111111111
    key:mock222222222

08-16 08:06:03.836 1314-1340/com.xyz I/IncidentMapFragment: async map: com.google.android.gms.maps.GoogleMap@1e72e3b
    com.google.android.gms.maps.GoogleMap@1e72e3b
    markersBundle.containsKey(_id): true
    update true
    async map: com.google.android.gms.maps.GoogleMap@1e72e3b
    com.google.android.gms.maps.GoogleMap@1e72e3b
    markersBundle.containsKey(_id): true
    update true
    async map: com.google.android.gms.maps.GoogleMap@1e72e3b
    com.google.android.gms.maps.GoogleMap@1e72e3b
    markersBundle.containsKey(_id): true
    update true
    async map: com.google.android.gms.maps.GoogleMap@1e72e3b
    com.google.android.gms.maps.GoogleMap@1e72e3b
    markersBundle.containsKey(_id): true
    update true
    async map: com.google.android.gms.maps.GoogleMap@1e72e3b
    com.google.android.gms.maps.GoogleMap@1e72e3b
    markersBundle.containsKey(_id): true
    update true

08-16 08:06:03.837 1314-1314/com.xyz I/IncidentMapFragment: onActivityCreated()

08-16 08:06:03.851 1314-1314/com.xyz I/IncidentMapFragment: onPostExecute() update:true,wamsLocationMarker:com.xyz.mapping.WamsLocationMarker@19b04df
    onPostExecute() update:true
    onPostExecute() update:true,wamsLocationMarker:com.xyz.mapping.WamsLocationMarker@47c13e2
    onPostExecute() update:true
    onPostExecute() update:true,wamsLocationMarker:com.xyz.mapping.WamsLocationMarker@6b22ea9
    onPostExecute() update:true
    onPostExecute() update:true,wamsLocationMarker:com.xyz.mapping.WamsLocationMarker@e387818

08-16 08:06:03.852 1314-1314/com.xyz I/IncidentMapFragment: onPostExecute() update:true
    onPostExecute() update:true,wamsLocationMarker:com.xyz.mapping.WamsLocationMarker@dab0d7
    onPostExecute() update:true
    onMapReady()
    ACCESS_COARSE_LOCATION GRANTED
    ACCESS_FINE_LOCATION GRANTED

08-16 08:06:03.853 1314-1314/com.xyz I/IncidentMapFragment: reDrawMarkers()
08-16 08:06:03.854 1314-1314/com.xyz I/IncidentMapFragment: key:015140000100161
    key:mock33333333
    key:mock444444444
    key:mock111111111
    key:mock222222222

08-16 08:06:03.854 1314-1338/com.xyz I/IncidentMapFragment: async map: com.google.android.gms.maps.GoogleMap@b7d1933
    com.google.android.gms.maps.GoogleMap@b7d1933
    markersBundle.containsKey(_id): true
    update true
    async map: com.google.android.gms.maps.GoogleMap@b7d1933
    com.google.android.gms.maps.GoogleMap@b7d1933
    markersBundle.containsKey(_id): true
    update true
    async map: com.google.android.gms.maps.GoogleMap@b7d1933
    com.google.android.gms.maps.GoogleMap@b7d1933
    markersBundle.containsKey(_id): true
    update true
    async map: com.google.android.gms.maps.GoogleMap@b7d1933
    com.google.android.gms.maps.GoogleMap@b7d1933
    markersBundle.containsKey(_id): true
    update true
    async map: com.google.android.gms.maps.GoogleMap@b7d1933
    com.google.android.gms.maps.GoogleMap@b7d1933
    markersBundle.containsKey(_id): true
    update true

08-16 08:06:03.865 1314-1314/com.xyz I/IncidentMapFragment: onPostExecute() update:true,wamsLocationMarker:com.xyz.mapping.WamsLocationMarker@19b04df
    onPostExecute() update:true
    onPostExecute() update:true,wamsLocationMarker:com.xyz.mapping.WamsLocationMarker@47c13e2
    onPostExecute() update:true
    onPostExecute() update:true,wamsLocationMarker:com.xyz.mapping.WamsLocationMarker@6b22ea9
    onPostExecute() update:true
    onPostExecute() update:true,wamsLocationMarker:com.xyz.mapping.WamsLocationMarker@e387818
    onPostExecute() update:true
    onPostExecute() update:true,wamsLocationMarker:com.xyz.mapping.WamsLocationMarker@dab0d7
    onPostExecute() update:true

谢谢

共有3个答案

连厉刚
2023-03-14

假设你给的代码是正确的,用这个替换你的代码。试试看,我做了一些修改

package com.xyz.fragments;

//I didnt not include imports in order to have a smaller post on Stackoverflow

//Based  on https://developers.google.com/maps/documentation/android-sdk/map-with-marker
public class IncidentMapFragment extends Fragment implements OnMapReadyCallback {

    public static final String TAG = "IncidentMapFragment";
    private static  IncidentMapFragment incidentMapFragment = null;
    public static IncidentMapFragment instance() {
        if (incidentMapFragment==null)
        {
            incidentMapFragment =   new IncidentMapFragment();
        }
        return incidentMapFragment;
    }

    private MapView mapView;
    private static GoogleMap map;
    private ProgressBar progressBar;
    private SupportMapFragment mapFragment;
    public static final int UPDATE_MY_CURRENT_LOCATION = 0;
    public static final int UPDATE_MY_TEAMS_CURRENT_LOCATIONS = 1;
    public static final int UPDATE_ALL_TEAMS_CURRENT_LOCATIONS = 2;
    public static final int UPDATE_ALL_LOCATION_BASED_EVENTS = 3;
    private static Context context;
    private int MY_DEFINED_ACCESS_COARSE_LOCATION_CALLBACK_RESULT = 1;
    private int MY_DEFINED_ACCESS_FINE_LOCATION_CALLBACK_RESULT = 2;
    boolean flagCoarseLocation = false;
    boolean flagFineLocation = false;
    private static CameraPosition cp;
    private WamsUnitVehicleUnitRelationshipDao vehicleUnitRelationshipDao = new WamsUnitVehicleUnitRelationshipDaoImpl();
    private static WamsUnitVehicleUnitRelationship newVehicleUnitRelationship = null;
    private static Bundle bundleOfMarkers = new Bundle();


    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.incident_map_fragment, container, false);
        context = rootView.getContext();
        Bundle bundleOfMarkers = new Bundle();
        progressBar = rootView.findViewById(R.id.incident_map_progress_bar);
        try {

            FragmentManager fm = getActivity().getSupportFragmentManager();
            mapFragment = (SupportMapFragment) fm.findFragmentById(R.id.incident_map);
            if (mapFragment == null) {
                mapFragment = SupportMapFragment.newInstance();
                fm.beginTransaction().replace(R.id.incident_map, mapFragment).commit();
            }

        } catch (Exception exc) {
            Log.e(TAG, exc.getMessage());
            exc.printStackTrace();
        }
        return rootView;
    }


    @Override
    public void onActivityCreated(Bundle bundle) {
        super.onActivityCreated(bundle);
        Log.i(TAG,"onActivityCreated()");
        newVehicleUnitRelationship = vehicleUnitRelationshipDao.getWamsUnitVehicleUnitRelationship(NgfrApp.getInstance().getUniqueDeviceId());
        if (bundle!=null) {
            bundleOfMarkers = bundle.getBundle("bundleOfMarkers");
            cp = bundle.getParcelable("cp");
        }
        if (mapFragment!=null) {
            mapFragment.getMapAsync(this);
        }

    }

    /*Handler used by outside class such as MqttBroker.
    1) UPDATE_MY_CURRENT_LOCATION. When my location service send a update location(lat,long) call updateMarkersOnMap() which creates a new AsyncTask to update teh display
    2) UPDATE_MY_TEAMS_CURRENT_LOCATIONS. When the MQTT dservice gets new location(lat,long) call updateMarkersOnMap() which creates a new AsyncTask to update teh display
    3) UPDATE_ALL_TEAMS_CURRENT_LOCATIONS, not implemented.
     */
    public static final Handler updateIncidentMap = new Handler(Looper.getMainLooper()) {
        public void handleMessage(Message msg) {
            //if the context is null then the MapFragment & GoogleMap objects are NOT instantiated and updating the maps non-existant UI will cause exceptions, NPE, and crashes!
            if (context != null) {
                Location myCurrentLocation = null;
                final int what = msg.what;
                switch (what) {
                    case UPDATE_MY_CURRENT_LOCATION:
                        Log.i(TAG,"UPDATE_MY_CURRENT_LOCATION");
                        myCurrentLocation = (Location) msg.obj;
                        if (map != null) {
                            updateMarkersOnMap(map, myCurrentLocation.getLatitude(),myCurrentLocation.getLongitude(),newVehicleUnitRelationship.getWamsId(), newVehicleUnitRelationship.getVehicleUnitId());
                        }

                        break;
                    case UPDATE_MY_TEAMS_CURRENT_LOCATIONS:
                        Log.i(TAG,"UPDATE_MY_TEAMS_CURRENT_LOCATIONS");
                        if (map != null) {
                            WamsLocationMarker wamsLocationMarker = (WamsLocationMarker) msg.obj;
                            updateMarkersOnMap(map, wamsLocationMarker.getLat(),wamsLocationMarker.getLon(), wamsLocationMarker.getClientId(), wamsLocationMarker.getVehicleId());
                            //mock team
                            mockTeam(map, wamsLocationMarker.getLat(),wamsLocationMarker.getLon());
                        }
                        break;
                    case UPDATE_ALL_TEAMS_CURRENT_LOCATIONS:
                        break;
                    default:
                        break;
                }
            } //end if context  is NOt null
        } //end handleMessage
    };

    /*I added the @SuppressLint("MissingPermission") because we are handling this in permissionHelper(getActivity()),
    and the IDE is too naive to know*/
    @SuppressLint("MissingPermission")
    @Override
    public void onMapReady(GoogleMap googleMap) {
        Log.i(TAG, "onMapReady()");
        try {

            //remove progress bar
            progressBar.setVisibility(GONE);
            //initially zoom in my location
            map = googleMap;
            if (permissionHelper(getActivity()))
            {
                map.setMyLocationEnabled(true);
                map.getUiSettings().setZoomControlsEnabled(true);
                map.getUiSettings().setCompassEnabled(true);
            }
            if (cp != null) {
                map.moveCamera(CameraUpdateFactory.newCameraPosition(cp));
                cp = null;
            }

            myResume();

        }
        catch (NullPointerException exc)
        {
            exc.printStackTrace();
        }
    }


    private static void updateMarkersOnMap(GoogleMap map,double lat,double log, String id, String vehicleId) {

        final GoogleMap _map = map;
        final double _lat = lat;
        final double _log = log;
        final String _id = id;
        final String _vehicleId = vehicleId;

        new AsyncTask < Void, Void, WamsLocationMarker > () {

            boolean update = false;
            @Override
            protected WamsLocationMarker doInBackground(Void...voids) {

                Marker marker = null;
                WamsLocationMarker wamsLocationMarker=null;
                try {
                    Log.i(TAG,"async map: "+map);
                    if (_map != null)
                    {
                        Log.i(TAG,_map.toString());
                        //if the wamsLocationMarker exists,  then UPDATE
                        if (bundleOfMarkers.containsKey(_id)) {

                            Log.i(TAG,"bundleOfMarkers.containsKey(_id): "+bundleOfMarkers.containsKey(_id));
                            Log.i(TAG,"update true");
                            //get from hashmap
                            wamsLocationMarker = (WamsLocationMarker)bundleOfMarkers.get(_id);
                            update = true;
                        } else {
                            //add to map
                            //if the ids are equal then this is YOU
                            wamsLocationMarker = new WamsLocationMarkerFactory().createWamsLocationMarker(_id, _vehicleId, _lat, _log);
                            Log.i(TAG,"WamsLocationMarker");
                            Log.i(TAG,"update false");
                        }
                    } else {

                        Log.e(TAG, " updateMarkersOnMap() map is " + _map);
                    }

                }
                catch (NullPointerException exc)
                {
                    exc.printStackTrace();
                }
                return wamsLocationMarker;
            }

            @Override
            protected void onPostExecute(WamsLocationMarker wamsLocationMarker) {
                super.onPostExecute(wamsLocationMarker);
                try {
                    if (wamsLocationMarker != null) {
                        Log.i(TAG,"onPostExecute() update:"+update+",wamsLocationMarker:"+wamsLocationMarker);

                        if (update) {

                            Log.i(TAG,"onPostExecute() update:"+update);

                            //UPDATE wth new lat & long if the markers coordinates have change, else dont redraw, beacuse the draw causes a refresh affect & its also a waste computationally
                            if (wamsLocationMarker.getMarker().getPosition().latitude != _lat && wamsLocationMarker.getMarker().getPosition().longitude != _log) {

                                LatLng latLng = new LatLng(_lat, _log);
                                //UPDATE THE MARKER POSITION
                                wamsLocationMarker.getMarker().setPosition(latLng);
                            }

                        } else {
                            //ADD A NEW MARKER
                            Marker marker = _map.addMarker(wamsLocationMarker.getMakerOptions());
                            Log.i(TAG,"ASYNC MARKER:"+marker.getId());
                            wamsLocationMarker.setMarker(marker);
                            bundleOfMarkers.remove(wamsLocationMarker.getClientId());
                            bundleOfMarkers.putParcelable(wamsLocationMarker.getClientId(), wamsLocationMarker);
                        }
                    }
                }
                catch (NullPointerException exc)
                {
                    exc.printStackTrace();
                }

            }
        }.execute();

    }

    /*I also tried using onSaveInstanceState & onViewStateRestored. I saved the markers on map in Bundle & put them in parceable.
    However I was unable to redraw the map*/

    @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        Log.i(TAG,"onSaveInstanceState()");
        myPause();
        outState.putBundle("bundleOfMarkers", bundleOfMarkers);
        outState.putParcelable("cp",cp); 
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        Log.i(TAG,"onRestoreInstanceState()");
        super.onRestoreInstanceState(savedInstanceState);
        bundleOfMarkers = savedInstanceState.getBundle("bundleOfMarkers");
        myResume();
    }
       /*
    @Override
    public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
        Log.i(TAG,"onViewStateRestored(),savedInstanceState:"+savedInstanceState);
        super.onViewStateRestored(savedInstanceState);

    }*/


   /* @Override

    public void onResume() {
        super.onResume();
        Log.i(TAG,"onResume()");
        if (mapFragment!=null) {
            mapFragment.getMapAsync(this);
        }
        newVehicleUnitRelationship = vehicleUnitRelationshipDao.getWamsUnitVehicleUnitRelationship(NgfrApp.getInstance().getUniqueDeviceId());



    }*/

    /*@Override
    public void onPause() {
        Log.i(TAG,"onPause()");
        super.onPause();
        myPause();
    }*/


   public void myResume() {
       Log.i(TAG,"myResume()");
       Set<String> keys = bundleOfMarkers.keySet();
       WamsLocationMarker wamsLocationMarker = null;
       for (String k : keys) {
           Log.i(TAG,"key:"+k);
           wamsLocationMarker = (WamsLocationMarker) bundleOfMarkers.getParcelable(k);
           updateMarkersOnMap(map, wamsLocationMarker.getLat(), wamsLocationMarker.getLon(), wamsLocationMarker.getClientId(), wamsLocationMarker.getVehicleId());
       }
   }

   public void myPause()
   {
       Log.i(TAG,"myPause()");
       if (map!=null) {
           //lets get  the camera position & markers
           cp = map.getCameraPosition();
       }

       //keys in hashmap
       Set<String> keys = IncidentMapFragment.bundleOfMarkers.keySet();
       WamsLocationMarker wamsLocationMarker = null;
       for (String k : keys) {
           wamsLocationMarker = (WamsLocationMarker) IncidentMapFragment.bundleOfMarkers.get(k);
           bundleOfMarkers.putParcelable(k,wamsLocationMarker);
       }
   }

    //Just for test - Im mocking some there points to represent other teams mates on the map, this is just for testing
    private static void mockTeam(GoogleMap map, double _lat, double _log) {

        updateMarkersOnMap(map, _lat+0.001, _log , "mock111111111", newVehicleUnitRelationship.getVehicleUnitId());


        updateMarkersOnMap(map,_lat, _log+0.001 ,"mock222222222", newVehicleUnitRelationship.getVehicleUnitId());


        updateMarkersOnMap(map, _lat-0.001, _log,"mock33333333", newVehicleUnitRelationship.getVehicleUnitId());

        updateMarkersOnMap(map, _lat, _log-0.001,"mock444444444", newVehicleUnitRelationship.getVehicleUnitId());


    }

    //Ask the user if  required & attempt to grant required location services
    private boolean permissionHelper(Activity activity) {

        String permission = Manifest.permission.ACCESS_COARSE_LOCATION;
        int res = getContext().checkCallingPermission(permission);
        //if the required coarse & fine permissions are granted then return true else proceed to get the permissions
        if (res == PackageManager.PERMISSION_GRANTED) {
            Log.i(TAG, "ACCESS_COARSE_LOCATION GRANTED");

            permission = Manifest.permission.ACCESS_FINE_LOCATION;
            res = getContext().checkCallingPermission(permission);
            if (res == PackageManager.PERMISSION_GRANTED) {
                Log.i(TAG, "ACCESS_FINE_LOCATION GRANTED");
                flagFineLocation = true;
            } else {
                Log.i(TAG, "ACCESS_FINE_LOCATION NOT GRANTED");
            }

            flagCoarseLocation = true;
        }
        //prompt user for COARSE location permission. If the user cancel then display toast & navigate back
        if (!flagCoarseLocation) {

            if (ActivityCompat.shouldShowRequestPermissionRationale(activity,
                    Manifest.permission.ACCESS_COARSE_LOCATION)) {

                dialogForCoarsePermission();

            } else {
                ActivityCompat.requestPermissions(activity,
                        new String[] {
                                Manifest.permission.ACCESS_COARSE_LOCATION
                        },
                        MY_DEFINED_ACCESS_COARSE_LOCATION_CALLBACK_RESULT);
                flagCoarseLocation = true;

            }
        }
        //prompt user for FINE location permission. If the user cancel then display toast & navigate back
        if (!flagFineLocation) {

            if (ActivityCompat.shouldShowRequestPermissionRationale(activity,
                    Manifest.permission.ACCESS_FINE_LOCATION)) {

                dialogForFinePermission();

            } else {
                ActivityCompat.requestPermissions(activity,
                        new String[] {
                                Manifest.permission.ACCESS_COARSE_LOCATION
                        },
                        MY_DEFINED_ACCESS_FINE_LOCATION_CALLBACK_RESULT);
                flagFineLocation = true;


            }
        }

        if (!flagCoarseLocation)
        {
            Log.i(TAG, "ACCESS_COARSE_LOCATION NOT GRANTED");
        }
        else
        {

            Log.i(TAG, "ACCESS_COARSE_LOCATION GRANTED");
        }
        if (!flagFineLocation)
        {
            Log.i(TAG, "ACCESS_FINE_LOCATION NOT GRANTED");
        }
        else
        {
            Log.i(TAG, "ACCESS_FINE_LOCATION GRANTED");
        }

        return (flagCoarseLocation && flagFineLocation);
    }

    private void dialogForCoarsePermission() {
        DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                switch (which) {
                    case DialogInterface.BUTTON_POSITIVE:
                        //Yes button clicked
                        ActivityCompat.requestPermissions(getActivity(),
                                new String[] {
                                        Manifest.permission.ACCESS_COARSE_LOCATION
                                },
                                MY_DEFINED_ACCESS_COARSE_LOCATION_CALLBACK_RESULT);
                        break;

                    case DialogInterface.BUTTON_NEGATIVE:
                        //No button clicked
                        break;
                }
            }
        };

        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setMessage("The map requires coarse location permission.Please it by pressing Yes. ").setPositiveButton("Yes", dialogClickListener)
                .setNegativeButton("No", dialogClickListener).show();
    }

    private void dialogForFinePermission() {
        DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                switch (which) {
                    case DialogInterface.BUTTON_POSITIVE:
                        //Yes button clicked
                        ActivityCompat.requestPermissions(getActivity(),
                                new String[] {
                                        Manifest.permission.ACCESS_FINE_LOCATION
                                },
                                MY_DEFINED_ACCESS_FINE_LOCATION_CALLBACK_RESULT);
                        break;

                    case DialogInterface.BUTTON_NEGATIVE:
                        //No button clicked
                        break;
                }
            }
        };

        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setMessage("The map ALSO requires fine location permission.Please it by pressing Yes. ").setPositiveButton("Yes", dialogClickListener)
                .setNegativeButton("No", dialogClickListener).show();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        Log.i(TAG, "onRequestPermissionsResult() request code:" + requestCode); // Log printed
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == MY_DEFINED_ACCESS_COARSE_LOCATION_CALLBACK_RESULT) {
            flagCoarseLocation = true;
            Toast.makeText(context, "Coarse location permission granted.", Toast.LENGTH_SHORT).show();

        }
        if (requestCode == MY_DEFINED_ACCESS_FINE_LOCATION_CALLBACK_RESULT) {
            flagFineLocation = true;
            Toast.makeText(context, "Fine location permission granted.", Toast.LENGTH_SHORT).show();
        }

    }


    }


**Fragment Adapter class:**

    package com.xyz.views;

//didnt include imports

    public class MainActivityViewPagerAdapter extends FragmentStatePagerAdapter {
        public MainActivityViewPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            Fragment returnFragment=null;

            switch(position) {
                case 0:
                    returnFragment = ServicesFragment.newInstance();
                    break;
                case 1:
                    returnFragment = BiometricsFragment.newInstance();
                    break;
                case 2:
                     returnFragment =IncidentMapFragment.newInstance();
                     break;
            }

            return returnFragment;
        }

        @Override
        public int getCount() {
            return 3;
        }

        public CharSequence getPageTitle(int position) {
            CharSequence title=null;
            switch (position) {
                case 0:
                    title = "Services";
                    break;
                case 1:
                    title = "Biometrics";
                    break;
                case 2:
                    title = "Incident Map";
                    break;

            }

            return title;


        }
    }
楚瑞
2023-03-14

您不必像其他答案建议的那样为此存储状态更改。但是MapFraank实现是错误的。您必须修复它。

onActivityCreated()中的代码更改为this并将其移动到onCreate()。您根本不必覆盖onActivityCreated

mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.incident_map);
mapFragment.getMapAsync(this);
萧修永
2023-03-14

很明显,第一个片段正在调用onResume()、onMapReady()、onPance(),这是重置映射

您可能处理错误了,因此我仍然认为问题仍然与活动/片段状态更改有关。

要想知道这是否是由于片段状态的变化造成的,一个简单的调整是,每当用户放置一个标记时,将所有值存储到SharedReference中,并在每次状态发生变化时(onPause、onResume等)将它们分配到映射中。

用于片段状态更改解释

一些用户触发和一些系统触发的不同事件会导致活动/片段从一种状态转换到另一种状态,并重置活动/片段。因此,在android中,您需要处理活动的不同状态以及片段。

为了处理活动状态更改,您可以参考Android文档。

对于您的情况:

关于如何处理片段状态更改,有一个非常非常好的示例和详细信息。

我希望这有帮助!

 类似资料:
  • 问题内容: 我正在尝试制作一个在鼠标本地化处绘制一个圆的简单Java程序,它获取了鼠标的X和Y坐标,但是它没有绘制任何内容,我试图绘制一个String,一个圆和一条线,但是没有任何效果,我稍微修改了代码,但仍然无法正常工作 问题答案: 不要直接在上执行自定义绘画。如果可以,请始终在替代方法上进行操作。 为此,请勿使用无限循环。有用于Mouse Motion收听的

  • 我遵循谷歌开发平台上分享的一步步说明http://developer.android.com/training/basics/actionbar/index.html 但由于某些原因,我没有看到ic_action_search。png在我的模拟器的菜单栏上,尽管它是在可绘制的hdpi上导入和复制的。 列出迄今为止尝试的所有选项(使用eclipse IDE): 导入图像ic_操作_搜索。巴布亚新几内

  • 本文向大家介绍python在openstreetmap地图上绘制路线图的实现,包括了python在openstreetmap地图上绘制路线图的实现的使用技巧和注意事项,需要的朋友参考一下 利用python进行经纬度轨迹展示 嘿!各位好久不见,距离第一次发博客已经过去两年多了,本人也从本科生变成了研究生,好了书归正传,最近在做一个关于航班滑行路径轨迹的项目,目的是将航班的经纬度数据在地图上显现出来并

  • 嗨,我正在学习如何在shiny上使用传单地图,我用了这个例子: 我想通过将函数替换为来将圈替换为标记。 实际的函数是:(server.r的第98行) 我把它换成了:

  • 问题内容: 我无法在JFrame上绘制此椭圆形。 框架显示,但其中未绘制任何内容。我在这里做错了什么? 问题答案: 您创建了一个静态方法,该方法不会覆盖paint方法。现在,其他人已经指出,您需要覆盖paintComponent等。但是,为了快速修复,您需要执行以下操作: 但是,正如其他人指出的那样,在JFrame上进行绘制非常棘手。最好使用JPanel。

  • 我已经创建了osmdroid地图视图,在上面我可以显示自定义WMS,这很有效。接下来,我需要在地图上以GeoJSON格式从定制服务获得的两点之间绘制路线。GeoJSON如下所示:http://pastebin.com/GJWYNkAq 通过OkHttp客户端调用服务: 我使用以下方法用于此Osmbonuspack库: 当我运行应用程序,启动后崩溃与此错误: 03-09 13:01:51.521 3