再インストール後、Android自動バックアップを使用して、allowBackup = trueでSharedPreferencesから値を取得する


9

アプリを再インストールした後、allowBackup = trueを設定しているときに、共有設定から(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();
  • (エミュレータ)電話(API 27)でGmailアカウントにログインしました。ドライブアプリ、バックアップ、アプリデータに移動すると、Youtube、Gmailなどの18個のアプリと自分のアプリが表示されます。
  • 「設定>システム>バックアップ」に移動すると、同じアプリと自分のアプリが表示されます。アプリをロードすると、sharedprefsコードが実行されます。アプリを閉じて、メモリから削除します。次に、「今すぐバックアップ」ボタンを押します。

ここに画像の説明を入力してください

確認するには、リストにアプリが表示され、0分前にバックアップが取得されました。

ここに画像の説明を入力してください

次に、アプリを削除して再インストールし、2つの値(Elenaと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. アプリを再インストールし、SharedPreferencesの値がまだ残っているかどうかを確認します。
  3. 値がなくなっています...

Samsung Cloudを搭載したSamsungデバイスでも動作が異なるようですが、今のところ、Androidのストックに焦点を当てましょう。

更新:

build.gradleでバージョンをダウングレードしたため、機能しなくなりました。

build.gradle:
versionCode 70
versionName "1.6.1"

でも、とandroid:restoreAnyVersion="true"AndroidManifestバージョンがダウングレードされなかったときにのみ動作します。



こんにちは@PraveenSP古いキー/バリューストアバージョンではなく、Android自動バックアップを使用したいと思います。
ジムクレルモンズ

回答:


1

デフォルトでは、デバイスがWi-Fiネットワークに接続されている場合(デバイスユーザーがモバイルデータバックアップを選択していない場合)、Androidシステムはすべてのデフォルトデータをバックアップし、アプリを再インストールしてWI-FIで接続してみます変更があった場合、24時間に1回のデータ。このようなバックアップの独自のルールを指定することもできます。

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

xmlファイルを作成し、res / xmlディレクトリに配置します。 ファイル内に、および要素を含むルールを追加します。次のサンプルは、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>`

それがあなたの問題を解決することを願っています。


xmlではなくsharedprefsを保存したいだけです。
ジムクレルモンズ

上記のコードは、Androidシステムがユーザードライブにデータを保存するためのルールです。これはxmlとして保存されません。包含および除外タグは、どのデータを同期して保存し、どのデータを同期操作で除外する必要があるかをシステムに通知します。 。
Ashish srivastava

理解しましたが、不要だと思いますか?
ジムクレルモンズ

1
私は考えていません、Androidシステムのブートが完了すると、デフォルトでマニフェストに構成されているすべてのアプリのルールをチェックするので、不必要な理由です。
Ashish srivastava

上記のXMLコードを追加しましたが、違いはありません。
ジムクレルモンズ

1

データバックドキュメントに従って、作成する必要があります に従って、SharedPreferencesBackupHelper、これらの手順に従ってSharedPreferencesをバックアップする必要があります。また、ケースのバックアップサービスを登録する必要があります。


こんにちは、Androidバックアップサービスではなく、Android Auto Backupのことです。
ジムクレルモンズ

自動バックアップのみに関連しています。サンプルのためにあなたが続くことができるこれらの手順は、codelabs.developers.google.com/codelabs/android-backup-codelab/...
Damodhar

1

この手順がうまくいくように。ユーザーのsharedPreferencesのバックアップと復元を試みます。これにより、任意の外部ストレージまたはデバイスに設定がバックアップされます。

ユーザーがアプリをアンインストールするとき、ユーザーはそれをバックアップする必要があります。外部ストレージまたはデバイスにファイルが存在する場合、それを元に戻すというロジックを追加します。

以下のコードを使用して、設定をバックアップしてください。

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のversionCodeがダウングレードされたときにバックアップされないことでした。それが機能しなかった理由です。単純な文字列のみを格納するのにこれだけのコードは必要ありません。
ジムクレルモンズ

私のために働いた...私の日を救った...ありがとう
unownsp

0

コンソールメッセージに表示されているように、自動復元設定をオンにしていません。システム設定に移動して、オンにする必要があります。その後、復元は機能します。

設定->バックアップ->自動復元。

ところで、あなたが使用したトークンは正しくありません。1573806051616は、トークンではなくタイムスタンプです。トークンは次のように表示されます。

Ancestral packages: none
Ever backed up: XXXXXXXXXXXXXXXX

ここではXXXXXXXXXXXXXXXX、トークンでなければなりません。


-1

復元をテストするには、アプリを削除せずに以下のコマンドを実行する必要があります。復元コマンドはアプリを強制的に停止し、データをワイプして復元を実行するため、Android AutoBackupの機能をシミュレートします。

bmgr restore <TOKEN> <PACKAGE>

TOKENlogcatバックアップコマンドの実行時のコマンドまたはコマンドから取得されますdumpsys backup。また、dumpsys backupをチェックして、バックアップが作成されたことを確認することもできます。

詳細はこちら:https : //developer.android.com/guide/topics/data/testingbackup.html#TestingRestore


私はこれを試して答えを編集しましたが、sharedpref値はまだ消えています。
ジムクレルモンズ

バックアップのために満たすべきいくつかの前提条件があります。下のリンクをご確認ください:: blog.devknox.io/...
Susheel Tickoo

前提条件が満たされ、機能していません。
ジムクレルモンズ

-1

これを行う1つの方法は次のとおりです。 (これは最善の方法ではないかもしれませんが、機能します!)

アプリをアンインストールする前に、バックアップを取ってください。外部ストレージにファイルが存在する場合、それを元に戻すというロジックを追加します。

SharedPreferencesクラスに保存されている設定は/data/data//shared_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();
}

次のコードを使用して設定を復元します

ただし、shared_prefsファイルはアプリから直接書き込めず、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);
}

:外部ストレージの書き込みおよび読み取り権限が必要です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.