다시 설치 한 후 Android Auto 백업을 사용하여 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. 가치는 사라졌다 ...

삼성 클라우드를 사용하는 삼성 기기에서는 동작이 달라 보이지만 지금은 재고 Android에 중점을 두겠습니다.

최신 정보:

build.gradle에서 버전을 다운 그레이드했기 때문에 더 이상 작동하지 않았습니다.

build.gradle:
versionCode 70
versionName "1.6.1"

심지어와 android:restoreAnyVersion="true"AndroidManifest버전이 다운 그레이드되지 않은 경우에만 작동합니다.



안녕하세요 @PraveenSP 이전 키 / 값 저장소 버전이 아닌 Android 자동 백업을 사용하고 싶습니다.
Jim Clermonts

답변:


1

기기가 Wi-Fi 네트워크에 연결된 경우 기본적으로 Android 시스템은 모든 기본 데이터를 백업합니다 (기기 사용자가 모바일 데이터 백업을 선택하지 않은 경우). 앱을 다시 설치하고 WI-FI로 연결합니다. 변경 사항이있는 경우 24 시간마다 한 번씩 데이터를 수집합니다. 이와 같은 백업 규칙을 직접 지정할 수도 있습니다.

`<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를 저장하고 싶습니다.
Jim Clermonts

위의 코드는 안드로이드 시스템이 사용자 드라이브에 데이터를 저장하는 규칙이며 xml로 저장되지 않습니다. 포함 및 제외 태그는 시스템에 데이터를 동기화하고 저장해야하며 동기화 작업에서 제외 해야하는 데이터를 알려줍니다 .
Ashish srivastava

이해하지만 필요하지 않습니까?
Jim Clermonts

1
안드로이드 시스템 부팅이 완료 될 때 불필요 한 beacause는 기본적으로 매니페스트에 구성된 모든 앱 규칙을 확인합니다. 또한 allowBackup이 true 일 때 동기화되지만 규칙을 작성할 때 안드로이드 시스템은 로컬 규칙을 유지하고 패키지 이름과 연결합니다.
Ashish srivastava

위의 XML 코드를 추가했지만 차이가 없습니다.
Jim Clermonts

1

데이터 백 문서에 따라 SharedPreferencesBackupHelper 를 작성 하고 다음 단계 에 따라 SharedPreferences를 백업하고 케이스에 대한 백업 서비스 를 등록 해야합니다.


안녕하세요, 저는 Android 백업 서비스가 아니라 Android 자동 백업에 대해 이야기하고 있습니다.
Jim Clermonts

자동 백업에만 관련됩니다. 샘플에 대한 당신이 따를 수있는 다음 단계는 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();

}

이 prepreence가 보류되기 전에 앱을 다시 시작하십시오.

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가 다운 그레이드 될 때 백업되지 않는다는 것입니다. 그것이 작동하지 않는 이유입니다. 이 많은 코드는 간단한 문자열 만 저장하는 데 필요하지 않습니다.
Jim Clermonts

나를 위해 일했다 ... 내 하루를 구했다 ... 감사합니다
unownsp

0

콘솔 메시지에 표시된대로 자동 복원 설정을 설정하지 않았습니다. 시스템 설정으로 가서 전원을 켜야합니다. 그 후 복원이 작동 할 수 있습니다.

설정-> 백업-> 자동 복원.

BTW, 사용한 토큰이 올바르지 않습니다. 1573806051616은 토큰 대신 타임 스탬프입니다. 토큰은 다음과 같이 나타납니다.

Ancestral packages: none
Ever backed up: XXXXXXXXXXXXXXXX

여기서 XXXXXXXXXXXXXXXX토큰이어야합니다.


-1

복원을 테스트하려면 앱을 제거하지 않고 아래 명령을 실행해야합니다. restore 명령은 앱을 강제로 중지하고 데이터를 지우고 복원을 수행하므로 Android AutoBackup의 기능을 시뮬레이션합니다.

bmgr restore <TOKEN> <PACKAGE>

TOKENlogcatbackup 명령을 실행할 때 명령에서 또는 명령 에서 검색됩니다 dumpsys backup. 또한 dumpsys backup백업이 생성되었는지 확인하기 위해를 확인할 수 있습니다 .

자세한 정보는 여기 ( https://developer.android.com/guide/topics/data/testingbackup.html#TestingRestore)


나는 이것을 시도하고 답을 편집했지만 sharedpref 값은 여전히 ​​사라졌습니다.
Jim Clermonts

백업을 위해 충족해야 할 몇 가지 전제 조건이 있습니다. 아래 링크를 확인하십시오 :: blog.devknox.io/…
Susheel Tickoo

전제 조건이 충족되었으며 작동하지 않습니다.
Jim Clermonts

-1

이를 수행하는 한 가지 방법은 다음과 같습니다 (이 방법이 최선의 방법은 아니지만 작동합니다!).

앱을 제거하기 전에 백업하십시오. 파일이 External Storage 에 있으면 다시 복원한다는 논리를 추가하십시오 .

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.