สำรองข้อมูลผู้ใช้ด้วยการสำรองข้อมูลอัตโนมัติ

การสำรองข้อมูลอัตโนมัติสำหรับแอปจะสำรองข้อมูลของผู้ใช้จากแอปที่กำหนดเป้าหมายและทำงานใน Android 6.0 (API ระดับ 23) ขึ้นไปโดยอัตโนมัติ Android จะเก็บรักษาข้อมูลแอปโดยการอัปโหลดไปยัง Google ไดรฟ์ของผู้ใช้ ซึ่งได้รับการปกป้องโดยข้อมูลเข้าสู่ระบบบัญชี Google ของผู้ใช้ การสำรองข้อมูลจะได้รับการเข้ารหัสจากต้นทางถึงปลายทางในอุปกรณ์ที่ใช้ Android 9 ขึ้นไปโดยใช้ PIN, รูปแบบ หรือรหัสผ่านของอุปกรณ์ ทุกแอป สามารถจัดสรรข้อมูลสำรองได้สูงสุด 25 MB ต่อผู้ใช้แอป ไม่มีค่าใช้จ่าย ในการจัดเก็บข้อมูลสำรอง แอปของคุณปรับแต่งกระบวนการสำรองข้อมูลหรือเลือกไม่ใช้ได้โดยปิดใช้การสำรองข้อมูล

ดูภาพรวมตัวเลือกการสำรองข้อมูลของ Android และคำแนะนำเกี่ยวกับข้อมูลที่จะสำรองและกู้คืนได้ที่ภาพรวมการสำรองข้อมูล

ไฟล์ที่สำรองข้อมูล

โดยค่าเริ่มต้น การสำรองข้อมูลอัตโนมัติจะรวมไฟล์ในไดเรกทอรีส่วนใหญ่ที่ระบบ กำหนดให้กับแอปของคุณ

  • ไฟล์ Shared Preferences

  • ไฟล์ที่บันทึกลงในที่จัดเก็บข้อมูลภายในของแอปและเข้าถึงโดย getFilesDir() หรือ getDir(String, int)

  • ไฟล์ในไดเรกทอรีที่ getDatabasePath(String) ส่งคืน ซึ่งรวมถึงไฟล์ที่สร้างด้วยคลาส SQLiteOpenHelper ด้วย

  • ไฟล์ในที่เก็บข้อมูลภายนอกในไดเรกทอรีที่ส่งคืนโดย getExternalFilesDir(String)

การสำรองข้อมูลอัตโนมัติจะยกเว้นไฟล์ในไดเรกทอรีที่ส่งคืนโดย getCacheDir() getCodeCacheDir() และ getNoBackupFilesDir() ไฟล์ที่บันทึกไว้ใน ตำแหน่งเหล่านี้จำเป็นต้องใช้ชั่วคราวเท่านั้น และเราตั้งใจที่จะยกเว้นไฟล์เหล่านี้จากการ ดำเนินการสำรองข้อมูล

คุณสามารถกำหนดค่าแอปให้รวมและยกเว้นไฟล์ที่ต้องการได้ ดูข้อมูลเพิ่มเติมได้ที่ส่วนรวมและยกเว้นไฟล์

ตำแหน่งของข้อมูลสำรอง

ระบบจะจัดเก็บข้อมูลสำรองไว้ในโฟลเดอร์ส่วนตัวในบัญชี Google ไดรฟ์ของผู้ใช้ โดยจำกัดไว้ที่ 25 MB ต่อแอป ข้อมูลที่บันทึกไว้จะไม่นับรวมในโควต้า Google ไดรฟ์ส่วนตัวของผู้ใช้ ระบบจะจัดเก็บเฉพาะข้อมูลสำรองล่าสุด เมื่อสร้างข้อมูลสำรอง ระบบจะลบข้อมูลสำรองก่อนหน้า ผู้ใช้หรือแอปอื่นๆ ในอุปกรณ์จะอ่านข้อมูลสำรองไม่ได้

ผู้ใช้จะเห็นรายการแอปที่สำรองข้อมูลไว้ในแอป Google Drive สำหรับ Android ในอุปกรณ์ที่ใช้ Android ผู้ใช้จะเห็นรายการนี้ในลิ้นชักการนำทางของแอป Drive ในส่วนการตั้งค่า > สำรองข้อมูลและรีเซ็ต

ระบบจะจัดเก็บข้อมูลสำรองจากแต่ละช่วงเวลาการตั้งค่าอุปกรณ์ไว้ในชุดข้อมูลแยกต่างหาก ดังที่อธิบายไว้ในตัวอย่างต่อไปนี้

  • หากผู้ใช้มีอุปกรณ์ 2 เครื่อง ก็จะมีชุดข้อมูลสำรองสำหรับอุปกรณ์แต่ละเครื่อง

  • หากผู้ใช้รีเซ็ตอุปกรณ์เป็นค่าเริ่มต้น แล้วตั้งค่าอุปกรณ์ด้วย บัญชีเดียวกัน ระบบจะจัดเก็บข้อมูลสำรองไว้ในชุดข้อมูลใหม่ ระบบจะลบชุดข้อมูลที่ล้าสมัยโดยอัตโนมัติหลังจากที่ไม่มีการใช้งานในระยะเวลาหนึ่ง

กำหนดการสำรองข้อมูล

ระบบจะสำรองข้อมูลโดยอัตโนมัติเมื่อเป็นไปตามเงื่อนไขทั้งหมดต่อไปนี้

  • ผู้ใช้ได้เปิดใช้การสำรองข้อมูลในอุปกรณ์ ใน Android 9 การตั้งค่านี้จะอยู่ในการตั้งค่า > ระบบ > การสำรองข้อมูล
  • เวลาผ่านไปอย่างน้อย 24 ชั่วโมงนับตั้งแต่การสำรองข้อมูลครั้งล่าสุด
  • อุปกรณ์อยู่ในสถานะไม่มีการใช้งาน
  • อุปกรณ์เชื่อมต่อกับเครือข่าย Wi-Fi (หากผู้ใช้อุปกรณ์ไม่ได้เลือกใช้การสำรองข้อมูลผ่านอินเทอร์เน็ตมือถือ)

ในทางปฏิบัติ เงื่อนไขเหล่านี้จะเกิดขึ้นทุกคืนโดยประมาณ แต่อุปกรณ์อาจไม่เคยสำรองข้อมูลเลย (เช่น หากไม่เคยเชื่อมต่อกับเครือข่าย) การอัปโหลดจะเกิดขึ้นก็ต่อเมื่อข้อมูลแอปมีการเปลี่ยนแปลงเท่านั้น เพื่อประหยัดแบนด์วิดท์ของเครือข่าย

ในระหว่างการสำรองข้อมูลอัตโนมัติ ระบบจะปิดแอปเพื่อให้แน่ใจว่าแอปจะไม่เขียนไปยังระบบไฟล์อีกต่อไป โดยค่าเริ่มต้น ระบบสำรองข้อมูลจะไม่สนใจแอปที่ ทำงานในเบื้องหน้าเพื่อหลีกเลี่ยงประสบการณ์การใช้งานที่ไม่ดี คุณจะลบล้างลักษณะการทำงานเริ่มต้นได้โดยตั้งค่าแอตทริบิวต์ android:backupInForeground เป็น true

Android มีเครื่องมือที่ช่วยให้คุณเริ่มการสำรองข้อมูลแอปด้วยตนเองได้เพื่อลดความซับซ้อนในการทดสอบ ดูข้อมูลเพิ่มเติมได้ที่ทดสอบการสำรองและกู้คืนข้อมูล

คืนค่ากำหนดเวลา

ระบบจะกู้คืนข้อมูลทุกครั้งที่มีการติดตั้งแอป ไม่ว่าจะจาก Play Store ระหว่างการตั้งค่าอุปกรณ์ (เมื่อระบบติดตั้งแอปที่ติดตั้งไว้ก่อนหน้านี้) หรือโดยการ เรียกใช้ adb install การดำเนินการกู้คืนจะเกิดขึ้นหลังจากติดตั้ง APK แต่ก่อนที่ผู้ใช้จะเปิดแอปได้

ในระหว่างวิซาร์ดการตั้งค่าอุปกรณ์เริ่มต้น ระบบจะแสดงรายการชุดข้อมูลสำรองที่มีให้แก่ผู้ใช้ และถามว่าต้องการกู้คืนข้อมูลจากชุดข้อมูลใด ชุดข้อมูลสำรอง ที่เลือกจะกลายเป็นชุดข้อมูลต้นทางของอุปกรณ์ อุปกรณ์สามารถ กู้คืนจากข้อมูลสำรองของตัวเองหรือชุดข้อมูลบรรพบุรุษ หากมีข้อมูลสำรองจากทั้ง 2 แหล่งที่มา อุปกรณ์จะจัดลำดับความสำคัญของข้อมูลสำรองของตัวเอง หากผู้ใช้ไม่ได้ทำตามวิซาร์ดการตั้งค่าอุปกรณ์ อุปกรณ์จะกู้คืนได้จากข้อมูลสำรองของตัวเองเท่านั้น

Android มีเครื่องมือที่ช่วยให้คุณเริ่มกู้คืนแอปด้วยตนเองได้เพื่อลดความซับซ้อนในการทดสอบ ดูข้อมูลเพิ่มเติมได้ที่ทดสอบการสำรองและกู้คืน

เปิดและปิดใช้การสำรองข้อมูล

แอปที่กำหนดเป้าหมายเป็น Android 6.0 (API ระดับ 23) ขึ้นไปจะเข้าร่วมการสำรองข้อมูลอัตโนมัติโดยอัตโนมัติ ในไฟล์ Manifest ของแอป ให้ตั้งค่าบูลีน android:allowBackup เพื่อเปิดหรือปิดใช้การสำรองข้อมูล ค่าเริ่มต้นคือ true แต่เราขอแนะนำให้ตั้งค่าแอตทริบิวต์อย่างชัดเจนในไฟล์ Manifest ดังที่แสดงในตัวอย่างต่อไปนี้

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

คุณปิดใช้การสำรองข้อมูลได้โดยตั้งค่า android:allowBackup เป็น false คุณอาจ ต้องการทำเช่นนี้หากแอปสามารถสร้างสถานะขึ้นใหม่ผ่านกลไกอื่น หรือหากแอปจัดการข้อมูลที่ละเอียดอ่อน

รวมและยกเว้นไฟล์

โดยค่าเริ่มต้น ระบบจะสำรองข้อมูลแอปเกือบทั้งหมด ดูข้อมูลเพิ่มเติมได้ที่ส่วนเกี่ยวกับไฟล์ที่สำรองข้อมูล

คุณควบคุมข้อมูลที่จะรวมอยู่ในการสำรองข้อมูลได้ตามประเภทการโอน การสำรองอัตโนมัติรองรับการสำรองข้อมูลในระบบคลาวด์ไปยัง Google ไดรฟ์และการโอนข้อมูลจากอุปกรณ์หนึ่งไปยังอีกอุปกรณ์หนึ่งโดยตรง (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 ไดรฟ์ได้ในขณะที่ยังคงโอนไฟล์ดังกล่าวในระหว่างการโอนจากอุปกรณ์ไปยังอุปกรณ์ (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 Cloud Messaging (FCM) ต้องสร้างโทเค็นการลงทะเบียนทุกครั้งที่ผู้ใช้ ติดตั้งแอปในอุปกรณ์ใหม่ หากมีการ กู้คืนโทเค็นการลงทะเบียนเก่า แอปอาจทำงานผิดปกติ

  • ไฟล์ที่เกี่ยวข้องกับการแก้ไขข้อบกพร่องของแอป

  • ไฟล์ขนาดใหญ่ที่ทำให้แอปใช้โควต้าการสำรองข้อมูลเกิน 25 MB

องค์ประกอบ <include> และ <exclude> แต่ละรายการต้องมีแอตทริบิวต์ 2 รายการต่อไปนี้

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> มาตรฐาน ตามที่อธิบายไว้ในไวยากรณ์สำหรับองค์ประกอบรวมและยกเว้น เพื่อระบุข้อมูลที่จะโอน

นอกจากนี้ คุณต้องระบุองค์ประกอบ <platform-specific-params> เพื่อช่วยให้ระบบจับคู่แอปของคุณกับแอปที่เกี่ยวข้องในแพลตฟอร์มเป้าหมาย องค์ประกอบนี้มีแอตทริบิวต์ที่จำเป็นต่อไปนี้

  • bundleId: รหัสชุดของแอปในแพลตฟอร์มอื่น (เช่น รหัสชุดของแอป iOS )
  • teamId: รหัสทีมของแอปในแพลตฟอร์มอื่น (เช่น รหัสทีมของแอป iOS)
  • contentVersion: สตริงเวอร์ชันที่คุณกำหนด ซึ่งเชื่อมโยงกับรูปแบบข้อมูลที่จะส่งออก

ระบบใช้แอตทริบิวต์ bundleId และ teamId เพื่อช่วยยืนยันความสมบูรณ์ของข้อมูล และการจับคู่แอปกับแอปอย่างเหมาะสม โดยจะรับประกันว่าข้อมูลจะโอนไปยังแอปที่ระบุในแพลตฟอร์มอื่นเท่านั้นในระหว่างการส่งออก และแอป Android นี้จะนำเข้าข้อมูลจากแอปนั้นเท่านั้นในระหว่างการนำเข้า

หากต้องการควบคุมกระบวนการแปลงและโอนข้อมูลอย่างละเอียด นอกเหนือจากที่กฎ XML ระบุไว้ คุณสามารถใช้BackupAgentที่กำหนดเองและใช้ API การโอนข้ามแพลตฟอร์ม

การแมปไฟล์สำหรับการโอนข้อมูลใน iOS

เมื่อโอนไฟล์ไปยัง iOS domain และ path ที่คุณระบุใน<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 ที่กำหนดเองก็ได้ โดยปกติแล้ว การดำเนินการนี้มีสาเหตุ 2 ประการดังนี้

  • คุณต้องการรับการแจ้งเตือนเกี่ยวกับเหตุการณ์การสำรองข้อมูล เช่น onRestoreFinished() และ onQuotaExceeded() ระบบจะเรียกใช้เมธอด การเรียกกลับเหล่านี้แม้ว่าแอปจะไม่ได้ทำงานอยู่ก็ตาม

  • คุณไม่สามารถแสดงชุดไฟล์ที่ต้องการสำรองข้อมูลด้วยกฎ XML ได้อย่างง่ายดาย ในกรณีที่เกิดขึ้นไม่บ่อยนัก คุณสามารถใช้BackupAgentที่ลบล้าง onFullBackup(FullBackupDataOutput)เพื่อจัดเก็บสิ่งที่คุณต้องการได้ หากต้องการคงการใช้งานเริ่มต้นของระบบ ให้เรียกใช้เมธอดที่เกี่ยวข้องในคลาสแม่ด้วย super.onFullBackup()

หากคุณใช้ BackupAgent โดยค่าเริ่มต้น ระบบจะคาดหวังให้แอปของคุณ สำรองและกู้คืนคีย์-ค่า หากต้องการใช้การสำรองข้อมูลอัตโนมัติแบบอิงตามไฟล์แทน ให้ตั้งค่าแอตทริบิวต์ android:fullBackupOnly เป็น true ใน Manifest ของแอป

ในระหว่างการดำเนินการสำรองข้อมูลและกู้คืนอัตโนมัติ ระบบจะเปิดแอปใน โหมดที่จำกัดเพื่อป้องกันไม่ให้แอปเข้าถึงไฟล์ที่อาจทำให้เกิด ข้อขัดแย้ง และอนุญาตให้แอปเรียกใช้เมธอดเรียกกลับใน BackupAgent ในโหมดที่ถูกจำกัดนี้ ระบบจะไม่เปิดใช้งานกิจกรรมหลักของแอปโดยอัตโนมัติ ไม่เริ่มต้นผู้ให้บริการเนื้อหา และจะสร้างอินสแตนซ์ของApplicationคลาสฐานแทนคลาสย่อยที่ประกาศไว้ในไฟล์ Manifest ของแอป

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