yeniden yükledikten sonra SharedPreferences'dan ve Android Auto backup kullanarak allowBackup = true ile değerler alma


9

Ben uygulamayı yeniden yükledikten sonra ve allowBackup = true sahipken paylaşılan Tercihler (Android 9.0 cihazında) değerleri alma konusunda sorun yaşıyorum.

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

Buna göre: https://developer.android.com/guide/topics/data/autobackup

Paylaşılan tercihler geri yüklenmeli mi?

    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();
  • Gmail hesabımda (emülatör) telefonda (API 27) oturum açtım ve Drive Uygulaması, Yedeklemeler, Uygulama verileri'ne giderken Youtube, Gmail vb.Gibi 18 Uygulamayı ve ayrıca kendi Uygulamamı görüyorum.
  • "Ayarlar> Sistem> Yedekleme" ye gittiğimde aynı Uygulamaları ve kendi Uygulamamı görüyorum. Uygulamayı yüklüyorum, sharedprefs kodu yürütülür. Uygulamayı kapatıyorum ve bellekten kaldırıyorum. Sonra "Şimdi yedekle" düğmesine basıyorum:

resim açıklamasını buraya girin

Uygulamamı listede görebildiğimi ve 0 dakika önce yedeklendiğini doğrulamak için:

resim açıklamasını buraya girin

Sonra App kaldırmak ve yeniden ve 2 değerleri (Elena ve 12) orada olmasını bekliyoruz. Ama siliniyorlar ...

Aynı şeyi komut satırı üzerinden de denedim, ancak çalışmıyor: 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. Uygulamayı Kaldır
  2. Uygulamayı yeniden yükleyin ve SharedPreferences değerlerinin hala orada olup olmadığını kontrol edin.
  3. Değerler gitti ...

Davranış ayrıca Samsung Cloud'lu Samsung cihazlarında farklı görünüyor, ancak şimdilik stok Android'e odaklanalım.

GÜNCELLEME:

Artık çalışmıyor.Çünkü build.gradle'daki sürümü düşürdüm:

build.gradle:
versionCode 70
versionName "1.6.1"

Hatta ile android:restoreAnyVersion="true"de AndroidManifestversiyon döndürüldüğünü değilken sadece çalışacak.



Merhaba @PraveenSP Eski anahtar / değer deposu sürümünü değil, Android Otomatik yedeklemeyi kullanmak istiyorum.
Jim Clermonts

Yanıtlar:


1

Varsayılan olarak android sistemi, cihaz bir Kablosuz ağa bağlıysa tüm varsayılan verileri yedekler (cihaz kullanıcısı mobil veri yedeklemelerini seçmediyse), uygulamayı yeniden yüklemeyi deneyin ve WI-FI genellikle android sistem senkronizasyonu ile bağlanın herhangi bir değişiklik varsa her 24 saatte bir veri. Bunun için yedekleme için kendi kurallarınızı belirtmeyi de deneyebilirsiniz.

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

ve bir xml dosyası oluşturun ve res / xml dizinine koyun . Dosyanın içine ve öğelerini içeren kurallar ekleyin. Aşağıdaki örnek, device.xml dışındaki tüm paylaşılan tercihleri ​​yedekler.

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

Umarım sorununuzu çözer.


Sadece paylaşımlıprefs kaydetmek istiyorum, xml yok.
Jim Clermonts

Yukarıdaki kod, android sisteminin kullanıcı sürücüsüne veri kaydetmesi için kurallar, xml olarak kaydedilmeyecek, Dahil Et ve Hariç Tut Etiketi, hangi verilerin senkronize edilmesi ve kaydedilmesi ve hangi verilerin senkronizasyon işleminde hariç tutulması gerektiğini sisteme bildirir .
Ashish srivastava

Anlıyorum ama bence gereksiz mi?
Jim Clermonts

1
sanmıyorum, android sistem önyükleme tamamlandığında onun gereksiz beacause ne zaman izin varsayılan olarak manifest yapılandırılmış tüm uygulamalar kuralları kontrol eder allowBackup doğru olduğunda senkronize, ama biz kuralları yazdığınızda android sistemi yerel kurallarda tutar ve paket adı ile ilişkilendirir.
Ashish srivastava

Yukarıdaki XML kodunu ekledim ancak bir fark yaratmıyor.
Jim Clermonts

1

Veri yeniden dokümana göre, oluşturmanız gereken SharedPreferencesBackupHelper ve bunlar izleyin adımları da gerek SharedPreferences yedeklemek ulaşmak için kayıt dava için yedekleme hizmetlerini


Merhaba, Android yedekleme hizmetinden değil Android Otomatik Yedekleme'den bahsediyorum.
Jim Clermonts

yalnızca otomatik yedekleme ile ilgilidir. örnek için şu adımları takip edebilirsiniz codelabs.developers.google.com/codelabs/android-backup-codelab/…
Damodhar

1

Bu prosedür sizin için işe yarar. Bir kullanıcının sharedPreferences'ı yedeklemeyi ve geri yüklemeyi deneyin. Bu, tercihinizi herhangi bir Harici Depolama veya cihaza yedekler.

Kullanıcı uygulamayı kaldırdığında, kullanıcının uygulamayı geri alması gerekir. Harici Depolama veya cihazda dosya varsa, dosyayı geri yükleyecek bir mantık ekleyin.

tercihinizi yedeklemek için aşağıdaki kodu kullanın.

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

tercihi geri yüklemek için aşağıdaki kodu kullanın

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

}

bu tercih beklemeden önce uygulamanızı yeniden başlatın

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

Merhaba, sorun build.gradle benim versionCode düşürüldüğünde yedekleme değil oldu. Bu yüzden işe yaramıyordu. Bu kadar kod yalnızca basit bir dizeyi saklamak için gerekli değildir.
Jim Clermonts

benim için çalıştı ... günümü kurtardı ... teşekkür ederim
19'da

0

Konsol mesajında ​​gösterildiği gibi Otomatik geri yükleme ayarlarını açmadınız. Sistem ayarlarına gitmeli ve açmalısınız. Bundan sonra restorasyon işe yarayabilir.

Ayarlar -> Yedekleme -> Otomatik geri yükleme.

BTW, kullandığınız belirteç doğru değil. 1573806051616, jeton yerine bir zaman damgasıdır. Jeton aşağıdaki gibi görünmelidir:

Ancestral packages: none
Ever backed up: XXXXXXXXXXXXXXXX

Burada, XXXXXXXXXXXXXXXXjeton olmalı.


-1

Geri yüklemeyi test etmek için, uygulamanızı kaldırmadan aşağıdaki komutu çalıştırmanız gerekir. Geri yükleme komutu, uygulamayı durdurmaya, verilerini silmeye ve geri yükleme işlemini gerçekleştirerek Android AutoBackup'ın işlevselliğini simüle edecektir:

bmgr restore <TOKEN> <PACKAGE>

TOKENalınır logcatyedekleme komutunu veya gelen çalıştırırken komuta dumpsys backupkomuta. Ayrıca dumpsys backupyedeklemenin oluşturulduğunu doğrulamak için işaretini kontrol edebilirsiniz .

Daha fazla bilgi burada: https://developer.android.com/guide/topics/data/testingbackup.html#TestingRestore


Bunu denedim ve cevabını düzenledim ama sharedpref değerleri hala gitti.
Jim Clermonts

Yedekleme için karşılanması gereken bazı ön koşullar vardır. Lütfen aşağıdaki bağlantıyı kontrol edin :: blog.devknox.io/…
Susheel Tickoo

Önkoşullar karşılandı ve çalışmıyor.
Jim Clermonts

-1

Bunu yapmanın bir yolu şu şekildedir, (Lütfen unutmayın, bu en iyi yol olmayabilir, ancak işe yarıyor!)

Uygulamayı kaldırmadan önce geri alın. Harici Depolama'da dosya varsa , geri yükleyeceğine dair bir mantık ekleyin .

SharedPreferences sınıfında saklanan tercihler /data/data//shared_prefs/_preferences.xml içine kaydedilir - yedekleme kolaydır, bu dosyanın içeriğini harici depoya kopyalamanız yeterlidir:

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

Tercihi geri yüklemek için aşağıdaki kodu kullanın

Ancak, restore_prefs dosyası uygulama tarafından doğrudan yazılabilir olmadığından ve SharedPrefs sınıfı işlevselliğini doğrudan xml'den serileştirmeye maruz bırakmadığından geri yükleme daha fazla zorluk sağlar. Bunun yerine XML'i kendiniz ayrıştırmanız ve değerleri tekrar içeri aktarmanız gerekir. Neyse ki XML dosyası basit bir yapıya sahiptir, bu nedenle öğeler üzerinde döngü yapmak ve bunları tekrar tercihlere dönüştürmek kolaydır.

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

NOT : Harici depolama yazma ve okuma izni gerekir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.