एंड्रॉइड ऑटो बैकअप का उपयोग करके फिर से इंस्टॉल करने और allowBackup = true के साथ साझा किए गए साझाकरण से मान प्राप्त करना


9

मैं एप्लिकेशन को फिर से स्थापित करने और अनुमति देने के बाद सच होने के बाद साझा प्राथमिकताएं से मान (Android 9.0 डिवाइस पर) प्राप्त करने में समस्या आ रही है।

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

इसके अनुसार: https://developer.android.com/guide/topics/data/autobackup

साझा प्राथमिकताएं बहाल होनी चाहिए?

    SharedPreferences prefs = getSharedPreferences("TEST", MODE_PRIVATE);
    String name = prefs.getString("name", "No name defined");//"No name defined" is the default value.
    int idName = prefs.getInt("idName", 0); //0 is the default value.

    SharedPreferences.Editor editor = getSharedPreferences("TEST", MODE_PRIVATE).edit();
    editor.putString("name", "Elena");
    editor.putInt("idName", 12);
    editor.apply();
  • मैंने (इम्यूलेटर) फोन (एपीआई 27) पर अपने जीमेल खाते में लॉग इन किया है और ड्राइव ऐप, बैकप, ऐप-डेटा में जाने पर मुझे 18 ऐप जैसे कि यूट्यूब, जीमेल आदि दिखाई देते हैं और मेरा अपना ऐप भी है।
  • जब मैं "सेटिंग> सिस्टम> बैकअप" पर जाता हूं तो मुझे वही एप्लिकेशन और अपना स्वयं का ऐप दिखाई देता है। मैं एप्लिकेशन लोड करता हूं, साझाकरण कोड निष्पादित किया जाता है। मैं ऐप को बंद करता हूं और इसे मेमोरी से हटा देता हूं। और फिर मैं "अब बैकअप" बटन दबाता हूं:

यहां छवि विवरण दर्ज करें

सत्यापित करने के लिए मैं सूची में अपना ऐप देख सकता हूं और इसे 0 मिनट पहले बैकअप मिला है:

यहां छवि विवरण दर्ज करें

फिर मैं ऐप को हटाता हूं और 2 मूल्यों (ऐलेना और 12) के होने की उम्मीद करता हूं। लेकिन वे मिट जाते हैं ...

मैंने कमांड लाइन के माध्यम से भी यही कोशिश की है, लेकिन यह भी काम नहीं कर रहा है: https://developer.android.com/guide/topics/data/testingbackup.html#Preparing

adb shell
dreamlte:/ $ bmgr enabled
Backup Manager currently enabled
dreamlte:/ $ bmgr list transports
    android/com.android.internal.backup.LocalTransport
    com.google.android.gms/.backup.migrate.service.D2dTransport
* com.google.android.gms/.backup.BackupTransportService
dreamlte:/ $ bmgr backupnow my.package.name
Running incremental backup for 1 requested packages.
Package @pm@ with result: Success
Package nl.dagelijkswoord.android with progress: 1536/309248
Package nl.dagelijkswoord.android with result: Success
Backup finished with result: Success

dreamlte:/ $ dumpsys backup
Backup Manager is enabled / provisioned / not pending init
Auto-restore is disabled
No backups running
Last backup pass started: 1573804513565 (now = 1573806675410)
  next scheduled: 1573819001046
...
1573806051616 : my.package.name

dreamlte:/ $ bmgr restore 1573806051616 my.package.name                                                                                                            
No matching restore set token.  Available sets:
  35e84268c94b7d9c : SM-G950F
  3a8e32898034f8af : SM-G950F
  3e2610c4ea45fb96 : Nexus 5X
done

dreamlte:/ $ bmgr restore 35e84268c94b7d9c my.package.name                                                                                                         
Scheduling restore: SM-G950F
restoreStarting: 1 packages
onUpdate: 0 = my.package.name 
restoreFinished: 0
done
  1. ऐप निकालें
  2. एप्लिकेशन को फिर से इंस्टॉल करें और जांचें कि क्या साझाकरण मान अभी भी हैं।
  3. मान गए ...

सैमसंग क्लाउड के साथ सैमसंग उपकरणों पर भी व्यवहार अलग-अलग प्रतीत होता है, लेकिन अब हम स्टॉक एंड्रॉइड पर ध्यान केंद्रित करते हैं।

अपडेट करें:

यह अब और काम नहीं कर रहा था क्योंकि मैंने build.gradle में संस्करण को डाउनग्रेड कर दिया था:

build.gradle:
versionCode 70
versionName "1.6.1"

यहां तक कि साथ android:restoreAnyVersion="true"में AndroidManifestयह केवल काम करेगा जब संस्करण डाउनग्रेड नहीं किया गया था।



नमस्कार @PraveenSP मैं एंड्रॉइड ऑटो बैकअप का उपयोग करना चाहता हूं न कि पुराने की / वैल्यू स्टोर वर्जन का।
जिम क्लरमॉंट्स

जवाबों:


1

डिफ़ॉल्ट रूप से एंड्रॉइड सिस्टम बैकअप के लिए सभी डिफॉल्ट डेटा यदि डिवाइस वाई-फाई नेटवर्क से जुड़ा है (यदि डिवाइस उपयोगकर्ता ने मोबाइल-डेटा बैकअप में नहीं चुना है), तो ऐप को फिर से स्थापित करने और WI-FI से कनेक्ट करने का प्रयास करें आमतौर पर एंड्रॉइड सिस्टम सिंक हर 24 घंटे में एक बार डेटा अगर कोई बदलाव हो। आप इस तरह से बैकअप के लिए अपने स्वयं के नियमों को निर्दिष्ट करने का प्रयास कर सकते हैं।

`<application 
 android:fullBackupContent="@xml/backup_rules">
</application>`

और एक xml फ़ाइल बनाएँ और इसे res / xml निर्देशिका में डालें फ़ाइल के अंदर, और तत्वों के साथ नियम जोड़ें। निम्न नमूना डिवाइस.xml को छोड़कर सभी साझा प्राथमिकताओं का समर्थन करता है।

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

मुझे उम्मीद है कि यह आपके मुद्दे को हल करेगा।


मैं सिर्फ साझा करने के लिए बचत करना चाहता हूं, कोई xml नहीं।
जिम क्लरमॉंट्स

उपर्युक्त कोड एंड्रॉइड सिस्टम के लिए उपयोगकर्ता ड्राइव पर डेटा को बचाने के लिए नियम है, इसके xml के रूप में सहेजने के लिए नहीं जा रहा है, शामिल करें और बहिष्कृत टैग सिस्टम को सूचित करें कि कौन से डेटा को सिंक करना है और सहेजना है और कौन सा डेटा सिंक ऑपरेशन में बाहर करना है ।
आशीष श्रीवास्तव

मैं समझता हूँ लेकिन यह अनावश्यक है मुझे लगता है?
जिम क्लरमॉंट्स 7

1
मुझे नहीं लगता कि, जब एंड्रॉइड सिस्टम बूट ने शिकायत की थी, तो यह अनावश्यक रूप से बीकॉज है, यह अनुमति देता है कि डिफ़ॉल्ट रूप से डिफ़ॉल्ट रूप से प्रकट होने वाले सभी एप्लिकेशन नियमों को चेक करता है जब allowBackup सच है, लेकिन जब हम लिखते हैं तो एंड्रॉइड सिस्टम स्थानीय नियमों में रहता है और इसे पैकेज नाम के साथ जोड़ देता है।
आशीष श्रीवास्तव

मैंने ऊपर XML कोड जोड़ा है, लेकिन इससे कोई फर्क नहीं पड़ता।
जिम क्लरमॉंट्स

1

डेटा बैक डॉक्यूमेंट के अनुसार, आपको SharedPreferencesBackupHelper बनाने और साझा करने के लिए इन चरणों का पालन करने की आवश्यकता है, ताकि आपके केस के लिए बैकअप सेवाओं को पंजीकृत करने की आवश्यकता हो।


हैलो, मैं एंड्रॉइड ऑटो बैकअप के बारे में बात कर रहा हूं, न कि एंड्रॉइड बैकअप सेवा।
जिम क्लरमॉंट्स

यह केवल ऑटो बैकअप से संबंधित है। नमूने के लिए आप का पालन कर सकते इन चरणों का codelabs.developers.google.com/codelabs/android-backup-codelab/...
Damodhar

1

यह प्रक्रिया आपके लिए काम करेगी। उपयोगकर्ता के साझाकरणों को बैकअप करने और पुनर्स्थापित करने का प्रयास करें। यह आपकी पसंद को किसी भी बाहरी संग्रहण या डिवाइस पर बैकअप देगा।

जब उपयोगकर्ता एप्लिकेशन की स्थापना रद्द करता है, तो उपयोगकर्ता को इसे वापस लेना चाहिए। कुछ तर्क जोड़ें कि यदि फ़ाइल बाहरी संग्रहण या डिवाइस में मौजूद है, तो उसे वापस लाएं।

अपनी वरीयता का बैकअप लेने के लिए नीचे दिए गए कोड का उपयोग करें।

public static void backupUserPrefs(Context context) {
    final File prefsFile = new File(context.getFilesDir(), "../shared_prefs/" + context.getPackageName() + "_preferences.xml");
    final File backupFile = new File(context.getExternalFilesDir(null),
        "preferenceBackup.xml");
    String error = "";

    try {
        FileChannel src = new FileInputStream(prefsFile).getChannel();
        FileChannel dst = new FileOutputStream(backupFile).getChannel();

        dst.transferFrom(src, 0, src.size());

        src.close();
        dst.close();

        Toast toast = Toast.makeText(context, "Backed up user prefs to " + backupFile.getAbsolutePath(), Toast.LENGTH_SHORT);
        toast.show();
        return;
    } catch (FileNotFoundException e) {
        error = e.getMessage();
        e.printStackTrace();
    } catch (IOException e) {
        error = e.getMessage();
        e.printStackTrace();
    }

वरीयता बहाल करने के लिए नीचे दिए गए कोड का उपयोग करें

public static boolean restoreUserPrefs(Context context) {
    final File backupFile = new File(context.getExternalFilesDir(null),
        "preferenceBackup.xml");
    String error = "";

    try {

        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);

        Editor editor = sharedPreferences.edit();

        InputStream inputStream = new FileInputStream(backupFile);

        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = docFactory.newDocumentBuilder();

        Document doc = docBuilder.parse(inputStream);
        Element root = doc.getDocumentElement();

        Node child = root.getFirstChild();
        while (child != null) {
            if (child.getNodeType() == Node.ELEMENT_NODE) {

                Element element = (Element) child;

                String type = element.getNodeName();
                String name = element.getAttribute("name");

                // In my app, all prefs seem to get serialized as either "string" or
                // "boolean" - this will need expanding if yours uses any other types!    
                if (type.equals("string")) {
                    String value = element.getTextContent();
                    editor.putString(name, value);
                } else if (type.equals("boolean")) {
                    String value = element.getAttribute("value");
                    editor.putBoolean(name, value.equals("true"));
                }
            }

            child = child.getNextSibling();

        }

        editor.commit();

        Toast toast = Toast.makeText(context, "Restored user prefs from " + backupFile.getAbsolutePath(), Toast.LENGTH_SHORT);
        toast.show();

        return true;

    } catch (FileNotFoundException e) {
        error = e.getMessage();
        e.printStackTrace();
    } catch (ParserConfigurationException e) {
        error = e.getMessage();
        e.printStackTrace();
    } catch (SAXException e) {
        error = e.getMessage();
        e.printStackTrace();
    } catch (IOException e) {
        error = e.getMessage();
        e.printStackTrace();
    }

    Toast toast = Toast.makeText(context, "Failed to restore user prefs from " + backupFile.getAbsolutePath() + " - " + error, Toast.LENGTH_SHORT);
    toast.show();

    return false;
}


    Toast toast = Toast.makeText(context, "Failed to Back up user prefs to " + backupFile.getAbsolutePath() + " - " + error, Toast.LENGTH_SHORT);
    toast.show();

}

फिर इन प्रीफ्रेंस को पकड़ने से पहले अपने ऐप को पुनः आरंभ करें

if (restoreUserPrefs(context)) {
    // Restart              
    AlarmManager alm = (AlarmManager) context.getSystemService(
    Context.ALARM_SERVICE);
    alm.set(AlarmManager.RTC,
    System.currentTimeMillis() + 1000, PendingIntent.getActivity(context, 0,
    new Intent(context, MainActivityName.class), 0));
    android.os.Process.sendSignal(android.os.Process.myPid(),
    android.os.Process.SIGNAL_KILL);
}

नमस्कार, समस्या यह थी कि जब build.gradle में डाउनग्रेड किया जाता है, तो यह बैकअप नहीं लेता है। यही कारण है कि यह काम नहीं कर रहा था। केवल एक साधारण स्ट्रिंग को संग्रहीत करने के लिए इस कोड की आवश्यकता नहीं है।
जिम क्लेरमॉंट्स 12

मेरे लिए काम किया ... मेरा दिन बचाया ... धन्यवाद
अप्रयुक्त

0

कंसोल संदेश में दिखाए गए अनुसार आपने ऑटो-रिस्टोर सेटिंग्स को चालू नहीं किया। आपको सिस्टम सेटिंग्स पर जाना चाहिए और इसे चालू करना चाहिए। उसके बाद, बहाली काम कर सकती थी।

सेटिंग्स -> बैकअप -> स्वचालित पुनर्स्थापना।

BTW, आपके द्वारा उपयोग किया गया टोकन सही नहीं है। 1573806051616 टोकन के बजाय टाइमस्टैम्प है। टोकन नीचे के रूप में दिखाई देना चाहिए:

Ancestral packages: none
Ever backed up: XXXXXXXXXXXXXXXX

यहां, XXXXXXXXXXXXXXXXटोकन होना चाहिए।


-1

बहाली का परीक्षण करने के लिए, आपको अपने ऐप को हटाए बिना नीचे दिए गए कमांड को चलाने की आवश्यकता है। पुनर्स्थापना आदेश एप्लिकेशन को बंद कर देगा, डेटा मिटा देगा और पुनर्स्थापना करेगा, इसलिए Android AutoBackup की कार्यक्षमता का अनुकरण करेगा:

bmgr restore <TOKEN> <PACKAGE>

TOKEN से पुनर्प्राप्त किया जाता है logcatबैकअप कमांड चलाते समय या कमांड से कमांडdumpsys backup । इसके अलावा आप जाँच सकते dumpsys backupहैं कि बैकअप बनाया गया था।

अधिक जानकारी यहाँ: https://developer.android.com/guide/topics/data/testingbackup.html#TestingRestore


मैंने यह कोशिश की और जवाब को संपादित किया, लेकिन शेअरपर्फ मान अभी भी चले गए हैं।
जिम क्लरमॉंट्स

बैकअप के लिए कुछ पूर्व शर्त पूरी की जानी चाहिए। कृपया नीचे दिए गए लिंक की जाँच करें :: blog.devknox.io/…
Susheel Tickoo

पूर्व शर्त पूरी की जाती है और यह काम नहीं कर रहा है।
जिम क्लरमॉंट्स

-1

ऐसा करने का एक तरीका इस प्रकार है, (कृपया ध्यान दें, यह सबसे अच्छा तरीका नहीं हो सकता है, लेकिन यह काम करता है!)

ऐप को अनइंस्टॉल करने से पहले उसका बैकअप ले लें। कुछ तर्क जोड़ें कि यदि फ़ाइल बाहरी संग्रहण में मौजूद है , तो उसे वापस लाएं।

SharedPreferences वर्ग में संग्रहीत वरीयताएँ /data/data//sared_prefs/_preferences.xml में सहेजी जाती हैं - बैकअप लेना आसान है, आपको बस इस फ़ाइल की सामग्री को बाहरी संग्रहण में कॉपी करने की आवश्यकता है:

public static void backupUserPrefs(Context context) {
final File prefsFile = new File(context.getFilesDir(), "../shared_prefs/" + context.getPackageName() + "_preferences.xml");
final File backupFile = new File(context.getExternalFilesDir(null),
    "preferenceBackup.xml");
String error = "";

try {
    FileChannel src = new FileInputStream(prefsFile).getChannel();
    FileChannel dst = new FileOutputStream(backupFile).getChannel();

    dst.transferFrom(src, 0, src.size());

    src.close();
    dst.close();

    Toast toast = Toast.makeText(context, "Backed up user prefs to " + backupFile.getAbsolutePath(), Toast.LENGTH_SHORT);
    toast.show();
    return;
} catch (FileNotFoundException e) {
    error = e.getMessage();
    e.printStackTrace();
} catch (IOException e) {
    error = e.getMessage();
    e.printStackTrace();
}

वरीयता बहाल करने के लिए निम्नलिखित कोड का उपयोग करें

लेकिन पुनर्स्थापना एक चुनौती का अधिक प्रदान करता है, क्योंकि शेयर्ड_पर्फ्स फ़ाइल सीधे ऐप द्वारा लिखने योग्य नहीं होती है, और SharedPrefs वर्ग सीधे xml से क्रमबद्ध होने के लिए इसकी कार्यक्षमता को उजागर नहीं करता है। इसके बजाय आपको अपने आप को XML को पार्स करना होगा और मानों को पीछे धकेलना होगा। शुक्र है कि XML फ़ाइल में एक सीधी संरचना है, इसलिए तत्वों पर लूप करना आसान है और इन्हें वापस प्राथमिकताओं में बदलना है।

if (restoreUserPrefs(context)) {
// Restart              
AlarmManager alm = (AlarmManager) context.getSystemService(
Context.ALARM_SERVICE);
alm.set(AlarmManager.RTC,
System.currentTimeMillis() + 1000, PendingIntent.getActivity(context, 0,
new Intent(context, MainActivityName.class), 0));
android.os.Process.sendSignal(android.os.Process.myPid(),
android.os.Process.SIGNAL_KILL);
}

नोट : बाहरी संग्रहण लिखना और पढ़ना आवश्यक है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.