Android 11(API レベル 30)より、複数のアプリが機械学習、メディア再生などのユースケースのためにアクセスする可能性がある大容量のデータセットは、システムによってキャッシュに保存され、ネットワーク上とディスク上の両方でデータの冗長性が軽減されます。
こうした大規模な共有データセットにアプリがアクセスする必要がある場合、新しいコピーをダウンロードするかどうかを判断する前に、「共有データ blob」と呼ばれる、キャッシュに保存されたデータセットをまず探すことができます。アプリは、BlobStoreManager
内の API を使用して、これらの共有データセット機能にアクセスできます。
システムが共有データ blob を保持し、どのアプリがそれにアクセスできるかを管理します。アプリがデータ blob を提供する際、以下のいずれかのメソッドを呼び出して、他にどのアプリがアクセス権を持つかを指定できます。
- デバイス上の特定のアプリのセットにアクセス権を付与するには、それらのアプリのパッケージ名を
allowPackageAccess()
に渡します。 - 自分のアプリに使用する鍵と同じ鍵で署名された証明書を持つアプリ(自分が管理するアプリスイートなど)にのみアクセスを許可する場合は、
allowSameSignatureAccess()
を呼び出します。 - デバイス上のすべてのアプリにアクセス権を付与するには、
allowPublicAccess()
を呼び出します。
共有データ blob にアクセスする
システムは各共有データ blob を BlobHandle
オブジェクトを使って表します。BlobHandle
の各インスタンスには、暗号化されて安全なハッシュと、そのデータセットを識別できるなんらかの詳細情報が含まれます。
共有データ blob にアクセスするには、サーバーから識別情報をダウンロードします。この情報を使って、データセットがシステムですでに利用可能かどうかを確認します。
次のステップは、データが利用可能かどうかによって異なります。
データセットが利用できる
データセットがそのデバイス上ですでに利用できる場合は、次のコード スニペットに示すように、システムからアクセスします。
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); } }
データセットが利用できない
データセットが利用できない場合は、次のコード スニペットに示すように、サーバーからデータセットをダウンロードして、システムに提供します。
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); } }