# Cache management

> **Note (legacy): A newer version of the Maps SDK is available**
> 
> This page uses v9.7.1 of the Mapbox Maps SDK. A newer version of the SDK is available. Learn about the latest version, v11.31.0, in the [Maps SDK documentation](https://docs.mapbox.com/android/maps/guides/).

Your browser doesn't support HTML5 video. Open [link to the video](https://docs.mapbox.com/android/android/assets/medias/maps-example-cache-management-activity-b36b6a18475e07bb52c5118631c691cf.mp4).

> **Note**
> 
> This example is a part of the [Mapbox Android Demo app](https://github.com/mapbox/mapbox-android-demo). You can find the values for all referenced resources in the [`res`](https://github.com/mapbox/mapbox-android-demo/tree/master/MapboxAndroidDemo/src/main/res) directory. For example, see [`res/values/activity_strings.xml`](https://github.com/mapbox/mapbox-android-demo/tree/master/MapboxAndroidDemo/src/main/res/values/activity_strings.xml) for `R.string.*` references used in this example. The dependencies can be found [here.](https://github.com/mapbox/mapbox-navigation-android-examples/blob/main/app/build.gradle) The examples use View binding. [See setup documention if necessary.](https://developer.android.com/topic/libraries/view-binding)

Title: `activity_offline_cache_manipulation`

```xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:mapbox="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/materialGrey"
    tools:context=".examples.offline.CacheManagementActivity">

    <com.mapbox.mapboxsdk.maps.MapView
        android:id="@+id/mapView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        mapbox:layout_constraintBottom_toTopOf="@+id/guideline7"
        mapbox:layout_constraintEnd_toEndOf="parent"
        mapbox:layout_constraintStart_toStartOf="parent"
        mapbox:layout_constraintTop_toTopOf="parent"
        mapbox:mapbox_cameraTargetLat="40.73581"
        mapbox:mapbox_cameraTargetLng="-73.99155"
        mapbox:mapbox_cameraZoom="11"/>

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline7"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        mapbox:layout_constraintGuide_percent="0.54"/>

    <Button
        android:id="@+id/invalidate_ambient_cache_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/invalidate_cache_button"
        android:textAllCaps="false"
        mapbox:layout_constraintBottom_toTopOf="@+id/set_max_ambient_cache_size_button_editText"
        mapbox:layout_constraintEnd_toStartOf="@+id/reset_database_button"
        mapbox:layout_constraintHorizontal_bias="0.5"
        mapbox:layout_constraintStart_toStartOf="parent"
        mapbox:layout_constraintTop_toTopOf="@+id/guideline7"/>

    <Button
        android:id="@+id/reset_database_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/reset_database_button"
        android:textAllCaps="false"
        mapbox:layout_constraintBottom_toBottomOf="@+id/invalidate_ambient_cache_button"
        mapbox:layout_constraintEnd_toEndOf="parent"
        mapbox:layout_constraintHorizontal_bias="0.5"
        mapbox:layout_constraintStart_toEndOf="@+id/invalidate_ambient_cache_button"
        mapbox:layout_constraintTop_toTopOf="@+id/invalidate_ambient_cache_button"/>

    <Button
        android:id="@+id/set_max_ambient_cache_size_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/set_ambient_cache_max"
        android:textAllCaps="false"
        mapbox:layout_constraintBottom_toTopOf="@+id/set_max_ambient_cache_size_button_textView"
        mapbox:layout_constraintEnd_toEndOf="@+id/set_max_ambient_cache_size_button_editText"
        mapbox:layout_constraintStart_toStartOf="@+id/set_max_ambient_cache_size_button_editText"/>

    <TextView
        android:id="@+id/set_max_ambient_cache_size_button_textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="32dp"
        android:gravity="center"
        android:text="@string/set_max_ambient_cache_size_textview"
        mapbox:layout_constraintBottom_toBottomOf="parent"
        mapbox:layout_constraintEnd_toEndOf="@+id/set_max_ambient_cache_size_button"
        mapbox:layout_constraintStart_toStartOf="@+id/set_max_ambient_cache_size_button"/>

    <EditText
        android:id="@+id/set_max_ambient_cache_size_button_editText"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:hint="@string/set_ambient_cache_max_hint"
        android:textAllCaps="false"
        mapbox:layout_constraintBottom_toTopOf="@+id/set_max_ambient_cache_size_button"
        mapbox:layout_constraintEnd_toEndOf="@+id/invalidate_ambient_cache_button"
        mapbox:layout_constraintStart_toStartOf="@+id/invalidate_ambient_cache_button"/>

    <Button
        android:id="@+id/clear_ambient_cache_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/clear_ambient_cache_button"
        android:textAllCaps="false"
        mapbox:layout_constraintBottom_toBottomOf="@+id/set_max_ambient_cache_size_button"
        mapbox:layout_constraintEnd_toEndOf="@+id/reset_database_button"
        mapbox:layout_constraintStart_toStartOf="@+id/reset_database_button"
        mapbox:layout_constraintTop_toTopOf="@+id/set_max_ambient_cache_size_button_editText"/>


</androidx.constraintlayout.widget.ConstraintLayout>
```

**Java**

Title: `CacheManagementActivity.java`

[View on GitHub](https://github.com/mapbox/mapbox-android-demo/tree/master/MapboxAndroidDemo/src/main/java/com/mapbox/mapboxandroiddemo/examples/offline/CacheManagementActivity.java)

```java
package com.mapbox.mapboxandroiddemo.examples.offline;

import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.remoteconfig.FirebaseRemoteConfig;
import com.mapbox.mapboxandroiddemo.BuildConfig;
import com.mapbox.mapboxandroiddemo.R;
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.log.Logger;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.maps.Style;
import com.mapbox.mapboxsdk.offline.OfflineManager;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

/**
 * Use the Maps SDK's cache management methods to adjust the ambient cache and database.
 * This activity shows how to adjust the cache based on Android system button UI click
 * listening. It also shows how to hook Firebase Remote Config into cache management logic.
 */
public class CacheManagementActivity extends AppCompatActivity {

  // Firebase Remote Config keys
  private static final String INVALIDATE_AMBIENT_CACHE_KEY = "invalidate_ambient_cache_key";
  private static final String SET_MAX_AMBIENT_CACHE_SIZE_BOOLEAN_KEY = "set_max_ambient_cache_size_boolean_key";
  private static final String SET_MAX_AMBIENT_CACHE_SIZE_AMOUNT_KEY = "set_max_ambient_cache_size_amount_key";
  private static final String CLEAR_AMBIENT_CACHE_KEY = "clear_ambient_cache_key";
  private static final String RESET_DATABASE_REMOTE_CONFIG_KEY = "reset_database_remote_config_key";

  private MapView mapView;
  private FirebaseRemoteConfig firebaseRemoteConfig;
  private EditText newMaxAmbientCacheSizeTextView;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);


    // Mapbox access token is configured here. This needs to be called either in your application
    // object or in the same activity which contains the mapview.
    Mapbox.getInstance(this, getString(R.string.access_token));

    // This contains the MapView in XML and needs to be called after the access token is configured.
    setContentView(R.layout.activity_offline_cache_manipulation);

    newMaxAmbientCacheSizeTextView = findViewById(
        R.id.set_max_ambient_cache_size_button_editText);

    // Disabling Firebase Remote Config usage here to avoid build and compiling issues during
    // development.
    if (!BuildConfig.DEBUG) {

      // Get an instance of Firebase Remote Config.
      firebaseRemoteConfig = FirebaseRemoteConfig.getInstance();

      // Sets the minimum interval between successive fetch calls. Fetches less than
      // number of seconds passed in as a parameter, after the last fetch from the Firebase Remote
      // Config server would use values returned during the last fetch.
      // More info at https://bit.ly/2XJdvuT.

      // NOT recommended for apps in production. Uncomment to use for app development and testing
      /*firebaseRemoteConfig.setConfigSettingsAsync(new FirebaseRemoteConfigSettings.Builder()
          .setMinimumFetchIntervalInSeconds(5)
          .build());*/

      // Set default Remote Config parameter values. The app uses the in-app default values, and
      // when you need to adjust those defaults, you set an updated value for only the values you
      // want to change in the Firebase console.
      firebaseRemoteConfig.setDefaults(R.xml.cache_management_remote_config_defaults);

      // Fetch the latest Remote Config values from Firebase and then adjust the cache if needed.
      firebaseRemoteConfig.fetchAndActivate().addOnCompleteListener(this,
          new OnCompleteListener<Boolean>() {
            @Override
            public void onComplete(@NonNull Task<Boolean> task) {
              if (task.isSuccessful()) {
                adjustCacheBasedOnRemoteConfigServerSettings();
              } else {
                Logger.d("CacheManagementActivity", "Couldn\'t get Firebase cache "
                    + "management remote config settings from Firebase.");
              }
            }
          });
    }

    mapView = findViewById(R.id.mapView);
    mapView.onCreate(savedInstanceState);
    mapView.getMapAsync(new OnMapReadyCallback() {
      @Override
      public void onMapReady(@NonNull MapboxMap mapboxMap) {
        mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() {
          @Override
          public void onStyleLoaded(@NonNull Style style) {
            findViewById(R.id.invalidate_ambient_cache_button).setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View view) {
                invalidateAmbientCache();
              }
            });

            findViewById(R.id.set_max_ambient_cache_size_button).setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View view) {
                try {
                  long newMaxAmbientCacheSize = Long.valueOf(
                      newMaxAmbientCacheSizeTextView.getText().toString());
                  setNewMaxAmbientCache(newMaxAmbientCacheSize);
                } catch (NumberFormatException exception) {
                  Logger.d("CacheManagementActivity", "%s", exception);
                }
              }
            });

            findViewById(R.id.clear_ambient_cache_button).setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View view) {
                clearAmbientCache();
              }
            });

            findViewById(R.id.reset_database_button).setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View view) {
                resetDatabase();
              }
            });
          }
        });
      }
    });
  }

  /**
   * Invalidate the ambient cache. See
   * https://docs.mapbox.com/android/maps/overview/offline/#cache-management for more
   * information about this method.
   */
  private void invalidateAmbientCache() {
    OfflineManager fileSource = OfflineManager.getInstance(CacheManagementActivity.this);
    fileSource.invalidateAmbientCache(new OfflineManager.FileSourceCallback() {
      @Override
      public void onSuccess() {
        showToast(getString(R.string.cache_invalidated_toast_confirmation));
      }

      @Override
      public void onError(@NonNull String message) {
        showToast(String.format(getString(
            R.string.cache_invalidated_toast_error), message));
      }
    });
  }

  /**
   * Set a new maximum size of the ambient cache. See
   * https://docs.mapbox.com/android/maps/overview/offline/#cache-management for more
   * information about this method.
   */
  private void setNewMaxAmbientCache(long newMaxAmbientCacheSize) {
    OfflineManager fileSource = OfflineManager.getInstance(CacheManagementActivity.this);
    if (newMaxAmbientCacheSize < 0) {
      showToast(getString(R.string.invalid_max_ambient_cache_size));
      return;
    }

    fileSource.setMaximumAmbientCacheSize(newMaxAmbientCacheSize,
        new OfflineManager.FileSourceCallback() {
          @Override
          public void onSuccess() {
            Toast.makeText(CacheManagementActivity.this, String.format(
                getString(R.string.set_max_ambient_cache_size_toast_confirmation),
                newMaxAmbientCacheSize), Toast.LENGTH_SHORT).show();
          }

          @Override
          public void onError(@NonNull String message) {
            showToast(String.format(getString(
                R.string.set_max_ambient_cache_size_toast_error), message));
          }
        });
  }

  /**
   * Clear the ambient cache. See
   * https://docs.mapbox.com/android/maps/overview/offline/#cache-management for more
   * information about this method.
   */
  private void clearAmbientCache() {
    OfflineManager fileSource = OfflineManager.getInstance(CacheManagementActivity.this);
    fileSource.clearAmbientCache(new OfflineManager.FileSourceCallback() {
      @Override
      public void onSuccess() {
        showToast(getString(R.string.clear_ambient_cache_size_toast_confirmation));
      }

      @Override
      public void onError(@NonNull String message) {
        showToast(String.format(getString(
            R.string.clear_ambient_cache_size_toast_error), message));
      }
    });
  }

  /**
   * Reset the Maps SDK's database. See
   * https://docs.mapbox.com/android/maps/overview/offline/#cache-management for more
   * information about this method.
   */
  private void resetDatabase() {
    OfflineManager fileSource = OfflineManager.getInstance(CacheManagementActivity.this);
    fileSource.resetDatabase(new OfflineManager.FileSourceCallback() {
      @Override
      public void onSuccess() {
        showToast(getString(R.string.reset_database_toast_confirmation));
      }

      @Override
      public void onError(@NonNull String message) {
        showToast(String.format(getString(
            R.string.reset_database_toast_error), message));
      }
    });
  }

  /**
   * Use Remote Config boolean values to make appropriate adjustments to the Maps SDK cache.
   */
  private void adjustCacheBasedOnRemoteConfigServerSettings() {
    if (firebaseRemoteConfig.getBoolean(INVALIDATE_AMBIENT_CACHE_KEY)) {
      invalidateAmbientCache();
    }
    if (firebaseRemoteConfig.getBoolean(SET_MAX_AMBIENT_CACHE_SIZE_BOOLEAN_KEY)) {
      setNewMaxAmbientCache(firebaseRemoteConfig.getLong(SET_MAX_AMBIENT_CACHE_SIZE_AMOUNT_KEY));
    }
    if (firebaseRemoteConfig.getBoolean(CLEAR_AMBIENT_CACHE_KEY)) {
      clearAmbientCache();
    }
    if (firebaseRemoteConfig.getBoolean(RESET_DATABASE_REMOTE_CONFIG_KEY)) {
      resetDatabase();
    }
  }

  private void showToast(String textToShow) {
    CacheManagementActivity.this.runOnUiThread(new Runnable() {
      public void run() {
        Toast.makeText(CacheManagementActivity.this,
            textToShow, Toast.LENGTH_SHORT).show();
      }
    });
  }

  // Add the mapView lifecycle to the activity's lifecycle methods
  @Override
  public void onResume() {
    super.onResume();
    mapView.onResume();
  }

  @Override
  protected void onStart() {
    super.onStart();
    mapView.onStart();
  }

  @Override
  protected void onStop() {
    super.onStop();
    mapView.onStop();
  }

  @Override
  public void onPause() {
    super.onPause();
    mapView.onPause();
  }

  @Override
  public void onLowMemory() {
    super.onLowMemory();
    mapView.onLowMemory();
  }

  @Override
  protected void onDestroy() {
    super.onDestroy();
    mapView.onDestroy();
  }

  @Override
  protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    mapView.onSaveInstanceState(outState);
  }
}
```