גיבוי של נתוני משתמשים באמצעות גיבוי אוטומטי

גיבוי אוטומטי לאפליקציות מגבה באופן אוטומטי את נתוני המשתמש מאפליקציות שמטרגטות ופועלות ב-Android 6.0 (רמת API ‏23) ואילך. מערכת Android שומרת את נתוני האפליקציה על ידי העלאה שלהם ל-Google Drive של המשתמש, שם הם מוגנים באמצעות פרטי הכניסה לחשבון Google של המשתמש. הגיבוי מוצפן מקצה לקצה במכשירים עם Android 9 ומעלה באמצעות קוד האימות, קו ביטול הנעילה או הסיסמה של המכשיר. כל אפליקציה יכולה להקצות עד 25 MB של נתוני גיבוי לכל משתמש באפליקציה. אין תשלום על אחסון נתוני גיבוי. האפליקציה יכולה להתאים אישית את תהליך הגיבוי או לבטל את הגיבוי על ידי השבתת הגיבויים.

סקירה כללית של אפשרויות הגיבוי ב-Android והנחיות לגבי הנתונים שכדאי לגבות ולשחזר מופיעות במאמר סקירה כללית של גיבוי נתונים.

קבצים שמגובים

כברירת מחדל, הגיבוי האוטומטי כולל קבצים ברוב הספריות שהמערכת מקצה לאפליקציה:

הגיבוי האוטומטי לא כולל קבצים בספריות שמוחזרות על ידי getCacheDir(),‏ getCodeCacheDir() ו-getNoBackupFilesDir(). הקבצים שנשמרים במיקומים האלה נדרשים רק באופן זמני, והם מוחרגים בכוונה מפעולות הגיבוי.

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

מיקום הגיבוי

נתוני הגיבוי מאוחסנים בתיקייה פרטית בחשבון Google Drive של המשתמש, עד 25 MB לכל אפליקציה. הנתונים השמורים לא נכללים במכסת האחסון האישית ב-Google Drive של המשתמש. נשמר רק הגיבוי האחרון. כשמבצעים גיבוי, כל הגיבויים הקודמים נמחקים. המשתמש או אפליקציות אחרות במכשיר לא יכולים לקרוא את נתוני הגיבוי.

משתמשים יכולים לראות רשימה של אפליקציות שגובו באפליקציית Google Drive ל-Android. במכשיר עם Android, הרשימה הזו מופיעה במגירת הניווט של אפליקציית Drive בקטע הגדרות > גיבוי ואיפוס.

גיבויים מכל מכשיר – הגדרה – משך שימוש מאוחסנים במערכי נתונים נפרדים, כמו שמתואר בדוגמאות הבאות:

  • אם המשתמש הוא הבעלים של שני מכשירים, יהיה מערך נתונים של גיבוי לכל מכשיר.

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

לו"ז גיבוי

הגיבויים מתבצעים אוטומטית אם כל התנאים הבאים מתקיימים:

  • המשתמש הפעיל את הגיבוי במכשיר. ב-Android 9, ההגדרה הזו נמצאת בהגדרות > מערכת > גיבוי.
  • חלפו לפחות 24 שעות מאז הגיבוי האחרון.
  • המכשיר לא פעיל.
  • המכשיר מחובר לרשת Wi-Fi (אם המשתמש במכשיר לא בחר להשתמש בגיבויים של חבילת הגלישה).

בפועל, התנאים האלה מתקיימים בערך כל לילה, אבל יכול להיות שמכשיר מסוים אף פעם לא יגבה (למשל, אם הוא אף פעם לא מתחבר לרשת). כדי לחסוך ברוחב הפס של הרשת, ההעלאה מתבצעת רק אם נתוני האפליקציה השתנו.

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

כדי לפשט את הבדיקה, Android כולל כלים שמאפשרים להתחיל גיבוי של האפליקציה באופן ידני. מידע נוסף זמין במאמר בדיקת גיבוי ושחזור.

שחזור לוח הזמנים

הנתונים משוחזרים בכל פעם שהאפליקציה מותקנת, בין אם מחנות Play, במהלך הגדרת המכשיר (כשהמערכת מתקינה אפליקציות שהותקנו בעבר) או על ידי הפעלת adb install. פעולת השחזור מתרחשת אחרי התקנת ה-APK אבל לפני שהאפליקציה זמינה להפעלה על ידי המשתמש.

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

כדי לפשט את הבדיקה, Android כולל כלים שמאפשרים להתחיל ידנית בשחזור של האפליקציה. מידע נוסף זמין במאמר בדיקת גיבוי ושחזור.

הפעלה והשבתה של הגיבוי

אפליקציות שמטרגטות ל-Android 6.0 (רמת API ‏23) ואילך משתתפות באופן אוטומטי בגיבוי אוטומטי. בקובץ המניפסט של האפליקציה, מגדירים את הערך הבוליאני android:allowBackup כדי להפעיל או להשבית את הגיבוי. ערך ברירת המחדל הוא true, אבל מומלץ להגדיר את המאפיין באופן מפורש בקובץ המניפסט, כמו בדוגמה הבאה:

<manifest ... >
    ...
    <application android:allowBackup="true" ... >
        ...
    </application>
</manifest>

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

הכללה והחרגה של קבצים

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

אתם יכולים לקבוע אילו נתונים ייכללו בגיבוי בהתאם לסוג ההעברה. הגיבוי האוטומטי תומך בגיבויים בענן ב-Google Drive ובהעברות ישירות ממכשיר למכשיר (D2D). שיטות ההגדרה משתנות בהתאם לגרסת Android ולtargetSdkVersion של האפליקציה.

שליטה בגיבוי ב-Android מגרסה 11 ומטה

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

  1. בקובץ AndroidManifest.xml, מוסיפים את המאפיין android:fullBackupContent לרכיב <application>, כמו בדוגמה הבאה. המאפיין הזה מצביע על קובץ XML שמכיל כללי גיבוי.

    <application ...
     android:fullBackupContent="@xml/backup_rules">
    </application>
  2. יוצרים קובץ XML בשם @xml/backup_rules בספרייה res/xml/. בקובץ הזה, מוסיפים כללים עם האלמנטים <include> ו-<exclude>. בדוגמה הבאה מגבים את כל ההעדפות המשותפות חוץ מ-device.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <full-backup-content>
     <include domain="sharedpref" path="."/>
     <exclude domain="sharedpref" path="device.xml"/>
    </full-backup-content>

הגדרת תנאי המכשיר שנדרשים לגיבוי

אם האפליקציה שומרת מידע רגיש במכשיר, אפשר לציין תנאים שלפיהם הנתונים של האפליקציה ייכללו בגיבוי של המשתמש. אפשר להוסיף את התנאים הבאים ב-Android 9 (רמת API 28) ומעלה:

אם שדרגתם את מכשירי הפיתוח שלכם ל-Android 9, אתם צריכים להשבית ואז להפעיל מחדש את גיבוי הנתונים אחרי השדרוג. הסיבה לכך היא שמערכת Android מצפינה גיבויים רק באמצעות סוד בצד הלקוח, אחרי שהיא מודיעה למשתמשים בהגדרות או באשף ההגדרה.

כדי להצהיר על תנאי ההכללה, מגדירים את המאפיין requireFlags לערך או לערכים נבחרים ברכיבי <include> בתוך קבוצת כללי הגיבוי:

backup_rules.xml

<?xml version="1.0" encoding="utf-8"?>
<full-backup-content>
    <!-- App data isn't included in user's backup
         unless client-side encryption is enabled. -->
    <include domain="file" path="."
             requireFlags="clientSideEncryption" />
</full-backup-content>

אם האפליקציה שלכם מטמיעה מערכת גיבוי של צמדי מפתח/ערך או אם הטמעתםBackupAgent בעצמכם, אתם יכולים גם להחיל את הדרישות המותנות האלה על לוגיקת הגיבוי שלכם. לשם כך, מבצעים השוואה ברמת הביטים בין קבוצת דגלי התעבורה של אובייקט BackupDataOutput לבין הדגלים FLAG_CLIENT_SIDE_ENCRYPTION_ENABLED או FLAG_DEVICE_TO_DEVICE_TRANSFER של סוכן הגיבוי המותאם אישית שלכם.

בקטע הקוד הבא יש דוגמה לשימוש במתודה הזו:

Kotlin

class CustomBackupAgent : BackupAgent() {
    override fun onBackup(oldState: ParcelFileDescriptor?,
            data: BackupDataOutput?, newState: ParcelFileDescriptor?) {
        if (data != null) {
            if ((data.transportFlags and
                    FLAG_CLIENT_SIDE_ENCRYPTION_ENABLED) != 0) {
                // Client-side backup encryption is enabled.
            }

            if ((data.transportFlags and FLAG_DEVICE_TO_DEVICE_TRANSFER) != 0) {
                // Local device-to-device transfer is enabled.
            }
        }
    }

    // Implementation of onRestore() here.
}

Java

public class CustomBackupAgent extends BackupAgent {
    @Override
    public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
            ParcelFileDescriptor newState) throws IOException {
        if ((data.getTransportFlags() &
                FLAG_CLIENT_SIDE_ENCRYPTION_ENABLED) != 0) {
            // Client-side backup encryption is enabled.
        }

        if ((data.getTransportFlags() &
                FLAG_DEVICE_TO_DEVICE_TRANSFER) != 0) {
            // Local device-to-device transfer is enabled.
        }
    }

    // Implementation of onRestore() here.
}

שליטה בגיבוי ב-Android 12 ואילך

אם האפליקציה מטרגטת את Android 12 (רמת API‏ 31) או גרסה מתקדמת יותר, צריך לפעול לפי השלבים שבקטע הזה כדי לקבוע אילו קבצים מגובים במכשירים שמופעלת בהם גרסה Android 12 או גרסה מתקדמת יותר.

  1. בקובץ AndroidManifest.xml, מוסיפים את המאפיין android:dataExtractionRules לרכיב <application>, כמו בדוגמה הבאה. המאפיין הזה מצביע על קובץ XML שמכיל כללי גיבוי.

    <application ...
     android:dataExtractionRules="backup_rules.xml">
    </application>
  2. יוצרים קובץ XML בשם backup_rules.xml בספרייה res/xml/. בקובץ הזה, מוסיפים כללים עם האלמנטים <include> ו-<exclude>. בדוגמה הבאה מגבים את כל ההעדפות המשותפות, למעט device.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <data-extraction-rules>
     <cloud-backup [disableIfNoEncryptionCapabilities="true|false"]>
       <include domain="sharedpref" path="."/>
       <exclude domain="sharedpref" path="device.xml"/>
     </cloud-backup>
    </data-extraction-rules>

תחביר של הגדרות ב-XML

תחביר ה-XML של קובץ ההגדרה משתנה בהתאם לגרסת Android שהאפליקציה מטרגטת ופועלת בה.

‫Android מגרסה 11 ומטה

משתמשים בתחביר ה-XML הבא לקובץ ההגדרות ששולט בגיבוי של מכשירים עם Android מגרסה 11 ומטה.

<full-backup-content>
    <include domain=["file" | "database" | "sharedpref" | "external" |
                     "root" | "device_file" | "device_database" |
                     "device_sharedpref" | "device_root" ] path="string"
    requireFlags=["clientSideEncryption" | "deviceToDeviceTransfer"] />
    <exclude domain=["file" | "database" | "sharedpref" | "external" |
                     "root" | "device_file" | "device_database" |
                     "device_sharedpref" | "device_root" ] path="string" />
</full-backup-content>

‫Android מגרסה 12 ואילך

אם האפליקציה מיועדת ל-Android 12 (רמת API‏ 31) או לגרסה מתקדמת יותר, צריך להשתמש בתחביר XML הבא עבור קובץ ההגדרות ששולט בגיבוי במכשירים עם Android 12 או גרסה מתקדמת יותר.

<data-extraction-rules>
  <cloud-backup [disableIfNoEncryptionCapabilities="true|false"]>
    ...
    <include domain=["file" | "database" | "sharedpref" | "external" |
                     "root" | "device_file" | "device_database" |
                     "device_sharedpref" | "device_root" ] path="string"/>
    ...
    <exclude domain=["file" | "database" | "sharedpref" | "external" |
                     "root" | "device_file" | "device_database" |
                     "device_sharedpref" | "device_root" ] path="string"/>
    ...
  </cloud-backup>
  <device-transfer>
    ...
    <include domain=["file" | "database" | "sharedpref" | "external" |
                     "root" | "device_file" | "device_database" |
                     "device_sharedpref" | "device_root" ] path="string"/>
    ...
    <exclude domain=["file" | "database" | "sharedpref" | "external" |
                     "root" | "device_file" | "device_database" |
                     "device_sharedpref" | "device_root" ] path="string"/>
    ...
  </device-transfer>
  <cross-platform-transfer platform="ios">
    ...
    <include domain=["file" | "database" | "sharedpref" | "external" |
                     "root" | "device_file" | "device_database" |
                     "device_sharedpref" | "device_root" ] path="string"/>
    ...
    <exclude domain=["file" | "database" | "sharedpref" | "external" |
                     "root" | "device_file" | "device_database" |
                     "device_sharedpref" | "device_root" ] path="string"/>
    ...
    <platform-specific-params bundleId="string" teamId="string" contentVersion="string"/>
    ...
  </cross-platform-transfer>
</data-extraction-rules>

כל קטע בהגדרה (<cloud-backup>, ‏<device-transfer>, ‏<cross-platform-transfer>) מכיל כללים שחלים רק על סוג ההעברה הזה. ההפרדה הזו מאפשרת לכם, למשל, להחריג קובץ או ספרייה מגיבויים של Google Drive, ועדיין להעביר אותם במהלך העברות ממכשיר למכשיר (D2D) או העברות בין פלטפורמות. האפשרות הזו שימושית אם יש לכם קבצים גדולים מדי לגיבוי בענן, אבל אפשר להעביר אותם בין מכשירים בלי בעיה.

אם אין כללים למצב גיבוי מסוים, למשל אם הקטע <device-transfer> חסר, המצב הזה מופעל באופן מלא לכל התוכן, למעט הספריות no-backup ו-cache, כפי שמתואר בקטע קבצים שמגובים.

באפליקציה אפשר להגדיר את הדגל disableIfNoEncryptionCapabilities בקטע <cloud-backup> כדי לוודא שהגיבוי יתבצע רק אם אפשר להצפין אותו, למשל כשהמשתמש הגדיר מסך נעילה. הגדרת האילוץ הזה מונעת שליחה של גיבויים לענן אם המכשיר של המשתמש לא תומך בהצפנה, אבל מכיוון שהעברות D2D לא נשלחות לשרת, הן ממשיכות לפעול גם במכשירים שלא תומכים בהצפנה.

תחביר של רכיבי הכללה והחרגה

בתוך התגים <full-backup-content>, <cloud-backup> ו-<device-transfer> (בהתאם לגרסת Android של המכשיר ול-targetSDKVersion של האפליקציה), אפשר להגדיר את הרכיבים <include> ו-<exclude>:

<include>

מציינים קובץ או תיקייה לגיבוי. כברירת מחדל, הגיבוי האוטומטי כולל כמעט את כל קובצי האפליקציות. אם מציינים רכיב <include>, המערכת לא כוללת יותר קבצים כברירת מחדל ומגבה רק את הקבצים שצוינו. כדי לכלול כמה קבצים, צריך להשתמש בכמה רכיבי <include>.

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

קבצים בספריות שמוחזרים על ידי getCacheDir(), getCodeCacheDir() או getNoBackupFilesDir() תמיד נכללים, גם אם מנסים לכלול אותם.

<exclude>

מציינים קובץ או תיקייה שיוחרגו במהלך הגיבוי. אלה כמה קבצים שבדרך כלל לא נכללים בגיבוי:

  • קבצים עם מזהים ספציפיים למכשיר, שהונפקו על ידי שרת או נוצרו במכשיר. לדוגמה, שירות העברת ההודעות בענן ב-Firebase ‏(FCM) צריך ליצור אסימון רישום בכל פעם שמשתמש מתקין את האפליקציה במכשיר חדש. אם משחזרים את טוקן הרישום הישן, יכול להיות שהאפליקציה תתנהג בצורה לא צפויה.

  • קבצים שקשורים לניפוי באגים באפליקציה.

  • קבצים גדולים שגורמים לאפליקציה לחרוג ממכסת הגיבוי של 25 MB.

כל רכיב <include> ו-<exclude> חייב לכלול את שני המאפיינים הבאים:

domain

מציין את מיקום המשאב. הערכים החוקיים של המאפיין הזה כוללים את האפשרויות הבאות:

  • root: הספרייה במערכת הקבצים שבה מאוחסנים כל הקבצים הפרטיים ששייכים לאפליקציה הזו.
  • file: ספריות שהוחזרו על ידי getFilesDir().
  • database: ספריות שהוחזרו על ידי getDatabasePath(). מסדי נתונים שנוצרו באמצעות SQLiteOpenHelper מאוחסנים כאן.
  • sharedpref: הספרייה שבה מאוחסנים SharedPreferences.
  • external: המדריך שמוחזר על ידי getExternalFilesDir().
  • device_root: כמו root אבל לאחסון שמוגן על ידי המכשיר.
  • device_file: כמו file אבל לאחסון שמוגן על ידי המכשיר.
  • device_database: כמו database אבל לאחסון שמוגן על ידי המכשיר.
  • device_sharedpref: כמו sharedpref אבל לאחסון שמוגן על ידי המכשיר.
path

מציינים קובץ או תיקייה שרוצים לכלול בגיבוי או להחריג ממנו. חשוב לזכור:

  • המאפיין הזה לא תומך בתווים כלליים לחיפוש או בתחביר של ביטויים רגולריים.
  • אפשר להפנות לספרייה הנוכחית באמצעות ./, אבל אי אפשר להפנות לספריית האב, למשל באמצעות .., מסיבות אבטחה.
  • אם מציינים ספרייה, הכלל חל על כל הקבצים בספרייה ובספריות המשנה הרקורסיביות.

הגדרת העברות בין פלטפורמות

החל מ-Android 16 QPR2 (רמת API‏ 36.1), אפשר להגדיר גיבוי אוטומטי להעברת נתונים אל מכשירים שהם לא מכשירי Android וממכשירים כאלה. כדי לעשות זאת, מוסיפים את האלמנט <cross-platform-transfer> בתוך ההגדרה <data-extraction-rules>, כמו שמוצג בתחביר של Android 12 ואילך. חובה לציין את פלטפורמת היעד באמצעות מאפיין החובה platform. הערך הנתמך היחיד הוא ios.

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

בנוסף, צריך לכלול את הרכיב <platform-specific-params> כדי לעזור למערכת להתאים את האפליקציה לאפליקציה התואמת בפלטפורמת היעד. לאלמנט הזה יש את מאפייני החובה הבאים:

  • bundleId: מזהה החבילה של האפליקציה בפלטפורמה השנייה (לדוגמה, מזהה החבילה של האפליקציה ל-iOS).
  • teamId: מזהה הצוות של האפליקציה בפלטפורמה השנייה (לדוגמה, מזהה הצוות של אפליקציית iOS).
  • contentVersion: מחרוזת של גרסה שאתם מגדירים, שמשויכת לפורמט הנתונים שמיוצאים.

המאפיינים bundleId ו-teamId משמשים כדי לאמת את תקינות הנתונים ואת ההתאמה הנכונה בין האפליקציות. הם מבטיחים שהנתונים יועברו אל האפליקציה שצוינה בפלטפורמה השנייה במהלך הייצוא, ושהאפליקציה הזו ל-Android תייבא נתונים רק מהאפליקציה הספציפית הזו במהלך הייבוא.

כדי לקבל שליטה פרטנית יותר בתהליך של טרנספורמציה והעברה של נתונים, מעבר למה שכללי ה-XML מספקים, אפשר להטמיע BackupAgent מותאם אישית ולהשתמש בממשקי ה-API של העברה בין פלטפורמות.

מיפוי קבצים להעברות ב-iOS

כשמעבירים קבצים ל-iOS, המיפוי של domain ו-path ב-Android שציינתם בכללי <include> הוא למבנה ספריות ספציפי. בטבלה הבאה מוצגים נתיבי היעד ב-iOS ביחס לשורש של יעד ההעברה, על סמך domain ב-Android:

Android domain הנתיב ב-iOS (ביחס לתיקיית השורש של ההעברה)
root app/
file app/files/
database app/databases/
sharedpref app/shared_prefs/
external external/files/
device_root device/app/
device_file device/app/files/
device_database device/app/databases/
device_sharedpref device/app/shared_prefs/

לדוגמה, קובץ שכלול ב-<include domain="file" path="my_settings.txt"/> יהיה זמין בצד של iOS בנתיב app/files/my_settings.txt ביחס לשורש של יעד ההעברה.

הטמעה של BackupAgent

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

  • אתם רוצים לקבל התראות על אירועים שקשורים לגיבוי, כמו onRestoreFinished() ו-onQuotaExceeded(). השיטות האלה של קריאה חוזרת מופעלות גם אם האפליקציה לא פועלת.

  • אי אפשר להגדיר בקלות את קבוצת הקבצים שרוצים לגבות באמצעות כללי XML. במקרים הנדירים האלה, אפשר להטמיע BackupAgent שמבטל את onFullBackup(FullBackupDataOutput) כדי לאחסן את מה שרוצים. כדי לשמור על הטמעת ברירת המחדל של המערכת, צריך להפעיל את השיטה המתאימה במחלקת העל עם super.onFullBackup().

אם מטמיעים BackupAgent, כברירת מחדל המערכת מצפה שהאפליקציה תבצע גיבוי ושחזור של צמדי מפתח/ערך. כדי להשתמש בגיבוי אוטומטי מבוסס-קבצים, צריך להגדיר את מאפיין android:fullBackupOnly לערך true במניפסט של האפליקציה.

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

ב-BackupAgent צריך להטמיע את השיטות המופשטות onBackup() ו-onRestore(), שמשמשות לגיבוי של זוגות מפתח/ערך. אם לא רוצים לבצע גיבוי של זוגות מפתח/ערך, אפשר להשאיר את ההטמעה של השיטות האלה ריקה.

מידע נוסף זמין במאמר בנושא הרחבת BackupAgent.

טיפול בהעברות בין פלטפורמות ב-BackupAgent

החל מ-Android 16 QPR2 (רמת API‏ 36.1), יש כמה ממשקי API חדשים ב-BackupAgent כדי לשפר את התמיכה בהעברות נתונים בין פלטפורמות.

דגל חדש של העברה:

  • FLAG_CROSS_PLATFORM_TRANSFER_IOS: הדגל הזה מתווסף ל-transportFlags שסופק ל-BackupAgent.
    • בדגל onFullBackup, הערך מוגדר אם פעולת הגיבוי הנוכחית היא חלק מייצוא נתונים למכשיר iOS.
    • בעומס היתר החדש onRestoreFile, הדגל הזה מוגדר אם הנתונים מיובאים ממכשיר iOS.

שיטת onRestoreFile חדשה:

נוספה עומס יתר חדש של onRestoreFile, שמקבל פרמטר יחיד של FullRestoreDataInput. האובייקט הזה מספק הקשר נוסף לגבי פעולת השחזור:

  • FullRestoreDataInput.getTransportFlags(): מחזירה את דגלי ההעברה של פעולת השחזור הנוכחית, שיכולים לכלול את FLAG_CROSS_PLATFORM_TRANSFER_IOS.
  • FullRestoreDataInput.getContentVersion(): מחזירה את מחרוזת גרסת התוכן שסופקה על ידי אפליקציית המקור בפלטפורמה השנייה במהלך העברה בין פלטפורמות. אם הערך לא מסופק על ידי המקור, הוא מחרוזת ריקה.

שיטה חדשה להערכת גודל:

  • onEstimateFullBackupBytes(): השיטה הזו מאפשרת לספק הערכה של גודל הנתונים שהאפליקציה מתכוונת לגבות. מומלץ מאוד להטמיע את התכונה הזו אם האפליקציה מבצעת טרנספורמציות משמעותיות של נתונים במהלך הגיבוי או מטפלת בנפח גדול של נתונים, כי היא יכולה לשפר את היעילות על ידי הימנעות מהרצת בדיקה יבשה של המערכת כברירת מחדל. בדרך כלל אין צורך בשיטה הזו באפליקציות עם גיבויים קטנים ופשוטים.

דוגמה לשימוש:

Kotlin

// In your custom BackupAgent class

override fun onFullBackup(out: FullBackupDataOutput) {
    // Check if this is a cross-platform export to iOS
    if ((out.transportFlags and FLAG_CROSS_PLATFORM_TRANSFER_IOS) != 0) {
        Log.d(TAG, "onFullBackup for iOS transfer")
        // Your custom export logic here
        // Call fullBackupFile() for files to include
    }
}

override fun onRestoreFile(input: FullRestoreDataInput) {
    if ((input.transportFlags and FLAG_CROSS_PLATFORM_TRANSFER_IOS) != 0) {
        val sourceContentVersion = input.contentVersion
        Log.d(TAG, "onRestoreFile from iOS, content version: $sourceContentVersion")
        // Your custom import logic here, using input.data, input.destination, etc.
    }
}

// Optional: Provide an estimate of the backup size
override fun onEstimateFullBackupBytes(): Long {
    return calculateEstimatedBackupSize()
}

Java

// In your custom BackupAgent class

@Override
public void onFullBackup(FullBackupDataOutput out) throws IOException {
    // Check if this is a cross-platform export to iOS
    if ((out.getTransportFlags() & FLAG_CROSS_PLATFORM_TRANSFER_IOS) != 0) {
        Log.d(TAG, "onFullBackup for iOS transfer");
        // Your custom export logic here
        // Call fullBackupFile() for files to include
    }
}

@Override
public void onRestoreFile(FullRestoreDataInput input) {
    if ((input.getTransportFlags() & FLAG_CROSS_PLATFORM_TRANSFER_IOS) != 0) {
        String sourceContentVersion = input.getContentVersion();
        Log.d(TAG, "onRestoreFile from iOS, content version: " + sourceContentVersion);
        // Your custom import logic here, using input.getData(), input.getDestination(), etc.
    }
}

// Optional: Provide an estimate of the backup size
@Override
public long onEstimateFullBackupBytes() {
    return calculateEstimatedBackupSize();
}