Abrufen von Werten aus SharedPreferences nach der Neuinstallation und mit allowBackup = true mithilfe der automatischen Android-Sicherung

9

Ich habe Probleme beim Abrufen von Werten (auf einem Android 9.0-Gerät) aus freigegebenen Einstellungen, nachdem ich die App neu installiert habe und allowBackup = true habe.

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

Demnach: https://developer.android.com/guide/topics/data/autobackup

Die gemeinsamen Einstellungen sollten wiederhergestellt werden?

    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();
  • Ich habe mich auf dem (Emulator-) Telefon (API 27) in meinem Google Mail-Konto angemeldet und sehe beim Aufrufen der Laufwerks-App, Backups, App-Daten 18 Apps wie Youtube, Google Mail usw. sowie meine eigene App.
  • Wenn ich zu "Einstellungen> System> Backup" gehe, sehe ich dieselben Apps und auch meine eigene App. Ich lade die App, Sharedprefs-Code wird ausgeführt. Ich schließe die App und entferne sie aus dem Speicher. Und dann drücke ich die Schaltfläche "Jetzt sichern":

Geben Sie hier die Bildbeschreibung ein

Zur Überprüfung kann ich meine App in der Liste sehen und sie wurde vor 0 Minuten gesichert:

Geben Sie hier die Bildbeschreibung ein

Dann entferne und installiere ich die App neu und erwarte, dass die 2 Werte (Elena und 12) vorhanden sind. Aber sie werden gelöscht ...

Ich habe das auch über die Befehlszeile versucht, aber es funktioniert auch nicht: 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. App entfernen
  2. Installieren Sie die App neu und prüfen Sie, ob die SharedPreferences-Werte noch vorhanden sind.
  3. Werte sind weg ...

Das Verhalten scheint sich auch auf Samsung-Geräten mit Samsung Cloud zu unterscheiden, aber jetzt konzentrieren wir uns auf Standard-Android.

AKTUALISIEREN:

Es funktionierte nicht mehr, weil ich die Version in build.gradle heruntergestuft habe:

build.gradle:
versionCode 70
versionName "1.6.1"

Auch mit android:restoreAnyVersion="true"in AndroidManifestwürde es nur funktionieren, wenn die Version nicht herabgestuft wurde.

Jim Clermonts
quelle
Dies könnte Ihnen helfen, Backup-Shared-Preferences-in-Android
PraveenSP
Hallo @PraveenSP Ich möchte Android Auto Backup verwenden und nicht die ältere Version des Schlüssel- / Wertspeichers.
Jim Clermonts

Antworten:

1

Standardmäßig sichert das Android-System alle Standarddaten, wenn das Gerät mit einem Wi-Fi-Netzwerk verbunden ist (wenn der Gerätebenutzer sich nicht für mobile Datensicherungen entschieden hat). Versuchen Sie, die App neu zu installieren und eine Verbindung mit WI-FI herzustellen Daten alle 24 Stunden einmal, wenn Änderungen vorhanden sind. Sie können auch versuchen, Ihre eigenen Regeln für die Sicherung wie folgt anzugeben.

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

Erstellen Sie eine XML-Datei und legen Sie sie im Verzeichnis res / xml ab. Fügen Sie in der Datei Regeln mit den Elementen und hinzu. Das folgende Beispiel sichert alle freigegebenen Einstellungen mit Ausnahme von 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>`

Ich hoffe, es wird Ihr Problem lösen.

Ashish Srivastava
quelle
Ich möchte nur sharedprefs speichern, keine XML.
Jim Clermonts
Der obige Code ist eine Regel für das Android-System zum Speichern von Daten auf dem Benutzerlaufwerk. Es wird nicht als XML gespeichert. Das Include & Exclude-Tag benachrichtigt das System darüber, welche Daten synchronisiert und gespeichert werden müssen und welche Daten beim Synchronisierungsvorgang ausgeschlossen werden müssen .
Ashish Srivastava
Ich verstehe, aber ich denke, es ist unnötig?
Jim Clermonts
1
Ich glaube nicht, dass es unnötig ist, weil beim Booten des Android-Systems alle im Manifest konfigurierten Apps-Regeln standardmäßig überprüft werden. Es wird auch synchronisiert, wenn allowBackup wahr ist, aber wenn wir Regeln schreiben, behält das Android-System die lokalen Regeln bei und ordnet es dem Paketnamen zu.
Ashish Srivastava
Ich habe den obigen XML-Code hinzugefügt, aber es macht keinen Unterschied.
Jim Clermonts
1

Gemäß dem Data Back-Dokument müssen Sie SharedPreferencesBackupHelper erstellen und diese Schritte ausführen, um eine SharedPreferences- Sicherung zu erreichen. Außerdem müssen Sie die Sicherungsdienste für Ihren Fall registrieren

Damodhar
quelle
Hallo, ich spreche von Android Auto Backup, nicht von Android Backup Service.
Jim Clermonts
Es bezieht sich nur auf die automatische Sicherung. Für das Beispiel können Sie diese Schritte ausführen
codelabs.developers.google.com/codelabs/android-backup-codelab/…
1

Möge dieses Verfahren für Sie funktionieren. Versuchen Sie, die sharedPreferences eines Benutzers zu sichern und wiederherzustellen. Dadurch wird Ihre Präferenz auf einem externen Speicher oder Gerät gesichert.

Wenn der Benutzer die App deinstalliert, sollte er sie sichern. Fügen Sie eine Logik hinzu, die wiederherstellt, wenn eine Datei im externen Speicher oder auf dem Gerät vorhanden ist.

Verwenden Sie den folgenden Code, um Ihre Präferenz zu sichern.

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

Verwenden Sie den folgenden Code, um die Einstellungen wiederherzustellen

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

}

Starten Sie dann Ihre App neu, bevor diese Einstellungen wirksam werden

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);
}
UD ..
quelle
Hallo, das Problem war, dass es nicht gesichert wird, wenn mein versionCode in build.gradle heruntergestuft wird. Deshalb hat es nicht funktioniert. So viel Code wird nicht benötigt, um nur eine einfache Zeichenfolge zu speichern.
Jim Clermonts
arbeitete für mich ... rettete meinen Tag ... danke
unownsp
0

Sie haben die Einstellungen für die automatische Wiederherstellung nicht aktiviert, wie in der Konsolenmeldung angezeigt. Sie sollten zu den Systemeinstellungen gehen und diese aktivieren. Danach könnte die Restaurierung funktionieren.

Einstellungen -> Backup -> Automatische Wiederherstellung.

Übrigens ist das von Ihnen verwendete Token nicht korrekt. 1573806051616 ist ein Zeitstempel anstelle des Tokens. Das Token sollte wie folgt aussehen:

Ancestral packages: none
Ever backed up: XXXXXXXXXXXXXXXX

Hier XXXXXXXXXXXXXXXXsollte das das Zeichen sein.

Freshomer
quelle
-1

Um die Wiederherstellung zu testen, müssen Sie den folgenden Befehl ausführen, ohne Ihre App zu entfernen. Der Wiederherstellungsbefehl erzwingt das Stoppen der App, löscht die Daten und führt die Wiederherstellung durch, wodurch die Funktionalität des Android AutoBackup simuliert wird:

bmgr restore <TOKEN> <PACKAGE>

TOKENwird logcatbeim Ausführen des Sicherungsbefehls oder beim dumpsys backupBefehl aus dem Befehl abgerufen . Sie können auch überprüfen dumpsys backup, ob das Backup erstellt wurde.

Weitere Informationen finden Sie hier: https://developer.android.com/guide/topics/data/testingbackup.html#TestingRestore

Ahasbini
quelle
Ich habe es versucht und die Antwort bearbeitet, aber die Sharedpref-Werte sind immer noch weg.
Jim Clermonts
Für die Sicherung müssen einige Voraussetzungen erfüllt sein. Bitte überprüfen Sie den folgenden Link: blog.devknox.io/…
Susheel Tickoo
Die Voraussetzungen sind erfüllt und es funktioniert nicht.
Jim Clermonts
-1

Eine Möglichkeit, dies zu tun, ist wie folgt: (Bitte beachten Sie, dass dies möglicherweise nicht der beste Weg ist, aber es funktioniert!)

Starten Sie die App, bevor Sie sie deinstallieren. Fügen Sie eine Logik hinzu , die wiederherstellt , wenn eine Datei im externen Speicher vorhanden ist.

In der SharedPreferences-Klasse gespeicherte Einstellungen werden in /data/data//shared_prefs/_preferences.xml gespeichert. Das Sichern ist einfach. Sie müssen lediglich den Inhalt dieser Datei in einen externen Speicher kopieren:

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

Verwenden Sie den folgenden Code, um die Einstellungen wiederherzustellen

Das Wiederherstellen ist jedoch eine größere Herausforderung, da die Datei shared_prefs nicht direkt von der App beschreibbar ist und die SharedPrefs-Klasse ihre Funktionalität nicht direkt für die Serialisierung aus XML verfügbar macht. Stattdessen müssen Sie das XML selbst analysieren und die Werte zurückschieben. Zum Glück hat die XML-Datei eine einfache Struktur, sodass es einfach ist, die Elemente zu durchlaufen und diese wieder in Einstellungen umzuwandeln.

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

HINWEIS : Schreib- und Leseberechtigung für externen Speicher erforderlich.

ChandraMouli Poreddy
quelle