简体   繁体   中英

Searching GPS icon never disappears on retained Fragment in Android with MyLocationOverlay (osmdroid)

This is the situation:

I have an activity with a PagerAdapter containing three fragments. This activity allows you to change the screen orientation.

One of those fragments has mapView created with the osmdroid library, and this fragment is retained ( setRetainInstance(true) ). At each orientation changed, the event onCreateView is fired again:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    fragmentView = (LinearLayout) inflater.inflate(R.layout.main,
            container, false);

    mapView = (MapView) fragmentView.findViewById(R.id.practice_mapview);

    mapView.setBuiltInZoomControls(true);
    mapView.setMultiTouchControls(true);
    mapView.setTileSource(TileSourceFactory.MAPNIK);
    mapView.setUseSafeCanvas(true);
    setHardwareAccelerationOff();

    mapController = (MapController) mapView.getController();

    [...]

    mLocationOverlay = new MyLocationOverlay(getActivity(), mapView);
    mLocationOverlay.setDrawAccuracyEnabled(true);

    [...]

    mapView.invalidate();

    return fragmentView;
}

At start everything works fine, but when I rotate the phone the sentence " mLocationOverlay = new MyLocationOverlay(getActivity(), mapView); " is executed again, and this means that, when you close the application, the GPS icon never disappears.

If you do not rotate the phone the icon disappears when the application closes.

This is what I have on the onPause event:

@Override
public void onPause() {
    mLocationOverlay.disableCompass();

    if (this.getActivity().isFinishing()) {
        disableMyLocation();    
        releaseLocationOverlay();
    }

    cleanMapViewCache();
}

private void disableMyLocation() {
    if (mLocationOverlay.isMyLocationEnabled() == true)
        mLocationOverlay.disableMyLocation();

    if (mLocationOverlay.isFollowLocationEnabled() == true)
        mLocationOverlay.disableFollowLocation();
}

private void releaseLocationOverlay() {
    if (mLocationOverlay != null) {
        mapView.getOverlays().remove(mLocationOverlay);
        mLocationOverlay = null;
    }
}

private void cleanMapViewCache() {
    mapView.getTileProvider().clearTileCache();
    System.gc();
}

Si en el evento onCreateView hago este sencillo control el problema desaparece:

If I put this control in the onCreateView event, the problem disappears:

if (this.getActivity().isFinishing())
    mLocationOverlay = new MyLocationOverlay(getActivity(), mapView);

But then, among other things, I am not able to center anymore:

mapController.animateTo(mLocationOverlay.getMyLocation());

Any idea? There's something I'm doing wrong?

If you need more code, you have no more to say. Thank you!

Two things here:

1) My understanding of your code is that mLocationOverlay is recreated when the orientation changes, but without switching its old instance off, leading a LocationListener to remain active and linked to the GPS.

Instead of doing this way in onCreate() :

// this is a copypaste of your workaround code but that prevents the map from moving
if (this.getActivity().isFinishing())
    mLocationOverlay = new MyLocationOverlay(getActivity(), mapView);

try doing:

if (mLocationOverlay != null) {
    uninitialize(); // see below
    mLocationOverlay = new MyLocationOverlay(getActivity(), mapView);
 }

and then, change your onPause() that way:

public void onPause() {
    uninitialize();
}

and create this method:

private void uninitialize() {
    // What follows is your former onPause() code:
    mLocationOverlay.disableCompass();

    if (this.getActivity().isFinishing()) {
        disableMyLocation();    
        releaseLocationOverlay();
    }

    cleanMapViewCache();
}

All this is subject to optimization/refactoring. I am not sure that calling cleanMapViewCache() when changing the device orientation is useful, for example.

2) Also, very important, dont keep your former mapController from an orientation to another: as your MapView is reinitialized in onCreate() , your controller should be reinitialized as well. This is probably why the map is no longer moving: the controller refers to the previous instance of this MapView instead of the current one.

Does all this work? Don't hesitate to let me know, I'll edit my answer if needed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM