microg/GmsCore · error · IllegalStateException

CameraUpdateFactory is not initialized

Error message

CameraUpdateFactory is not initialized

What it means

CameraUpdateFactory delegates all camera-update creation to an ICameraUpdateFactoryDelegate that must be installed via setDelegate by the active maps backend (e.g. the vtm backend). getDelegate() throws IllegalStateException when no backend has registered, so any static factory method like newCameraPosition fails.

Source

Thrown at play-services-maps/src/main/java/com/google/android/gms/maps/CameraUpdateFactory.java:29

import android.os.RemoteException;
import androidx.annotation.NonNull;
import com.google.android.gms.maps.internal.ICameraUpdateFactoryDelegate;
import com.google.android.gms.maps.model.CameraPosition;
import org.microg.gms.common.Hide;

/**
 * A class containing methods for creating {@link CameraUpdate} objects that change a map's camera. To modify the map's camera, call
 * {@link GoogleMap#animateCamera(CameraUpdate)}, {@link GoogleMap#animateCamera(CameraUpdate, GoogleMap.CancelableCallback)} or
 * {@link GoogleMap#moveCamera(CameraUpdate)}, using a {@link CameraUpdate} object created with this class.
 */
public class CameraUpdateFactory {
    private static ICameraUpdateFactoryDelegate delegate;
    @Hide
    public static void setDelegate(@NonNull ICameraUpdateFactoryDelegate delegate) {
        CameraUpdateFactory.delegate = delegate;
    }
    private static ICameraUpdateFactoryDelegate getDelegate() {
        if (delegate == null) throw new IllegalStateException("CameraUpdateFactory is not initialized");
        return delegate;
    }

    /**
     * Returns a {@link CameraUpdate} that moves the camera to a specified {@link CameraPosition}. In effect, this creates a transformation from the
     * {@link CameraPosition} object's latitude, longitude, zoom level, bearing and tilt.
     *
     * @param cameraPosition The requested position. Must not be {@code null}.
     * @return a {@link CameraUpdate} containing the transformation.
     */
    public static CameraUpdate newCameraPosition(@NonNull CameraPosition cameraPosition) {
        try {
            return new CameraUpdate(getDelegate().newCameraPosition(cameraPosition));
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }
    }

View on GitHub (pinned to 157c9d86ac)

Solutions

  1. Obtain/initialize the map view (or call MapsInitializer / backend init) before creating CameraUpdate objects via CameraUpdateFactory
  2. Ensure the microG maps backend is actually present and loaded so it calls CameraUpdateFactory.setDelegate(...)
  3. In tests, install a mock ICameraUpdateFactoryDelegate via CameraUpdateFactory.setDelegate before exercising the factory

Example fix

// before
CameraUpdate update = CameraUpdateFactory.newCameraPosition(pos); // delegate null
map.moveCamera(update);
// after
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(googleMap -> {
    CameraUpdate update = CameraUpdateFactory.newCameraPosition(pos);
    googleMap.moveCamera(update);
});
Defensive patterns

Strategy: try-catch

Validate before calling

// only build camera updates after the map is initialized
mapFragment.getMapAsync(googleMap -> {
    CameraUpdate u = CameraUpdateFactory.newCameraPosition(pos);
    googleMap.moveCamera(u);
});

Try / catch

try { CameraUpdateFactory.newCameraPosition(pos); } catch (IllegalStateException e) { /* defer until map initialized */ }

Prevention

When it happens

Trigger: Calling CameraUpdateFactory.newCameraPosition(...)/newLatLngZoom(...)/newLatLngBounds(...) before the map backend initialized — typically before any MapsInitializer or map fragment/view creation, or in a plain non-microG unit test.

Common situations: Creating CameraUpdate objects in Application.onCreate or a ViewModel before the map view exists; using microG maps classes on a device where no backend registered the delegate; running Robolectric/JUnit tests without setting a fake delegate.

Related errors


AI-assisted analysis of microg/GmsCore@157c9d86ac (2026-09-06). Data as JSON: /api/errors/392cae574e4ff221. Report an issue: GitHub.