简体   繁体   中英

Google Map API v2 doesn't update the Maps once app is restarted

I have written a App in android using Google Maps Api V2. The App basically runs a Service behind and reports Location to the Activity where Google Map is added using SupportMapFragment.

When I launch the App, everything seems to work fine and Maps are updated. The problem is when I push back button or screen turns off and get back to the App Google Maps Stop working. The Location is still reported and I call moveCamera method on Map object.

public class GpsTracker extends android.support.v4.app.FragmentActivity {

public static final int GPS_LOCATION_UPDATE = 0;
public static final int NETWORK_LOCATION_UPDATE = 1;
public static final int LOCATION_NETWORK_UNAVAILABLE = 2;
public static final int LOCATION_GPS_UNAVAILABLE = 3;

private static String gpsTrackerTag = "GpsTracker:MainActivity";

private GoogleMap mMap;
private PolylineOptions mpolyOptions = new PolylineOptions();
GpsTrackerMyService myservice = null;
ServiceConnection sc = null;
static MyHandlerCallback myCallback = null;

//private Boolean mServiceRunning = false; // Initial State When service is yet not started.
private Boolean mServiceBinded = false;

public static Callback CallBackHandler()
{
    return myCallback;
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_gps_tracker);

    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);

    if (savedInstanceState == null)     {
        // First incarnation of this activity.
        mapFragment.setRetainInstance(true);
    } else {
        // Reincarnated activity. The obtained map is the same map instance in the previous
        // activity life cycle. There is no need to reinitialize it.
        mMap = mapFragment.getMap();
    }

    InitializeActivity();
    setUpMapIfNeeded();
}

@Override
protected void onPause()
{
    super.onPause();
    if(mServiceBinded)
    {
        unbindService(sc);
        mServiceBinded = false;
        Log.d(gpsTrackerTag, "onPause(): Unbinded from the Serivce");
    }
    else
        Log.d(gpsTrackerTag, "onPause():  Service Already in not Bind State");
}

@Override
protected void onResume()
{
    super.onResume();
    if(GpsTrackerMyService.isInstanceCreated() == true)
    {
        bindService(new Intent(this, GpsTrackerMyService.class), sc, 0);
        mServiceBinded = true;
        Log.d(gpsTrackerTag, "onResume(): Binded to the Service");
    }
    else
        Log.d(gpsTrackerTag, "onResume(): Service Not Running");

    setUpMapIfNeeded();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.activity_gps_tracker, menu);
    return true;
}

private void setUpMapIfNeeded() {
    // Do a null check to confirm that we have not already instantiated the map.
    if (mMap == null) {
        // Try to obtain the map from the SupportMapFragment.
        mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
                .getMap();
        // Check if we were successful in obtaining the map.
        if (mMap != null) {
            setUpMap();
        }
    }
}

private void setUpMap() {
   // mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
}

private void InitializeActivity() {

    if(myCallback == null)
        myCallback = new MyHandlerCallback();

    if(sc == null){
        sc = new ServiceConnection() {

            @Override
            public void onServiceDisconnected(ComponentName name) {
                mServiceBinded = false;
                CharSequence text = "Service DisConnected";
                Toast t = Toast.makeText(getApplicationContext(), text, Toast.LENGTH_LONG);
                t.show();

                Log.d(gpsTrackerTag, "Service Disconnected ");
            }

            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                myservice = ((MyBinder) service).getService();
                mServiceBinded = true;
                Log.d(gpsTrackerTag, "Service Connected ");
            }

        };
    }   
}

public void startButton_Click(View view)
{
    if(GpsTrackerMyService.isInstanceCreated() == false)
    {
        Intent serviceIntent = startService();
        bindService(serviceIntent);
        Log.d(gpsTrackerTag, "startButton_Click(): Service Started and Called for bind");
    }
    else
        Log.d(gpsTrackerTag, "startButton_Click(): Service Already Running");

}

private void bindService(Intent serviceIntent) {
    bindService(serviceIntent, sc, 0 );
}

private Intent startService() {
    Intent serviceIntent = new Intent(this, GpsTrackerMyService.class);
    startService(serviceIntent);
    return serviceIntent;
}

public void stopButton_Click(View view)
{
    stopService();
}

private void stopService() {

    if(GpsTrackerMyService.isInstanceCreated() == true)
    {
        Log.d(gpsTrackerTag, "stopService(): Service Running Calling Stop on the Service");
        myservice.stopSelf();
    }
    else
        Log.d(gpsTrackerTag, "stopService(): Service Already Stopped");
}

public class MyHandlerCallback implements Callback
{

    @Override
    public boolean handleMessage(Message arg0) {

        Location l;
        CharSequence text;
        Toast t;
        LatLng mLatLng;
        int pos = 1;

        switch(arg0.what)
        {
        case GpsTracker.LOCATION_NETWORK_UNAVAILABLE:
            text = "Network Location Unavailable";
            t = Toast.makeText(getApplicationContext(), text, Toast.LENGTH_LONG);
            t.show();
            return true;

        case GpsTracker.NETWORK_LOCATION_UPDATE:
            l = ((Location)arg0.obj);
            mLatLng = new LatLng(l.getLatitude(), l.getLongitude());
            mpolyOptions.add(mLatLng).width(2).color(Color.BLACK).geodesic(true);
            mMap.addPolyline(mpolyOptions);
            mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mLatLng, 12));

            mMap.addMarker(new MarkerOptions()
               .position(mLatLng)
               .title("Pos " + pos));

            //text =  ((Location)arg0.obj).toString();
            t = Toast.makeText(getApplicationContext(), "Network Location Update", Toast.LENGTH_LONG);
            t.show();
            return true;


        case GpsTracker.GPS_LOCATION_UPDATE:
            l = ((Location)arg0.obj);
            mLatLng = new LatLng(l.getLatitude(), l.getLongitude());
            //mpolyOptions.add(mLatLng).width(2).color(Color.BLACK).geodesic(true);
            //mMap.addPolyline(mpolyOptions);
            boolean check = mMap.isMyLocationEnabled();
            mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mLatLng, 12));
                    //text =    ((Location)arg0.obj).toString();
            t = Toast.makeText(getApplicationContext(), "GPS Location Update", Toast.LENGTH_LONG);
            t.show();
            return true;



        case GpsTracker.LOCATION_GPS_UNAVAILABLE:
            text = "Gps Location Unavailable";
            t = Toast.makeText(getApplicationContext(), text, Toast.LENGTH_LONG);
            t.show();
            return true;

            default:
                return false;
        }
    }
}

In MyCallBackHandler case GPS_LOCATION_UPDATE the map doesn't move the camera.

I think your problem is related to the non-static inner class CallBack . When your activity is recreated, you keep a static reference to it in myCallBack , which itself has an implicit reference your old Activity . Not only is that a memory leak, but when you invoke the CallBack it is looking at an old activity's variables. See this post for more info on memory leaks and non-static inner classes.

If you make a new Callback when you launch a new activity, it should solve the problem. So, in your InitializeActivity , change

 if(myCallback == null)
        myCallback = new MyHandlerCallback();

to

myCallback = new MyHandlerCallback();

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