Access shared datasets
Stay organized with collections
Save and categorize content based on your preferences.
Starting in Android 11 (API level 30), the system caches large datasets that
multiple apps might access for use cases like machine learning and media
playback. This functionality helps reduce data redundancy, both over the network
and on disk.
When your app needs access to a shared large dataset, it can first look for
these cached datasets, called shared data blobs, before determining whether to
download a new copy. Apps can access these shared datasets functionality using
the APIs in BlobStoreManager
.
The system maintains the shared data blobs and controls which apps can access
them. When your app contributes data blobs, you can indicate which other apps
should have access by calling one of the following methods:
- To grant access to a specific set of apps on a device, pass the package names
of these apps into
allowPackageAccess()
.
- To allow only apps whose certificates are signed using the same key as the one
used for your app—such as an app suite that you manage—call
allowSameSignatureAccess()
.
- To grant access to all apps on a device, call
allowPublicAccess()
.
Access shared data blobs
The system represents each shared data blob using a
BlobHandle
object. Each instance of BlobHandle
contains a cryptographically-secure hash and some identifying details for the
dataset.
To access shared data blobs, download identifying details from the server. Using
these details, check whether the dataset is already available on the system.
The next step depends on whether data is available.
Dataset available
If the dataset is already available on the device, then access it from the system,
as shown in the following code snippet:
Kotlin
val blobStoreManager =
getSystemService(Context.BLOB_STORE_SERVICE) as BlobStoreManager
// The label "Sample photos" is visible to the user.
val blobHandle = BlobHandle.createWithSha256(sha256DigestBytes,
"Sample photos",
System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1),
"photoTrainingDataset")
try {
val input = ParcelFileDescriptor.AutoCloseInputStream(
blobStoreManager.openBlob(blobHandle))
useDataset(input)
}
Java
BlobStoreManager blobStoreManager =
((BlobStoreManager) getSystemService(Context.BLOB_STORE_SERVICE));
if (blobStoreManager != null) {
// The label "Sample photos" is visible to the user.
BlobHandle blobHandle = BlobHandle.createWithSha256(
sha256DigestBytes,
"Sample photos",
System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1),
"photoTrainingDataset");
try (InputStream input = new ParcelFileDescriptor.AutoCloseInputStream(
blobStoreManager.openBlob(blobHandle))) {
useDataset(input);
}
}
Dataset unavailable
If the dataset isn't available, then download it from the server and contribute it
to the system, as shown in the following code snippet:
Kotlin
val sessionId = blobStoreManager.createSession(blobHandle)
try {
val session = blobStoreManager.openSession(sessionId)
try {
// For this example, write 200 MiB at the beginning of the file.
val output = ParcelFileDescriptor.AutoCloseOutputStream(
session.openWrite(0, 1024 * 1024 * 200))
writeDataset(output)
session.apply {
allowSameSignatureAccess()
allowPackageAccess(your-app-package,
app-certificate)
allowPackageAccess(some-other-app-package,
app-certificate)
commit(mainExecutor, callback)
}
}
}
Java
long sessionId = blobStoreManager.createSession(blobHandle);
try (BlobStoreManager.Session session =
blobStoreManager.openSession(sessionId)) {
// For this example, write 200 MiB at the beginning of the file.
try (OutputStream output = new ParcelFileDescriptor.AutoCloseOutputStream(
session.openWrite(0, 1024 * 1024 * 200)))
writeDataset(output);
session.allowSameSignatureAccess();
session.allowPackageAccess(your-app-package,
app-certificate);
session.allowPackageAccess(some-other-app-package,
app-certificate);
session.commit(getMainExecutor(), callback);
}
}
Content and code samples on this page are subject to the licenses described in the Content License. Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
Last updated 2025-08-26 UTC.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-08-26 UTC."],[],[],null,["Starting in Android 11 (API level 30), the system caches large datasets that\nmultiple apps might access for use cases like machine learning and media\nplayback. This functionality helps reduce data redundancy, both over the network\nand on disk.\n\nWhen your app needs access to a shared large dataset, it can first look for\nthese cached datasets, called *shared data blobs* , before determining whether to\ndownload a new copy. Apps can access these shared datasets functionality using\nthe APIs in [`BlobStoreManager`](/reference/android/app/blob/BlobStoreManager).\n\nThe system maintains the shared data blobs and controls which apps can access\nthem. When your app contributes data blobs, you can indicate which other apps\nshould have access by calling one of the following methods:\n\n- To grant access to a specific set of apps on a device, pass the package names of these apps into [`allowPackageAccess()`](/reference/android/app/blob/BlobStoreManager.Session#allowPackageAccess(java.lang.String,%20byte%5B%5D)).\n- To allow only apps whose certificates are signed using the same key as the one used for your app---such as an app suite that you manage---call [`allowSameSignatureAccess()`](/reference/android/app/blob/BlobStoreManager.Session#allowSameSignatureAccess()).\n- To grant access to all apps on a device, call [`allowPublicAccess()`](/reference/android/app/blob/BlobStoreManager.Session#allowPublicAccess()).\n\nAccess shared data blobs\n\nThe system represents each shared data blob using a\n[`BlobHandle`](/reference/android/app/blob/BlobHandle) object. Each instance of `BlobHandle`\ncontains a cryptographically-secure hash and some identifying details for the\ndataset.\n\nTo access shared data blobs, download identifying details from the server. Using\nthese details, check whether the dataset is already available on the system.\n\nThe next step depends on whether data is available.\n\nDataset available\n\nIf the dataset is already available on the device, then access it from the system,\nas shown in the following code snippet: \n\nKotlin \n\n```kotlin\nval blobStoreManager =\n getSystemService(Context.BLOB_STORE_SERVICE) as BlobStoreManager\n// The label \"Sample photos\" is visible to the user.\nval blobHandle = BlobHandle.createWithSha256(sha256DigestBytes,\n \"Sample photos\",\n System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1),\n \"photoTrainingDataset\")\ntry {\n val input = ParcelFileDescriptor.AutoCloseInputStream(\n blobStoreManager.openBlob(blobHandle))\n useDataset(input)\n}\n```\n\nJava \n\n```java\nBlobStoreManager blobStoreManager =\n ((BlobStoreManager) getSystemService(Context.BLOB_STORE_SERVICE));\nif (blobStoreManager != null) {\n // The label \"Sample photos\" is visible to the user.\n BlobHandle blobHandle = BlobHandle.createWithSha256(\n sha256DigestBytes,\n \"Sample photos\",\n System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1),\n \"photoTrainingDataset\");\n try (InputStream input = new ParcelFileDescriptor.AutoCloseInputStream(\n blobStoreManager.openBlob(blobHandle))) {\n useDataset(input);\n }\n}\n```\n\nDataset unavailable\n\nIf the dataset isn't available, then download it from the server and contribute it\nto the system, as shown in the following code snippet: \n\nKotlin \n\n```kotlin\nval sessionId = blobStoreManager.createSession(blobHandle)\ntry {\n val session = blobStoreManager.openSession(sessionId)\n try {\n // For this example, write 200 MiB at the beginning of the file.\n val output = ParcelFileDescriptor.AutoCloseOutputStream(\n session.openWrite(0, 1024 * 1024 * 200))\n writeDataset(output)\n\n session.apply {\n allowSameSignatureAccess()\n allowPackageAccess(your-app-package,\n app-certificate)\n allowPackageAccess(some-other-app-package,\n app-certificate)\n commit(mainExecutor, callback)\n }\n }\n}\n```\n\nJava \n\n```java\nlong sessionId = blobStoreManager.createSession(blobHandle);\ntry (BlobStoreManager.Session session =\n blobStoreManager.openSession(sessionId)) {\n // For this example, write 200 MiB at the beginning of the file.\n try (OutputStream output = new ParcelFileDescriptor.AutoCloseOutputStream(\n session.openWrite(0, 1024 * 1024 * 200)))\n writeDataset(output);\n session.allowSameSignatureAccess();\n session.allowPackageAccess(your-app-package,\n app-certificate);\n session.allowPackageAccess(some-other-app-package,\n app-certificate);\n session.commit(getMainExecutor(), callback);\n }\n}\n```"]]