Android की बैकअप सेवा, मुख्य वैल्यू के लिए क्लाउड स्टोरेज का बैकअप लेने और उसे वापस पाने की सुविधा देती है डेटा शामिल है. की-वैल्यू वाली बैकअप कार्रवाई के दौरान, ऐप्लिकेशन का बैकअप डेटा को डिवाइस के बैकअप ट्रांसपोर्ट में भेज दिया जाता है. अगर डिवाइस डिफ़ॉल्ट Google बैकअप ट्रांसपोर्ट, फिर डेटा Android बैकअप को भेज दिया जाता है संग्रहित करने की सेवा.
आपके ऐप्लिकेशन के हर उपयोगकर्ता का डेटा 5 एमबी तक सीमित होता है. स्टोर करने के लिए कोई शुल्क नहीं है बैकअप डेटा.
Android के बैकअप विकल्पों की खास जानकारी और इस बारे में दिशा-निर्देश पाने के लिए कि कौनसा डेटा का बैक अप लेना और उसे वापस लाना है, तो डेटा का बैकअप देखें खास जानकारी पर टैप करें.
की-वैल्यू बैकअप लागू करना
अपने ऐप्लिकेशन डेटा का बैकअप लेने के लिए, आपको बैकअप एजेंट लागू करना होगा. आपका बैकअप बैकअप लेने और डेटा वापस पाने के दौरान, बैकअप मैनेजर एजेंट को कॉल करता है.
बैकअप एजेंट लागू करने के लिए, आपको:
अपनी मेनिफ़ेस्ट फ़ाइल में बैकअप एजेंट का एलान
android:backupAgent
एट्रिब्यूट की वैल्यू सबमिट करें.बैकअप एजेंट तय करने के लिए, इनमें से कोई एक तरीका अपनाएं:
BackupAgent
की अवधि बढ़ाई जा रही हैBackupAgent
क्लास ऐप्लिकेशन, एक ऐसा सेंट्रल इंटरफ़ेस उपलब्ध कराता है जिसका इस्तेमाल आपका ऐप्लिकेशन, बैकअप मैनेजर पर क्लिक करें. अगर इस क्लास को सीधे तौर पर एक्सटेंड किया जाता है, तो आपको अपने डेटा के बैक अप और उसे वापस लाने की प्रोसेस को मैनेज करने के लिए,onBackup()
औरonRestore()
को बदलना होगा.BackupAgentHelper
की अवधि बढ़ाई जा रही हैBackupAgentHelper
क्लास,BackupAgent
क्लास के लिए एक आसान रैपर उपलब्ध कराती है. इससे, आपको कम से कम कोड लिखना पड़ता है. अपनेBackupAgentHelper
है, तो आपको एक या उससे ज़्यादा हेल्पर ऑब्जेक्ट का इस्तेमाल करना होगा, कुछ प्रकार के डेटा का अपने आप बैक अप ले लेगा और उसे पुनर्स्थापित कर सकेगा, ताकि आपonBackup()
औरonRestore()
लागू करने की ज़रूरत होती है. जब तक आपको स्टोरेज की पूरी ज़रूरत न हो तो हमारा सुझाव है कि आपBackupAgentHelper
का इस्तेमाल करें और बैकअप लेने की ज़रूरत नहीं होती.फ़िलहाल, Android में बैकअप लेने में मदद करने वाली सुविधाएं उपलब्ध हैं. इनकी मदद से,
SharedPreferences
और इंटरनल स्टोरेज में मौजूद सभी फ़ाइलों का बैकअप लिया जा सकता है और उन्हें वापस लाया जा सकता है.
अपनी मेनिफ़ेस्ट फ़ाइल में बैकअप एजेंट की जानकारी दें
बैकअप एजेंट के लिए क्लास का नाम तय करने के बाद, <application>
टैग में android:backupAgent
एट्रिब्यूट का इस्तेमाल करके, उसे अपने मेनिफ़ेस्ट में एलान करें.
उदाहरण के लिए:
<manifest ... > ... <application android:label="MyApplication" android:backupAgent="MyBackupAgent"> <meta-data android:name="com.google.android.backup.api_key" android:value="unused" /> <activity ... > ... </activity> </application> </manifest>
हमारा सुझाव है कि पुराने डिवाइसों के साथ काम करने के लिए, एपीआई पासकोड <meta-data>
जोड़ें
को अपलोड करने की ज़रूरत नहीं पड़ेगी. Android Backup Service के लिए अब सेवा कुंजी की ज़रूरत नहीं है. हालांकि, हो सकता है कि कुछ पुराने डिवाइसों पर बैकअप लेने के दौरान, अब भी कुंजी की जांच की जाए. android:name
को com.google.android.backup.api_key
पर और
android:value
से unused
.
कॉन्टेंट बनाने
android:restoreAnyVersion
एट्रिब्यूट की बूलियन वैल्यू का इस्तेमाल करके यह पता चलता है कि आपको ऐप्लिकेशन को वापस लाना है या नहीं
डेटा भले ही ऐप्लिकेशन के मौजूदा वर्शन की तुलना में
डेटा का बैकअप लिया है. डिफ़ॉल्ट वैल्यू false
है. ज़्यादा जानकारी के लिए, डेटा का वह वर्शन देखें जिसे वापस पाना है लेख पढ़ें.
Extend BackupAgentHelper
अगर आप चाहें, तो आपको BackupAgentHelper
का इस्तेमाल करके अपना बैकअप एजेंट बनाना चाहिए
SharedPreferences
या डिवाइस के स्टोरेज से पूरी फ़ाइलों का बैक अप लें.
BackupAgentHelper
के साथ बैकअप एजेंट बनाने के लिए इससे कम कोड की ज़रूरत होती है
एक्सटेंशन BackupAgent
को बढ़ाया जा रहा है, क्योंकि आपको onBackup()
और
onRestore()
.
BackupAgentHelper
को लागू करने के लिए, एक या उससे ज़्यादा बैकअप हेल्पर का इस्तेमाल करना ज़रूरी है.
बैकअप हेल्पर एक खास कॉम्पोनेंट होता है, जिसे BackupAgentHelper
इकट्ठा करता है
किसी खास तरह के डेटा का बैकअप लेने और उसे रीस्टोर करने का काम करता है. कॉन्टेंट बनाने
Android फ़्रेमवर्क, फ़िलहाल दो अलग-अलग हेल्पर उपलब्ध कराता है:
SharedPreferences
फ़ाइलों का बैक अप लेने के लिए,SharedPreferencesBackupHelper
को चुनें.- पीछे जाने के लिए
FileBackupHelper
डिवाइस के स्टोरेज में सेव की गई फ़ाइलें मिटा दें.
BackupAgentHelper
में एक से ज़्यादा हेल्पर शामिल किए जा सकते हैं, लेकिन सिर्फ़ एक ही मदद ली जा सकती है
हर डेटा टाइप के लिए हेल्पर की ज़रूरत होती है. इसका मतलब है कि अगर आपके पास एक से ज़्यादा
SharedPreferences
फ़ाइलें हैं, तो आपको सिर्फ़ एक
SharedPreferencesBackupHelper
फ़ाइल की ज़रूरत है.
हर उस हेल्पर के लिए जिसे आपको अपने BackupAgentHelper
में जोड़ना है, आपको ये काम करने होंगे
फ़ॉलो कर रहे हैं,
onCreate()
तरीका:
- मनचाहे हेल्पर क्लास का इंस्टेंस इंस्टैंशिएट करें. क्लास के कंस्ट्रक्टर में, आपको उन फ़ाइलों के बारे में बताना होगा जिनका बैक अप लेना है.
- कॉल करें
addHelper()
अपनेBackupAgentHelper
में हेल्पर को जोड़ने के लिए.
नीचे दिए सेक्शन में बताया गया है कि उपलब्ध हेल्पर.
SharedPreferences का बैक अप लें
SharedPreferencesBackupHelper
को इंस्टैंशिएट करते समय, आपको
एक या ज़्यादा SharedPreferences
फ़ाइलों का नाम डालें.
उदाहरण के लिए, user_preferences
नाम की SharedPreferences
फ़ाइल का बैक अप लेने के लिए, BackupAgentHelper
का इस्तेमाल करने वाला पूरा बैकअप एजेंट ऐसा दिखता है:
Kotlin
// The name of the SharedPreferences file const val PREFS = "user_preferences" // A key to uniquely identify the set of backup data const val PREFS_BACKUP_KEY = "prefs" class MyPrefsBackupAgent : BackupAgentHelper() { override fun onCreate() { // Allocate a helper and add it to the backup agent SharedPreferencesBackupHelper(this, PREFS).also { addHelper(PREFS_BACKUP_KEY, it) } } }
Java
public class MyPrefsBackupAgent extends BackupAgentHelper { // The name of the SharedPreferences file static final String PREFS = "user_preferences"; // A key to uniquely identify the set of backup data static final String PREFS_BACKUP_KEY = "prefs"; // Allocate a helper and add it to the backup agent @Override public void onCreate() { SharedPreferencesBackupHelper helper = new SharedPreferencesBackupHelper(this, PREFS); addHelper(PREFS_BACKUP_KEY, helper); } }
SharedPreferencesBackupHelper
में वे सभी कोड मौजूद हैं जिनका बैक अप लेना है और
SharedPreferences
फ़ाइल को वापस लाएं.
जब Backup Manager, onBackup()
और onRestore()
को कॉल करता है, तो BackupAgentHelper
आपके बैकअप हेल्पर को कॉल करता है, ताकि आपने जिन फ़ाइलों का बैक अप लेने के लिए कहा है उनका बैक अप लिया जा सके और उन्हें वापस लाया जा सके.
अन्य फ़ाइलों का बैक अप लें
FileBackupHelper
का इंस्टेंस बनाते समय, आपको एक या उससे ज़्यादा फ़ाइलों का नाम शामिल करना होगा. ये फ़ाइलें, आपके ऐप्लिकेशन के इंटरनल स्टोरेज में सेव होनी चाहिए. इन फ़ाइलों के नाम, getFilesDir()
में बताए गए हैं. यह वही जगह है जहां openFileOutput()
फ़ाइलें लिखता है.
उदाहरण के लिए, scores
और stats
नाम की दो फ़ाइलों का बैक अप लेने के लिए, जो एक बैकअप एजेंट हैं
BackupAgentHelper
का उपयोग करने पर यह ऐसा दिखेगा:
Kotlin
// The name of the file const val TOP_SCORES = "scores" const val PLAYER_STATS = "stats" // A key to uniquely identify the set of backup data const val FILES_BACKUP_KEY = "myfiles" class MyFileBackupAgent : BackupAgentHelper() { override fun onCreate() { // Allocate a helper and add it to the backup agent FileBackupHelper(this, TOP_SCORES, PLAYER_STATS).also { addHelper(FILES_BACKUP_KEY, it) } } }
Java
public class MyFileBackupAgent extends BackupAgentHelper { // The name of the file static final String TOP_SCORES = "scores"; static final String PLAYER_STATS = "stats"; // A key to uniquely identify the set of backup data static final String FILES_BACKUP_KEY = "myfiles"; // Allocate a helper and add it to the backup agent @Override public void onCreate() { FileBackupHelper helper = new FileBackupHelper(this, TOP_SCORES, PLAYER_STATS); addHelper(FILES_BACKUP_KEY, helper); } }
FileBackupHelper
में, आपके ऐप्लिकेशन के इंटरनल स्टोरेज में सेव की गई फ़ाइलों का बैक अप लेने और उन्हें वापस लाने के लिए ज़रूरी सारा कोड शामिल होता है.
हालांकि, डिवाइस के स्टोरेज में मौजूद फ़ाइलों को पढ़ने और लिखने की सुविधा नहीं है थ्रेड सुरक्षित है. यह पक्का करने के लिए कि आपका बैकअप एजेंट, आपकी गतिविधियों के दौरान आपकी फ़ाइलों को न पढ़े या उनमें न लिखे, आपको हर बार पढ़ने या लिखने के लिए सिंक किए गए स्टेटमेंट का इस्तेमाल करना होगा. उदाहरण के लिए, ऐसी किसी भी गतिविधि में जहां आपने पढ़ने और लिखने के लिए, आपको एक ऑब्जेक्ट की ज़रूरत होगी, जिसका इस्तेमाल सिंक किए गए स्टेटमेंट:
Kotlin
// Object for intrinsic lock companion object { val sDataLock = Any() }
Java
// Object for intrinsic lock static final Object sDataLock = new Object();
इसके बाद, हर बार फ़ाइलों को पढ़ने या उनमें बदलाव करने पर, इस लॉक के साथ सिंक किया गया स्टेटमेंट बनाएं. उदाहरण के लिए, यहां किसी गेम में सबसे नया स्कोर, फ़ाइल में लिखने के लिए सिंक किया गया स्टेटमेंट दिया गया है:
Kotlin
try { synchronized(MyActivity.sDataLock) { val dataFile = File(filesDir, TOP_SCORES) RandomAccessFile(dataFile, "rw").apply { writeInt(score) } } } catch (e: IOException) { Log.e(TAG, "Unable to write to file") }
Java
try { synchronized (MyActivity.sDataLock) { File dataFile = new File(getFilesDir(), TOP_SCORES); RandomAccessFile raFile = new RandomAccessFile(dataFile, "rw"); raFile.writeInt(score); } } catch (IOException e) { Log.e(TAG, "Unable to write to file"); }
आपको अपने पढ़े गए स्टेटमेंट एक ही लॉक से सिंक करने चाहिए.
इसके बाद, अपने BackupAgentHelper
में, आपको onBackup()
और
onRestore()
को बदलना होगा, ताकि बैकअप और वापस पाने की प्रोसेस को एक ही
अंतरिक्ष लॉक के साथ सिंक किया जा सके. उदाहरण के लिए, ऊपर दिए गए MyFileBackupAgent
उदाहरण के लिए, इन तरीकों की ज़रूरत है:
Kotlin
@Throws(IOException::class) override fun onBackup( oldState: ParcelFileDescriptor, data: BackupDataOutput, newState: ParcelFileDescriptor ) { // Hold the lock while the FileBackupHelper performs back up synchronized(MyActivity.sDataLock) { super.onBackup(oldState, data, newState) } } @Throws(IOException::class) override fun onRestore( data: BackupDataInput, appVersionCode: Int, newState: ParcelFileDescriptor ) { // Hold the lock while the FileBackupHelper restores the file synchronized(MyActivity.sDataLock) { super.onRestore(data, appVersionCode, newState) } }
Java
@Override public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data, ParcelFileDescriptor newState) throws IOException { // Hold the lock while the FileBackupHelper performs back up synchronized (MyActivity.sDataLock) { super.onBackup(oldState, data, newState); } } @Override public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState) throws IOException { // Hold the lock while the FileBackupHelper restores the file synchronized (MyActivity.sDataLock) { super.onRestore(data, appVersionCode, newState); } }
बैक अप एजेंट को लंबे समय तक बढ़ाएं
ज़्यादातर ऐप्लिकेशन को BackupAgent
क्लास को सीधे तौर पर बढ़ाने की ज़रूरत नहीं होनी चाहिए. हालांकि, ऐसा करना चाहिए
इसके बजाय, फ़ायदा पाने के लिए BackupAgentHelper
की अवधि बढ़ाएं
पहले से मौजूद हेल्पर क्लास की सुविधा का इस्तेमाल करें. ये आपकी फ़ाइलों का अपने-आप बैक अप लेती हैं और उन्हें वापस लाती हैं.
हालांकि, इन कामों के लिए BackupAgent
को सीधे तौर पर एक्सटेंड किया जा सकता है:
- अपने डेटा फ़ॉर्मैट का वर्शन बनाएं. उदाहरण के लिए, अगर आपको जिस फ़ॉर्मैट में ऐप्लिकेशन का डेटा लिखा जाता है उसमें बदलाव किया जा सकता है, बैकअप लिया जा सकता है को वापस करने की कार्रवाई के दौरान, एजेंट को आपके ऐप्लिकेशन के वर्शन की दोबारा जांच करनी चाहिए. डिवाइस का वर्शन अलग होने पर किसी भी ज़रूरी काम करने के लिए सुझाव दें 30% से कम नहीं है. ज़्यादा जानकारी के लिए, बहाल किए गए डेटा का वर्शन देखना लेख पढ़ें.
- यह तय करें कि बैक अप के लिए डेटा का कौनसा हिस्सा इस्तेमाल करना है. पूरे डेटा का बैक अप लेने के बजाय फ़ाइल है, तो आप डेटा के उन हिस्सों को तय कर सकते है जिनका बैक अप लेना है और फिर डिवाइस पर बहाल किया गया. इससे आपको अलग-अलग वर्शन मैनेज करने में भी मदद मिल सकती है. ऐसा इसलिए, क्योंकि डेटा को पूरी फ़ाइलों के बजाय, यूनीक इकाइयों के तौर पर पढ़ा और लिखा जाता है.
- डेटाबेस में मौजूद डेटा का बैक अप लेना. अगर आपके पास अपनी पसंद का SQLite डेटाबेस है
उपयोगकर्ता के आपके ऐप्लिकेशन को पुनः इंस्टॉल करने पर उसे पुनर्स्थापित करने के लिए, आपको एक कस्टम
BackupAgent
जो बैकअप कार्रवाई के दौरान सही डेटा पढ़ता है, इसके बाद अपनी टेबल बनाएं और वापस लाने की कार्रवाई के दौरान डेटा शामिल करें.
अगर आपको ऊपर दिए गए किसी भी काम की ज़रूरत नहीं है और आपको SharedPreferences
या डिवाइस के स्टोरेज में मौजूद सभी फ़ाइलों का बैक अप लेना है, तो BackupAgentHelper
को बड़ा करना लेख पढ़ें.
ज़रूरी तरीके
BackupAgent
बनाते समय, आपको ये कॉलबैक
तरीके लागू करने होंगे:
onBackup()
- बैकअप मैनेजर इस विधि को आपके अनुरोध करने के बाद कॉल करता है बैक अप लें. इस तरीके में, डिवाइस से ऐप्लिकेशन का डेटा पढ़ा जाता है और उस डेटा को बैकअप मैनेजर को भेजा जाता है जिसका बैक अप लेना है. इस बारे में बैक अप लेने का तरीका में बताया गया है.
onRestore()
बैकअप मैनेजर इस तरीके को पहले जैसा करने की कार्रवाई के दौरान कॉल करता है. यह तरीका आपका बैकअप डेटा डिलीवर करता है. ऐप्लिकेशन इसका इस्तेमाल करके, पुराना डेटा वापस ला सकता है जैसा कि डेटा वापस पाने की सुविधा में बताया गया है.
सिस्टम इस तरीके को, बैकअप डेटा को वापस लाने के लिए कॉल करता है. ऐसा तब होता है, जब उपयोगकर्ता आपके ऐप्लिकेशन को फिर से इंस्टॉल करता है, लेकिन आपका ऐप्लिकेशन किसी वापस लाएं.
बैक अप लेना
बैकअप के अनुरोध करने पर, आपके onBackup()
पेमेंट के तरीके पर तुरंत कॉल नहीं किया जाता. इसके बजाय, बैकअप मैनेजर सही समय का इंतज़ार करता है. इसके बाद, वह उन सभी ऐप्लिकेशन का बैकअप लेता है जिन्होंने पिछली बार बैकअप लेने के बाद से बैकअप का अनुरोध किया है. यहां पर आपको अपने ऐप्लिकेशन का डेटा देना होगा
से लिंक करना होगा, ताकि इसे क्लाउड स्टोरेज में सेव किया जा सके.
सिर्फ़ बैकअप मैनेजर आपके बैकअप एजेंट के onBackup()
तरीके को कॉल कर सकता है. हर
जब आपको ऐप्लिकेशन के डेटा में बदलाव करना हो और आपको बैकअप लेना हो, तो ऐसा करना ज़रूरी है.
कॉल करके बैकअप कार्रवाई का अनुरोध करें
dataChanged()
.
ज़्यादा जानकारी के लिए बैकअप का अनुरोध करें देखें.
सलाह: अपना ऐप्लिकेशन डेवलप करते समय, तुरंत बैकअप लेने की प्रोसेस शुरू की जा सकती है
bmgr
के साथ बैकअप मैनेजर की ओर से कार्रवाई
टूल.
जब बैकअप मैनेजर आपके onBackup()
तरीके को कॉल करता है, तो यह तीन से ज़्यादा हो जाता है
पैरामीटर:
oldState
- ओपन, रीड-ओनली
ParcelFileDescriptor
पॉइंटिंग आपके ऐप्लिकेशन से मिली पिछली बैकअप स्थिति तक. यह बैकअप डेटा नहीं है क्लाउड स्टोरेज से लिया गया है, लेकिन उस डेटा का स्थानीय प्रतिनिधित्व जिसका बैक अप लिया गया था पिछली बारonBackup()
को कॉल किया गया था, जैसा किnewState
याonRestore()
.onRestore()
के बारे में अगले सेक्शन में बताया गया है.onBackup()
की मदद से, क्लाउड स्टोरेज में मौजूद बैकअप डेटा को नहीं पढ़ा जा सकता. इसलिए, इस लोकल डेटा का इस्तेमाल करके यह पता लगाया जा सकता है कि पिछले बैकअप के बाद आपके डेटा में बदलाव हुआ है या नहीं. data
- एक
BackupDataOutput
ऑब्जेक्ट की मदद से बनाया जाता है, जिसका इस्तेमाल बैकअप मैनेजर को बैकअप डेटा देने के लिए किया जाता है. newState
- उस फ़ाइल के बारे में बताने वाला एक खुला, पढ़ें/लिखें
ParcelFileDescriptor
, जिसमें आप आपको उस डेटा का प्रतिनिधित्व लिखना होगा जो आपनेdata
को डिलीवर किया था. ऐप्लिकेशन यह आपकी फ़ाइल के लिए, आखिरी बार बदलाव किए गए टाइमस्टैंप जितना आसान हो सकता है. अगली बार जब Backup Manager आपकेonBackup()
तरीके को कॉल करेगा, तो यह ऑब्जेक्टoldState
के तौर पर दिखाया जाएगा. अगर आपनेnewState
में बैकअप डेटा नहीं डाला है, तो अगली बार जब Backup ManageronBackup()
को कॉल करेगा, तबoldState
खाली फ़ाइल पर ले जाएगा.
इन पैरामीटर का इस्तेमाल करके, अपना onBackup()
तरीका लागू करें और ये काम करें:
पिछले बैकअप के बाद से डेटा में बदलाव हुआ है या नहीं, इसकी तुलना करके देखें आपके मौजूदा डेटा में
oldState
.oldState
में डेटा को पढ़ने का तरीका, इस बात पर निर्भर करता है कि आपने इसेnewState
में कैसे लिखा था (तीसरा चरण देखें). सबसे आसान तरीका फ़ाइल की स्थिति को उसके आखिरी बदलाव किए गए टाइमस्टैंप के साथ रिकॉर्ड करें. उदाहरण के लिए,oldState
के टाइमस्टैंप को पढ़ने और उसकी तुलना करने का तरीका यहां बताया गया है:Kotlin
val instream = FileInputStream(oldState.fileDescriptor) val dataInputStream = DataInputStream(instream) try { // Get the last modified timestamp from the state file and data file val stateModified = dataInputStream.readLong() val fileModified: Long = dataFile.lastModified() if (stateModified != fileModified) { // The file has been modified, so do a backup // Or the time on the device changed, so be safe and do a backup } else { // Don't back up because the file hasn't changed return } } catch (e: IOException) { // Unable to read state file... be safe and do a backup }
Java
// Get the oldState input stream FileInputStream instream = new FileInputStream(oldState.getFileDescriptor()); DataInputStream in = new DataInputStream(instream); try { // Get the last modified timestamp from the state file and data file long stateModified = in.readLong(); long fileModified = dataFile.lastModified(); if (stateModified != fileModified) { // The file has been modified, so do a backup // Or the time on the device changed, so be safe and do a backup } else { // Don't back up because the file hasn't changed return; } } catch (IOException e) { // Unable to read state file... be safe and do a backup }
अगर कोई बदलाव नहीं हुआ है और आपको बैक अप लेने की ज़रूरत नहीं है, तो सीधे तीसरे चरण पर जाएं.
अगर
oldState
की तुलना में आपका डेटा बदल गया है, तो मौजूदा डेटा को क्लाउड स्टोरेज पर इसका बैक अप लेने के लिएdata
.आपको
BackupDataOutput
में डेटा के हर हिस्से को इकाई के तौर पर लिखना होगा. इकाई, एक फ़्लैट किया गया बाइनरी डेटा रिकॉर्ड होता है. इसकी पहचान, एक यूनीक पासकोड स्ट्रिंग से की जाती है. इस प्रकार, आप जिस डेटा सेट का बैक अप लेते हैं, वह सैद्धांतिक रूप से की-वैल्यू पेयर.अपने बैकअप डेटा सेट में कोई इकाई जोड़ने के लिए, आपको ये काम करने होंगे:
कॉल करें
writeEntityHeader()
, जो डेटा आप लिखने वाले हैं उसके लिए एक अद्वितीय स्ट्रिंग कुंजी पास करना और डेटा साइज़.writeEntityData()
को कॉल करें. इसके लिए, बाइट बफ़र को पास करें. इसमें आपका डेटा और बफ़र से लिखे जाने वाले बाइट की संख्या शामिल होनी चाहिए. यह संख्या,writeEntityHeader()
को पास किए गए साइज़ से मेल खानी चाहिए.
उदाहरण के लिए, यह कोड कुछ डेटा को बाइट स्ट्रीम में फ़्लैट करता है और उसे एक एंटिटी में लिखता है:
Kotlin
val buffer: ByteArray = ByteArrayOutputStream().run { DataOutputStream(this).apply { writeInt(playerName) writeInt(playerScore) } toByteArray() } val len: Int = buffer.size data.apply { writeEntityHeader(TOPSCORE_BACKUP_KEY, len) writeEntityData(buffer, len) }
Java
// Create buffer stream and data output stream for our data ByteArrayOutputStream bufStream = new ByteArrayOutputStream(); DataOutputStream outWriter = new DataOutputStream(bufStream); // Write structured data outWriter.writeUTF(playerName); outWriter.writeInt(playerScore); // Send the data to the Backup Manager via the BackupDataOutput byte[] buffer = bufStream.toByteArray(); int len = buffer.length; data.writeEntityHeader(TOPSCORE_BACKUP_KEY, len); data.writeEntityData(buffer, len);
आपको जिस डेटा का बैक अप लेना है उसके लिए यह तरीका अपनाएं. बांटने का तरीका आपका डेटा इकाइयों में शामिल होना चाहिए या नहीं. यहां तक कि आप केवल एक इकाई का उपयोग भी कर सकते हैं.
दूसरे चरण में बैकअप लेने के बाद भी,
newState
ParcelFileDescriptor
में मौजूदा डेटा की जानकारी लिखें. द बैकअप मैनेजर इस ऑब्जेक्ट को स्थानीय तौर पर, उस डेटा के प्रतिनिधि के तौर पर बनाए रखता है जो फ़िलहाल, बैक अप लिया जा चुका है. अगली बारonBackup()
को कॉल करने पर, यह वैल्यू आपकोoldState
के तौर पर वापस भेजती है, ताकि आप यह तय कर सकें कि पहला बैकअप लेने के बाद, क्या कोई और बैकअप लेना ज़रूरी है. यह तय करने का तरीका, पहले चरण में बताया गया है. अगर इस फ़ाइल में मौजूदा डेटा की स्थिति नहीं लिखी जाती है, तो अगले कॉलबैक के दौरानoldState
खाली रहेगा.यहां दिए गए उदाहरण में, फ़ाइल में पिछली बार बदलाव करने के टाइमस्टैंप का इस्तेमाल करके, मौजूदा डेटा को
newState
में सेव किया गया है:Kotlin
val modified = dataFile.lastModified() FileOutputStream(newState.fileDescriptor).also { DataOutputStream(it).apply { writeLong(modified) } }
Java
FileOutputStream outstream = new FileOutputStream(newState.getFileDescriptor()); DataOutputStream out = new DataOutputStream(outstream); long modified = dataFile.lastModified(); out.writeLong(modified);
डेटा को वापस लाना
जब आपके ऐप्लिकेशन के डेटा को वापस लाने का समय आता है, तो Backup Manager आपके बैकअप एजेंट के onRestore()
तरीके को कॉल करता है. इस तरीके को कॉल करने पर, Backup Manager आपके बैकअप डेटा को डिलीवर करता है, ताकि आप उसे डिवाइस पर वापस ला सकें.
सिर्फ़ बैकअप मैनेजर onRestore()
को कॉल कर सकता है, जो अपने-आप होता है
जब सिस्टम आपका ऐप्लिकेशन इंस्टॉल करता है और उसे मौजूदा बैकअप डेटा मिलता है.
जब बैकअप मैनेजर आपके onRestore()
तरीके को कॉल करता है, तो यह तीन से ज़्यादा हो जाता है
पैरामीटर:
data
- एक
BackupDataInput
ऑब्जेक्ट, इसकी मदद से, बैकअप में मौजूद डेटा को पढ़ा जा सकता है. appVersionCode
- आपके ऐप्लिकेशन की वैल्यू दिखाने वाला पूर्णांक
android:versionCode
मेनिफ़ेस्ट विशेषता में दी गई जानकारी इस्तेमाल करें, जैसा कि इस डेटा का बैक अप लेने पर किया गया था. इसका इस्तेमाल करके, ऐप्लिकेशन के मौजूदा वर्शन की पुष्टि की जा सकती है. साथ ही, यह भी पता लगाया जा सकता है कि डेटा फ़ॉर्मैट काम करता है या नहीं. अलग-अलग मैसेज को हैंडल करने के लिए इसका इस्तेमाल करने के बारे में डेटा वापस पाने का विकल्प चुनने पर, डेटा वापस पाने की प्रोसेस से जुड़ा डेटा देखें वर्शन के तौर पर उपलब्ध है. newState
- उस फ़ाइल के बारे में बताने वाला एक खुला, पढ़ें/लिखें
ParcelFileDescriptor
, जिसमें आप कोdata
के साथ उपलब्ध कराई गई बैकअप की आखिरी स्थिति लिखनी होगी. यह ऑब्जेक्ट अगली बारonBackup()
को कॉल करने पर,oldState
के तौर पर दिखेगा. याद रखें कि आपकोonBackup()
कॉलबैक में भी वहीnewState
ऑब्जेक्ट लिखना होगा. ऐसा करने से यह भी पक्का होता है कि डिवाइस को वापस लाने के बाद,onBackup()
को पहली बार कॉल करने पर भीonBackup()
को दिया गयाoldState
ऑब्जेक्ट मान्य हो.
onRestore()
को लागू करते समय, आपको डेटा सेट में मौजूद सभी इकाइयों को दोहराने के लिए, data
पर readNextHeader()
को कॉल करना चाहिए. हर इकाई के लिए
मिला है, तो ये काम करें:
getKey()
की मदद से, इकाई की कुंजी पाएं.इकाई कुंजी की तुलना, उन कुंजी वैल्यू की सूची से करें जिन्हें आपको अपनी
BackupAgent
क्लास में स्टैटिक फ़ाइनल स्ट्रिंग के तौर पर घोषित करना चाहिए. जब कुंजी, आपकी किसी जानी-पहचानी कुंजी स्ट्रिंग से मैच करती है, तो इकाई का डेटा निकालने और उसे डिवाइस में सेव करने के लिए स्टेटमेंट डालें:- इसके साथ इकाई डेटा का आकार पाएं
getDataSize()
और उस साइज़ की बाइट अरे बनाएं. readEntityData()
को कॉल करें और उसे बाइट कलेक्शन पास करें. यह वह जगह है जहां डेटा सेव होगा. साथ ही, शुरू करने के ऑफ़सेट और पढ़ने के साइज़ की जानकारी दें.- आपका बाइट कलेक्शन अब भर गया है. डेटा पढ़ें और उसे डिवाइस पर लिखें जैसे आप चाहें.
- इसके साथ इकाई डेटा का आकार पाएं
डिवाइस पर अपना डेटा वापस पढ़ने और लिखने के बाद,
newState
पैरामीटर में अपना डेटा उसी तरह से शामिल करना जैसा आपonBackup()
.
उदाहरण के लिए, पिछले सेक्शन में दिए गए उदाहरण के आधार पर, बैक अप लिए गए डेटा को वापस लाने का तरीका यहां बताया गया है:
Kotlin
@Throws(IOException::class) override fun onRestore(data: BackupDataInput, appVersionCode: Int, newState: ParcelFileDescriptor) { with(data) { // There should be only one entity, but the safest // way to consume it is using a while loop while (readNextHeader()) { when(key) { TOPSCORE_BACKUP_KEY -> { val dataBuf = ByteArray(dataSize).also { readEntityData(it, 0, dataSize) } ByteArrayInputStream(dataBuf).also { DataInputStream(it).apply { // Read the player name and score from the backup data playerName = readUTF() playerScore = readInt() } // Record the score on the device (to a file or something) recordScore(playerName, playerScore) } } else -> skipEntityData() } } } // Finally, write to the state blob (newState) that describes the restored data FileOutputStream(newState.fileDescriptor).also { DataOutputStream(it).apply { writeUTF(playerName) writeInt(mPlayerScore) } } }
Java
@Override public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState) throws IOException { // There should be only one entity, but the safest // way to consume it is using a while loop while (data.readNextHeader()) { String key = data.getKey(); int dataSize = data.getDataSize(); // If the key is ours (for saving top score). Note this key was used when // we wrote the backup entity header if (TOPSCORE_BACKUP_KEY.equals(key)) { // Create an input stream for the BackupDataInput byte[] dataBuf = new byte[dataSize]; data.readEntityData(dataBuf, 0, dataSize); ByteArrayInputStream baStream = new ByteArrayInputStream(dataBuf); DataInputStream in = new DataInputStream(baStream); // Read the player name and score from the backup data playerName = in.readUTF(); playerScore = in.readInt(); // Record the score on the device (to a file or something) recordScore(playerName, playerScore); } else { // We don't know this entity key. Skip it. (Shouldn't happen.) data.skipEntityData(); } } // Finally, write to the state blob (newState) that describes the restored data FileOutputStream outstream = new FileOutputStream(newState.getFileDescriptor()); DataOutputStream out = new DataOutputStream(outstream); out.writeUTF(playerName); out.writeInt(mPlayerScore); }
इस उदाहरण में, onRestore()
में पास किए गए appVersionCode
पैरामीटर का इस्तेमाल नहीं किया गया है. हालांकि, अगर आपने बैकअप लेने का विकल्प चुना है, तो हो सकता है कि आप इसका इस्तेमाल करना चाहें
जब ऐप्लिकेशन का उपयोगकर्ता वर्शन वाकई में पीछे चला जाता है (उदाहरण के लिए,
उपयोगकर्ता आपके ऐप्लिकेशन के 1.5 वर्शन से 1.0 पर चला गया है). ज़्यादा जानकारी के लिए, अगला सेक्शन देखें.
डेटा वापस लाने का वर्शन देखें
जब बैक अप मैनेजर आपके डेटा को क्लाउड स्टोरेज में सेव करता है, तब वह अपने-आप क्लाउड स्टोरेज में सेव हो जाता है
में आपके ऐप्लिकेशन का वर्शन शामिल होता है, जैसा कि आपकी मेनिफ़ेस्ट फ़ाइल में बताया गया है
android:versionCode
एट्रिब्यूट की वैल्यू सबमिट करें. Backup Manager आपके डेटा को वापस लाने के लिए, बैकअप एजेंट को कॉल करने से पहले, इंस्टॉल किए गए ऐप्लिकेशन के android:versionCode
को देखता है और उसकी तुलना, डेटा वापस लाने के लिए सेट किए गए डेटा से की जाती है. अगर पहले जैसा करने के लिए सेव किए गए डेटा में रिकॉर्ड किया गया वर्शन, डिवाइस पर मौजूद ऐप्लिकेशन के वर्शन से नया है, तो इसका मतलब है कि उपयोगकर्ता ने अपने ऐप्लिकेशन को डाउनग्रेड कर दिया है. इस मामले में, Backup Manager आपके ऐप्लिकेशन को पहले जैसा करने की प्रोसेस को रोक देगा और आपके onRestore()
तरीके को कॉल नहीं करेगा. ऐसा इसलिए, क्योंकि पुराने वर्शन के लिए, पहले जैसा करने के लिए सेव किए गए डेटा का कोई मतलब नहीं है.
android:restoreAnyVersion
एट्रिब्यूट की मदद से, इस व्यवहार को बदला जा सकता है.
इस एट्रिब्यूट को true
पर सेट करें, ताकि यह पता चल सके कि आपको ऐप्लिकेशन को पहले जैसा करना है, फिर चाहे वह सेट किए गए वर्शन पर हो या नहीं. डिफ़ॉल्ट वैल्यू false
है. अगर आपको
इसे true
पर सेट करें, तो बैकअप मैनेजर
android:versionCode
और सभी मामलों में अपने onRestore()
तरीके को कॉल करें. ऐसा करने पर, अपने onRestore()
तरीके में वर्शन के अंतर की मैन्युअल तौर पर जांच की जा सकती है. साथ ही, अगर वर्शन मैच नहीं करते हैं, तो डेटा को काम करने लायक बनाने के लिए ज़रूरी कदम उठाए जा सकते हैं.
onRestore()
तरीका, appVersionCode
पैरामीटर के तौर पर, वापस लाने के लिए सेट किए गए डेटा में शामिल वर्शन कोड को पास करता है. इससे, डेटा को वापस लाने के दौरान अलग-अलग वर्शन को मैनेज करने में मदद मिलती है. इसके बाद, PackageInfo.versionCode
फ़ील्ड की मदद से, ऐप्लिकेशन के मौजूदा वर्शन कोड के बारे में क्वेरी की जा सकती है. उदाहरण के लिए:
Kotlin
val info: PackageInfo? = try { packageManager.getPackageInfo(packageName, 0) } catch (e: PackageManager.NameNotFoundException) { null } val version: Int = info?.versionCode ?: 0
Java
PackageInfo info; try { String name = getPackageName(); info = getPackageManager().getPackageInfo(name, 0); } catch (NameNotFoundException nnfe) { info = null; } int version; if (info != null) { version = info.versionCode; }
इसके बाद, यहां से मिले version
की तुलना करें
PackageInfo
से
appVersionCode
को onRestore()
में पास किया गया.
बैकअप का अनुरोध करें
किसी भी समय dataChanged()
पर कॉल करके, बैकअप कार्रवाई का अनुरोध किया जा सकता है. यह
यह तरीका, बैकअप मैनेजर को सूचना देता है कि उसका इस्तेमाल करके,
आपका बैकअप एजेंट है. इसके बाद, बैकअप मैनेजर आपके बैकअप एजेंट के onBackup()
तरीके का इस्तेमाल करके, बैकअप लेता है. आम तौर पर, आपको
डेटा में हर बार बदलाव होने पर (जैसे कि जब उपयोगकर्ता किसी ऐप्लिकेशन को बदलता है)
चुनें, जिसका आप बैक अप लेना चाहते हैं. अगर Backup Manager आपके एजेंट से बैकअप का अनुरोध करने से पहले, dataChanged()
को कई बार कॉल किया जाता है, तो भी आपके एजेंट को onBackup()
पर सिर्फ़ एक कॉल मिलेगा.
डेटा वापस पाने का अनुरोध करना
ऐप्लिकेशन के सामान्य इस्तेमाल के दौरान, आपको डेटा को वापस लाने के लिए अनुरोध करने की ज़रूरत नहीं पड़ती. सिस्टम अपने-आप बैकअप डेटा की जांच करता है और ऐप्लिकेशन इंस्टॉल होने पर वापस लाएं.
ऑटो बैकअप पर माइग्रेट करना
अपने ऐप्लिकेशन को पूरे डेटा का बैकअप लेने की सुविधा चालू करें. ऐसा करने के लिए,
android:fullBackupOnly
मेनिफ़ेस्ट फ़ाइल में <application>
एलिमेंट में true
तक. Android 5.1 (एपीआई लेवल 22) या उससे पहले के वर्शन वाले डिवाइस पर चलने पर, आपका ऐप्लिकेशन मेनिफ़ेस्ट में मौजूद इस वैल्यू को अनदेखा कर देता है और कुंजी-वैल्यू के बैकअप लेना जारी रखता है. दौड़ते समय
Android 6.0 (एपीआई लेवल 23) या उसके बाद के वर्शन वाले डिवाइस पर, आपका ऐप्लिकेशन अपने-आप काम करता है
की-वैल्यू बैकअप के बजाय बैकअप.
उपयोगकर्ता की निजता
हम अच्छी तरह जानते हैं कि आपको हम पर भरोसा है और उपयोगकर्ताओं की निजता को सुरक्षित रखना हमारी ज़िम्मेदारी है. बैकअप लेने और डेटा वापस लाने की सुविधाएं देने के लिए, Google आपके बैकअप डेटा को सुरक्षित तरीके से Google के सर्वर पर भेजता है और वहां से वापस लाता है. Google के अनुसार, Google इस डेटा को निजी जानकारी मानता है. निजता नीति.
इसके अलावा, उपयोगकर्ता Android सिस्टम की बैकअप सेटिंग में जाकर, डेटा बैकअप की सुविधा बंद कर सकते हैं. जब कोई उपयोगकर्ता बैकअप लेने की सुविधा बंद करता है, तो Android Backup Service, सेव किए गए सभी बैकअप डेटा को मिटा देती है. उपयोगकर्ता, डिवाइस पर बैकअप की सुविधा को फिर से चालू कर सकता है. हालांकि, Android Backup Service, पहले मिटाए गए डेटा को वापस नहीं लाएगी.