diff --git a/native/android/app/CMakeLists.txt b/native/android/app/CMakeLists.txt
--- a/native/android/app/CMakeLists.txt
+++ b/native/android/app/CMakeLists.txt
@@ -118,6 +118,7 @@
   "./src/cpp/StaffUtilsJNIHelper.cpp"
   "./src/cpp/AESCrypto.cpp"
   "./src/cpp/CommServicesAuthMetadataEmitter.cpp"
+  "./src/cpp/CommMMKV.cpp"
 )
 
 list(APPEND GENERATED_NATIVE_CODE
diff --git a/native/android/app/build.gradle b/native/android/app/build.gradle
--- a/native/android/app/build.gradle
+++ b/native/android/app/build.gradle
@@ -652,6 +652,7 @@
 }
 
 dependencies {
+    implementation 'com.tencent:mmkv:1.3.3'
     implementation fileTree(dir: "libs", include: ["*.jar"])
     implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.10"
     //noinspection GradleDynamicVersion
diff --git a/native/android/app/src/cpp/CommMMKV.cpp b/native/android/app/src/cpp/CommMMKV.cpp
new file mode 100644
--- /dev/null
+++ b/native/android/app/src/cpp/CommMMKV.cpp
@@ -0,0 +1,68 @@
+#include "jniHelpers.h"
+#include <Tools/CommMMKV.h>
+#include <fbjni/fbjni.h>
+
+using namespace facebook::jni;
+
+class CommMMKVJavaClass : public JavaClass<CommMMKVJavaClass> {
+public:
+  static auto constexpr kJavaDescriptor = "Lapp/comm/android/fbjni/CommMMKV;";
+
+  static void initialize() {
+    static const auto cls = javaClassStatic();
+    static auto method = cls->getStaticMethod<void()>("initialize");
+    method(cls);
+  }
+
+  static void clearSensitiveData() {
+    static const auto cls = javaClassStatic();
+    static auto method = cls->getStaticMethod<void()>("clearSensitiveData");
+    method(cls);
+  }
+
+  static bool setString(std::string key, std::string value) {
+    static const auto cls = javaClassStatic();
+    static auto method =
+        cls->getStaticMethod<jboolean(std::string, std::string)>("setString");
+    return method(cls, key, value);
+  }
+
+  static std::optional<std::string> getString(std::string key) {
+    static const auto cls = javaClassStatic();
+    static auto method =
+        cls->getStaticMethod<JString(std::string)>("getString");
+    const auto result = method(cls, key);
+    if (result) {
+      return result->toStdString();
+    }
+    return std::nullopt;
+  }
+};
+
+namespace comm {
+
+void CommMMKV::initialize() {
+  NativeAndroidAccessProvider::runTask(
+      []() { CommMMKVJavaClass::initialize(); });
+}
+
+void CommMMKV::clearSensitiveData() {
+  NativeAndroidAccessProvider::runTask(
+      []() { CommMMKVJavaClass::clearSensitiveData(); });
+}
+
+bool CommMMKV::setString(std::string key, std::string value) {
+  bool result;
+  NativeAndroidAccessProvider::runTask(
+      [&]() { result = CommMMKVJavaClass::setString(key, value); });
+  return result;
+}
+
+std::optional<std::string> CommMMKV::getString(std::string key) {
+  std::optional<std::string> result;
+  NativeAndroidAccessProvider::runTask(
+      [&]() { result = CommMMKVJavaClass::getString(key); });
+  return result;
+}
+
+} // namespace comm
diff --git a/native/android/app/src/main/java/app/comm/android/MainApplication.java b/native/android/app/src/main/java/app/comm/android/MainApplication.java
--- a/native/android/app/src/main/java/app/comm/android/MainApplication.java
+++ b/native/android/app/src/main/java/app/comm/android/MainApplication.java
@@ -6,6 +6,7 @@
 import androidx.annotation.NonNull;
 import androidx.multidex.MultiDexApplication;
 import app.comm.android.commservices.CommServicesPackage;
+import app.comm.android.fbjni.CommMMKV;
 import app.comm.android.fbjni.CommSecureStore;
 import app.comm.android.fbjni.DatabaseInitializer;
 import app.comm.android.fbjni.GlobalDBSingleton;
@@ -91,6 +92,7 @@
 
     SoLoader.init(this, /* native exopackage */ false);
     this.initializeDatabase();
+    CommMMKV.initialize();
     ApplicationLifecycleDispatcher.onApplicationCreate(this);
     try {
       Field field = CursorWindow.class.getDeclaredField("sCursorWindowSize");
diff --git a/native/android/app/src/main/java/app/comm/android/fbjni/CommMMKV.java b/native/android/app/src/main/java/app/comm/android/fbjni/CommMMKV.java
new file mode 100644
--- /dev/null
+++ b/native/android/app/src/main/java/app/comm/android/fbjni/CommMMKV.java
@@ -0,0 +1,98 @@
+package app.comm.android.fbjni;
+
+import app.comm.android.MainApplication;
+import app.comm.android.fbjni.CommSecureStore;
+import app.comm.android.fbjni.PlatformSpecificTools;
+import com.tencent.mmkv.MMKV;
+import java.util.Base64;
+
+public class CommMMKV {
+  private static final int MMKV_ENCRYPTION_KEY_SIZE = 16;
+  private static final int MMKV_ID_SIZE = 8;
+
+  private static final String SECURE_STORE_MMKV_ENCRYPTION_KEY_ID =
+      "comm.mmkvEncryptionKey";
+  private static final String SECURE_STORE_MMKV_IDENTIFIER_KEY_ID =
+      "comm.mmkvID";
+
+  private static String mmkvEncryptionKey;
+  private static String mmkvIdentifier;
+
+  private static MMKV getMMKVInstance(String mmkvID, String encryptionKey) {
+    MMKV mmkv =
+        MMKV.mmkvWithID(mmkvID, MMKV.SINGLE_PROCESS_MODE, encryptionKey);
+    if (mmkv == null) {
+      throw new RuntimeException("Failed to instantiate MMKV object.");
+    }
+    return mmkv;
+  }
+
+  private static void assignInitializationData() {
+    byte[] encryptionKeyBytes = PlatformSpecificTools.generateSecureRandomBytes(
+        MMKV_ENCRYPTION_KEY_SIZE);
+    byte[] identifierBytes =
+        PlatformSpecificTools.generateSecureRandomBytes(MMKV_ID_SIZE);
+    String encryptionKey = Base64.getEncoder()
+                               .encodeToString(encryptionKeyBytes)
+                               .substring(0, MMKV_ENCRYPTION_KEY_SIZE);
+    String identifier = Base64.getEncoder()
+                            .encodeToString(identifierBytes)
+                            .substring(0, MMKV_ID_SIZE);
+    CommSecureStore.set(SECURE_STORE_MMKV_ENCRYPTION_KEY_ID, encryptionKey);
+    CommSecureStore.set(SECURE_STORE_MMKV_IDENTIFIER_KEY_ID, identifier);
+    mmkvEncryptionKey = encryptionKey;
+    mmkvIdentifier = identifier;
+  }
+
+  public static void initialize() {
+    if (mmkvEncryptionKey != null && mmkvIdentifier != null) {
+      return;
+    }
+
+    synchronized (CommMMKV.class) {
+      if (mmkvEncryptionKey != null && mmkvIdentifier != null) {
+        return;
+      }
+
+      String encryptionKey =
+          CommSecureStore.get(SECURE_STORE_MMKV_ENCRYPTION_KEY_ID);
+      String identifier =
+          CommSecureStore.get(SECURE_STORE_MMKV_IDENTIFIER_KEY_ID);
+
+      if (encryptionKey == null || identifier == null) {
+        assignInitializationData();
+      } else {
+        mmkvEncryptionKey = encryptionKey;
+        mmkvIdentifier = identifier;
+      }
+
+      MMKV.initialize(MainApplication.getMainApplicationContext());
+      getMMKVInstance(mmkvIdentifier, mmkvEncryptionKey);
+    }
+  }
+
+  public static void clearSensitiveData() {
+    initialize();
+    synchronized (mmkvEncryptionKey) {
+      getMMKVInstance(mmkvIdentifier, mmkvEncryptionKey).clearAll();
+      boolean storageRemoved = MMKV.removeStorage(mmkvIdentifier);
+      if (!storageRemoved) {
+        throw new RuntimeException("Failed to remove MMKV storage.");
+      }
+      assignInitializationData();
+      MMKV.initialize(MainApplication.getMainApplicationContext());
+      getMMKVInstance(mmkvIdentifier, mmkvEncryptionKey);
+    }
+  }
+
+  public static boolean setString(String key, String value) {
+    initialize();
+    return getMMKVInstance(mmkvIdentifier, mmkvEncryptionKey)
+        .encode(key, value);
+  }
+
+  public static String getString(String key) {
+    initialize();
+    return getMMKVInstance(mmkvIdentifier, mmkvEncryptionKey).decodeString(key);
+  }
+}
diff --git a/native/cpp/CommonCpp/DatabaseManagers/DatabaseManager.cpp b/native/cpp/CommonCpp/DatabaseManagers/DatabaseManager.cpp
--- a/native/cpp/CommonCpp/DatabaseManagers/DatabaseManager.cpp
+++ b/native/cpp/CommonCpp/DatabaseManagers/DatabaseManager.cpp
@@ -1,8 +1,6 @@
 #include "DatabaseManager.h"
 #include "../Notifications/BackgroundDataStorage/NotificationsCryptoModule.h"
-#ifdef __APPLE__
 #include "../Tools/CommMMKV.h"
-#endif
 #include "../Tools/CommSecureStore.h"
 #include "Logger.h"
 #include "PlatformSpecificTools.h"
@@ -39,9 +37,7 @@
   CommSecureStore::set(CommSecureStore::commServicesAccessToken, "");
   SQLiteQueryExecutor::clearSensitiveData();
   PlatformSpecificTools::removeBackupDirectory();
-#ifdef __APPLE__
   CommMMKV::clearSensitiveData();
-#endif
   NotificationsCryptoModule::clearSensitiveData();
   DatabaseManager::setDatabaseStatusAsWorkable();
 }