Dostęp do udostępnionych zbiorów danych

Od Androida 11 (poziom API 30) system buforuje duże zbiory danych, do których może mieć dostęp wiele aplikacji w przypadkach użycia takich jak uczenie maszynowe i odtwarzanie multimediów. Ta funkcja pomaga zmniejszyć nadmiarowość danych zarówno w sieci, jak i na dysku.

Gdy aplikacja potrzebuje dostępu do udostępnionego dużego zbioru danych, może najpierw wyszukać te zbuforowane zbiory danych, zwane udostępnionymi blobami danych, zanim zdecyduje, czy pobrać nową kopię. Aplikacje mogą korzystać z funkcji udostępnionych zbiorów danych za pomocą interfejsów API w BlobStoreManager.

System przechowuje udostępnione obiekty danych i określa, które aplikacje mogą mieć do nich dostęp. Gdy aplikacja przesyła bloki danych, możesz wskazać, które inne aplikacje powinny mieć do nich dostęp, wywołując jedną z tych metod:

  • Aby przyznać dostęp do określonego zestawu aplikacji na urządzeniu, przekaż nazwy pakietów tych aplikacji do allowPackageAccess().
  • Aby zezwolić tylko aplikacjom, których certyfikaty są podpisane tym samym kluczem co klucz używany w Twojej aplikacji (np. pakietowi aplikacji, którym zarządzasz), wywołaj funkcję allowSameSignatureAccess().
  • Aby przyznać dostęp do wszystkich aplikacji na urządzeniu, wywołaj funkcję allowPublicAccess().

Dostęp do udostępnionych obiektów danych

System reprezentuje każdy udostępniony blok danych za pomocą obiektu BlobHandle. Każde wystąpienie BlobHandle zawiera bezpieczny kryptograficznie skrót i niektóre szczegóły identyfikacyjne zbioru danych.

Aby uzyskać dostęp do udostępnionych obiektów danych, pobierz z serwera szczegóły identyfikacyjne. Na podstawie tych informacji sprawdź, czy zbiór danych jest już dostępny w systemie.

Dalsze kroki zależą od tego, czy dane są dostępne.

Zbiór danych jest dostępny

Jeśli zbiór danych jest już dostępny na urządzeniu, uzyskaj do niego dostęp z systemu, jak pokazano w tym fragmencie kodu:

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

Zbiór danych jest niedostępny

Jeśli zbiór danych nie jest dostępny, pobierz go z serwera i prześlij do systemu, jak pokazano w tym fragmencie kodu:

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