Od Androida 11 (poziom interfejsu API 30) system zapisuje w pamięci podręcznej duże zbiory danych, do których wiele aplikacji może mieć dostęp na potrzeby takich zastosowań jak systemy uczące się 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 poszukać tych zbiorów danych w pamięci podręcznej (tzw. udostępnionych blobów danych), zanim zdecyduje, czy pobrać nową kopię. Aplikacje mogą korzystać z funkcji udostępniania zbiorów danych za pomocą interfejsów API w narzędziu BlobStoreManager
.
System utrzymuje udostępnione bloby danych i kontroluje, które aplikacje mogą z nich korzystać. Gdy Twoja aplikacja udostępnia obiekty blob danych, możesz wskazać inne aplikacje, które powinny mieć 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 na aplikacje, których certyfikaty są podpisane przy użyciu tego samego klucza, który został użyty w Twojej aplikacji (np. pakietu aplikacji, którym zarządzasz), zadzwoń pod numer
allowSameSignatureAccess()
. - Aby przyznać dostęp do wszystkich aplikacji na urządzeniu, wywołaj metodę
allowPublicAccess()
.
Dostęp do udostępnionych blobów danych
System reprezentuje każdy blob udostępnionych danych za pomocą obiektu BlobHandle
. Każda instancja obiektu BlobHandle
zawiera zabezpieczony kryptograficznie hasz i pewne szczegóły identyfikujące zbiór danych.
Aby uzyskać dostęp do udostępnionych blobów danych, pobierz z serwera szczegóły identyfikacyjne. Na podstawie tych informacji sprawdź, czy zbiór danych jest już dostępny w systemie.
Następny krok zależy 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 niedostępny
Jeśli zbiór danych jest niedostę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); } }