Доступ к общим наборам данных

Начиная с Android 11 (уровень API 30), система кэширует большие наборы данных, к которым могут обращаться несколько приложений для таких задач, как машинное обучение и воспроизведение мультимедиа. Эта функция помогает уменьшить избыточность данных как в сети, так и на диске.

Когда вашему приложению требуется доступ к общему большому набору данных, оно может сначала искать эти кэшированные наборы данных, называемые общими блоками данных , прежде чем решить, следует ли загружать новую копию. Приложения могут получить доступ к функциональности этих общих наборов данных, используя API в BlobStoreManager .

Система поддерживает общие блоки данных и контролирует, какие приложения могут к ним получить доступ. Когда ваше приложение предоставляет блоки данных, вы можете указать, каким другим приложениям должен быть предоставлен доступ, вызвав один из следующих методов:

  • Чтобы предоставить доступ к определенному набору приложений на устройстве, передайте имена пакетов этих приложений в allowPackageAccess() .
  • Чтобы разрешить доступ только приложениям, сертификаты которых подписаны с использованием того же ключа, что и для вашего приложения (например, для управляемого вами набора приложений), вызовите метод allowSameSignatureAccess() .
  • Чтобы предоставить доступ всем приложениям на устройстве, вызовите метод allowPublicAccess() .

Доступ к общим блокам данных

Система представляет каждый общий блок данных с помощью объекта BlobHandle . Каждый экземпляр BlobHandle содержит криптографически защищенный хеш и некоторые идентификационные данные для набора данных.

Для доступа к общим блокам данных загрузите с сервера идентификационные данные. Используя эти данные, проверьте, доступен ли набор данных уже в системе.

Следующий шаг зависит от наличия данных.

Доступен набор данных

Если набор данных уже доступен на устройстве, то получите к нему доступ из системы, как показано в следующем фрагменте кода:

Котлин

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);
    }
}

Набор данных недоступен

Если набор данных недоступен, загрузите его с сервера и добавьте в систему, как показано в следующем фрагменте кода:

Котлин

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);
    }
}