גישה למערכי נתונים משותפים

החל מ-Android 11 (רמת API 30), המערכת שומרת במטמון מערכי נתונים גדולים אפליקציות רבות יכולות לגשת לתרחישים לדוגמה כמו למידת מכונה ומדיה להפעלה. הפונקציונליות הזו עוזרת לצמצם יתירות נתונים, גם ברשת ובדיסק.

כשהאפליקציה צריכה גישה למערך נתונים גדול משותף, היא יכולה לחפש תחילה מערכי הנתונים השמורים במטמון, שנקראים blobs של נתונים משותפים, לפני שנקבע אם מורידים עותק חדש. האפליקציות יכולות לגשת לפונקציונליות של מערכי הנתונים המשותפים האלה באמצעות ממשקי ה-API ב-BlobStoreManager.

המערכת שומרת את ה-blobs המשותפים של הנתונים וקובעת לאילו אפליקציות יש גישה אותם. כשהאפליקציה שלך תורמת blobs של נתונים, אפשר לציין אילו אפליקציות אחרות צריכה להיות גישה באמצעות אחת מהשיטות הבאות:

  • כדי להעניק גישה לקבוצה ספציפית של אפליקציות במכשיר, צריך להעביר את שמות החבילות מהאפליקציות האלה בתוך allowPackageAccess()
  • כדי להתיר רק אפליקציות שהאישורים שלהן נחתמו באמצעות אותו מפתח כמו המפתח שמשמש את האפליקציה שלך, כמו חבילת אפליקציות שאתה מנהל, התקשר allowSameSignatureAccess()
  • כדי להעניק גישה לכל האפליקציות במכשיר, צריך להתקשר allowPublicAccess()

גישה ל-blobs של נתונים משותפים

המערכת מייצגת כל blob של נתונים משותפים באמצעות אובייקט BlobHandle. כל מופע של BlobHandle שמכיל גיבוב (hash) מאובטח מבחינה קריפטוגרפית וכמה פרטים מזהים של של הכיתובים.

כדי לגשת ל-blobs משותפים של נתונים, צריך להוריד מהשרת את הפרטים המזהים. באמצעות יש לבדוק אם מערך הנתונים כבר זמין במערכת.

השלב הבא תלוי בזמינות של הנתונים.

מערך הנתונים זמין

אם מערך הנתונים כבר זמין במכשיר, ניגשים אליו מהמערכת, כפי שמוצג בקטע הקוד הבא:

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