12

I have some preference data, which should not be backup as they are not valid across different devices.

These are my Manifest.xml and backup rule file.

Manifest.xml

<application
    android:name=".WeNoteApplication"
    android:backupAgent="com.yocto.wenote.auto_backup.CustomBackupAgent"
    android:fullBackupOnly="true"
    android:allowBackup="true"
    android:fullBackupContent="@xml/my_backup_rules"

my_backup_rules.xml

<?xml version="1.0" encoding="utf-8"?>
<full-backup-content>
    <include domain="sharedpref" path="com.yocto.wenote_preferences.xml" />

    <exclude domain="sharedpref" path="com.yocto.wenote.backup.Backuper.xml" />
</full-backup-content>

I want to explicitly exclude preference with name "com.yocto.wenote.backup.Backuper"

I'm getting the following error from IDE

enter image description here

com.yocto.wenote.backup.Backuper.xml is not in an included path

May I know why it is so? How can I certainly exclude selected preference XML file from being backup-ed?

A similar issue was raised before : Android full backup: "file.xml is not in an included path" But, there are no solution.

Cheok Yan Cheng
  • 47,586
  • 132
  • 466
  • 875

3 Answers3

8

You are getting this error because the path you are excluding is outside the path that is included in the backup. If you specify any custom include, then ONLY those things will be backed up:

<include> - Specifies a file or folder to backup. By default, Auto Backup includes almost all app files. If you specify an element, the system no longer includes any files by default and backs up only the files specified. To include multiple files, use multiple elements.

Documentation here.

In your case, the exclude at com.yocto.wenote.backup.Backuper.xml is not on the include path com.yocto.wenote_preferences.xml - hence the error.

If you examine the code of the lint rule that generates the error message, it will confirm that because your exclude path does not have the prefix of any include, you will fall through to the !hasPrefix case.

Relevant portion here:

    for (String includePath : included) {
        if (excludePath.startsWith(includePath)) {
            if (excludePath.equals(includePath)) {
                Attr pathNode = exclude.getAttributeNode(ATTR_PATH);
                assert pathNode != null;
                Location location = context.getValueLocation(pathNode);
                // Find corresponding include path so we can link to it in the
                // chained location list
                for (Element include : includes) {
                    Attr includePathNode = include.getAttributeNode(ATTR_PATH);
                    String includeDomain = include.getAttribute(ATTR_DOMAIN);
                    if (includePathNode != null
                        && excludePath.equals(includePathNode.getValue())
                        && domain.equals(includeDomain)) {
                        Location earlier = context.getLocation(includePathNode);
                        earlier.setMessage("Unnecessary/conflicting <include>");
                        location.setSecondary(earlier);
                    }
                }
                context.report(ISSUE, exclude, location,
                               String.format("Include `%1$s` is also excluded", excludePath));
            }
            hasPrefix = true;
            break;
        }
    }
    if (!hasPrefix) {
        Attr pathNode = exclude.getAttributeNode(ATTR_PATH);
        assert pathNode != null;
        context.report(ISSUE, exclude, context.getValueLocation(pathNode),
                       String.format("`%1$s` is not in an included path", excludePath));
    }

Full code listing

So, in your case, you do not need to exclude that file at all, as ONLY com.yocto.wenote_preferences.xml is included in your backup.

You can also turn on verbose logging for the backup transport and XML parsing so that you can see what's happening:

adb shell setprop log.tag.GmsBackupTransport VERBOSE
adb shell setprop log.tag.BackupXmlParserLogging VERBOSE
kenny_k
  • 3,831
  • 5
  • 30
  • 41
  • Do you have idea how to verify the outcome in real device? I want to know what files are being backup-ed by running `adb shell bmgr backupnow xxx`. But, the console output doesn't provide such information. – Cheok Yan Cheng Sep 17 '19 at 13:30
  • The first thing that comes to mind is the indirect route - save something to the shared prefs that you expect to be included, run the backup/restore and make sure that it's there. Adjust your configuration to exclude that thing, repeat - make sure it's not there after restore. – kenny_k Sep 17 '19 at 14:46
  • additionally, you can try to enable verbose backups: `adb shell setprop log.tag.GmsBackupTransport VERBOSE` and `adb shell setprop log.tag.BackupXmlParserLogging VERBOSE` – kenny_k Sep 17 '19 at 15:00
0

As @kenny_k explained you have to specifically state the path in <include/> in order to exclude something from it. It means that you have to <include/> folder and <exclude/> files(or folders) from it - this is how it works.

In order to overcome this issue - try to remove <include/> tag completely - thus the system will loop through all the files it wants to backup and it will find this one file you want to exclude and it will exclude it. With <include/> tag you've limited the systems visibility to the value of the path field.

Hope it helps.

Pavlo Ostasha
  • 14,527
  • 11
  • 35
0

Use the Device File Explorer to browse app internal storage, to see which domains and filenames to include / exclude. Likely it's directory /data/data/com.yocto.wenote/shared_prefs/ (only browse-able for debug builds or with root permissions). The . (current directory) would include all files in shared_prefs - and com.yocto.wenote.backup.Backuper.xml is excluded:

<?xml version="1.0" encoding="utf-8"?>
<full-backup-content>
    <include domain="sharedpref" path="."/>
    <exclude domain="sharedpref" path="com.yocto.wenote.backup.Backuper.xml"/>
</full-backup-content>

If that file is not within domain sharedpref, there would be further domains:

domain=["file" | "database" | "sharedpref" | "external" | "root"]

Codelab Configure Auto Backup shows how to backup & restore manually.

Martin Zeitler
  • 1
  • 19
  • 155
  • 216