-1

I have separate map class in which I have written all the logic related to map activities as it was a strict requirement to keep both map related things separate. Now from main app activity I am calling function like this:

        Timer t = new Timer();
        t.scheduleAtFixedRate(new TimerTask() {

            @Override
            public void run() {
                if (mapObj.isLocationClientConnected)
                    Location currentLocation = mapObj.gotoCurrentLocation();

            }

        }, 0, refreshUserLocationInterval);

And in Map Class I have:

public Location gotoCurrentLocation() {
    currentLocation = mLocationClient.getLastLocation();
        LatLng ll = new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude());
        CameraUpdate cUpdate = CameraUpdateFactory.newLatLngZoom(ll, defaultZoom);
        gMap.animateCamera(cUpdate);

    return currentLocation;

}

But I get this error:

06-22 19:56:30.900: E/AndroidRuntime(11413): FATAL EXCEPTION: Timer-0
06-22 19:56:30.900: E/AndroidRuntime(11413): java.lang.IllegalStateException: Not on the main thread
06-22 19:56:30.900: E/AndroidRuntime(11413):    at kbh.b(Unknown Source)
06-22 19:56:30.900: E/AndroidRuntime(11413):    at lzd.b(Unknown Source)
06-22 19:56:30.900: E/AndroidRuntime(11413):    at mbi.b(Unknown Source)
06-22 19:56:30.900: E/AndroidRuntime(11413):    at fms.onTransact(SourceFile:92)
06-22 19:56:30.900: E/AndroidRuntime(11413):    at android.os.Binder.transact(Binder.java:310)
06-22 19:56:30.900: E/AndroidRuntime(11413):    at com.google.android.gms.maps.internal.IGoogleMapDelegate$a$a.animateCamera(Unknown Source)
06-22 19:56:30.900: E/AndroidRuntime(11413):    at com.google.android.gms.maps.GoogleMap.animateCamera(Unknown Source)
06-22 19:56:30.900: E/AndroidRuntime(11413):    at com.mapworlds.mapworlds.MapClass.gotoCurrentLocation(MapClass.java:176)

I want to keep the animateCamera in same function inside map class. I already have main context from main app available as a variable in this class, can I utilize it and make it work?

Maven
  • 14,587
  • 42
  • 113
  • 174

2 Answers2

5

In fact, animateCamera modifies a UI component (the map), so that must be done on the UI thread.

EDIT

You can do this :

Timer t = new Timer();
        t.scheduleAtFixedRate(new TimerTask() {

            @Override
            public void run() {
             runOnUiThread(new Runnable() 
             {
              public void run() 
              {  
                //update ui
                if (mapObj.isLocationClientConnected)
                    Location currentLocation = mapObj.gotoCurrentLocation();

              }
             });
           }
        }, 0, refreshUserLocationInterval);
Farouk Touzi
  • 3,451
  • 2
  • 19
  • 25
3

You need to call animateCamera() from the main thread.

You can do so with a Handler or runOnUiThread(), or post().

matiash
  • 54,791
  • 16
  • 125
  • 154
  • I want to keep calling this function after specified intervals, can i do this with these? – Maven Jun 22 '14 at 17:34
  • 1
    @Maven yes, any of these will do. – matiash Jun 22 '14 at 17:35
  • @Maven Yes `Handler` would be a good choice. http://stackoverflow.com/questions/17839419/android-thread-for-a-timer. Note: `runOnUiThread` is a method of Activity class – Raghunandan Jun 22 '14 at 17:35
  • @Maven Just be sure to create the `Handler` in the main thread (i.e. not inside `gotoCurrentLocation()`. – matiash Jun 22 '14 at 17:41