存取共用資料集

自 Android 11 (API 級別 30) 起,系統會快取多個應用程式可能會存取的大型資料集,例如機器學習和媒體播放。這項功能有助於減少網路和磁碟上的資料備援。

如果應用程式需要存取共用的大型資料集,可以先查看這些快取資料集 (稱為共用資料 blob),再決定是否要下載新副本。應用程式可透過 BlobStoreManager 中的 API,存取這些共用資料集功能。

系統會維護共用資料 blob,並控管哪些應用程式可以存取。應用程式提供資料 blob 時,您可以呼叫下列任一方法,來表明哪些應用程式應具備存取權:

  • 如要對裝置上的特定應用程式集授予存取權,請將這些應用程式的套件名稱傳遞至 allowPackageAccess()
  • 如要僅允許使用與您的應用程式 (如您管理的應用程式套件) 相同的金鑰來簽署憑證的應用程式,請呼叫 allowSameSignatureAccess()
  • 如要對裝置上的所有應用程式授予存取權,請呼叫 allowPublicAccess()

存取共用資料 blob

系統以 BlobHandle 物件來代表每個共用資料 blob。每個 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);
    }
}