2

In my Android app I use a set of randomly generated file names to store some data. In order to ensure that the same set of file names are generated at app restart - and are yet different for each app installation - I start off the process by picking the names as substrings from a long string of random alphanumeric characters which I generate when the app is installed. This latter string is stored in Shared Prefereneces.

As I am testing out the app I have run into a rather peculiar issue. From time-to-time I make major changes so I fully uninstall the app - and even Force Close it + clear all its data. At that point I would expect that the device would have no "prior knowledge" of the app if it is reinstalled. And yet I find that the Shared Preferences string is somehow "remembered". This causes havoc if in the interim I have changed how the file name substrings are picked up from the stored shared preferences string.

How can I ensure that the app has "zero memory" of a previously installed version that has subsequently been uninstalled?


One solution I have used in the past is to instruct Android not to do any backups via the manifest file, android:allowBackup = "false". However, I have backed away from that idea since - unless I am mistaken - it effectively means that I am stopping the user from porting their app over to a new device when they decide to change handsets.

DroidOS
  • 8,530
  • 16
  • 99
  • 171
  • 2
    We had same issue and get resolved by `android:allowBackup="false"` in `AndroidManifest.xml.` now try it with new device, it should have resolved. I have no idea how it worked. – Rumit Patel Nov 17 '18 at 05:37
  • Thanks for the comment. I have changed my question a bit. I had tried the `android:allowBackup` approach but find that it can raise other issues as I explain now. – DroidOS Nov 17 '18 at 05:46
  • I just saw these comments and your updated question. I'll revise my answer. – hungryghost Nov 17 '18 at 05:50

3 Answers3

4

On (re)install, your app may be restoring files from Google auto-backup (via Google Drive). To disable this feature, you can explicitly set it to false in the manifest:

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

If you'd like more granular control over what is backed up/restored and what is not, you can include or exclude specific files from the backups.

See auto backup documentation: https://developer.android.com/guide/topics/data/autobackup#EnablingAutoBackup

If you don't want to disable auto backups, but want to reinstall with a "clean slate" (for testing purposes), you can do one of the following:

  • Clear app data after reinstall. This will wipe out files that were restored automatically on install
  • Clear app data prior to uninstall, then force a new backup (so old one gets reset) by using this command: adb shell bmgr backupnow <PACKAGE>

See how to test backups documentation: https://developer.android.com/guide/topics/data/testingbackup#TestingBackup

hungryghost
  • 9,463
  • 3
  • 23
  • 36
  • I am accepting and upvoting your answer because you put me on the right track here. I have provided my solution to the issue - based on what you suggested - as a separate answer for the benefit of others who might run into a similar situation. – DroidOS Nov 17 '18 at 06:18
2

To extend on this, for example mobile/src/debug/AndroidManifest.xml

<application
    tools:replace="android:allowBackup"
    android:allowBackup="false">

    ...

</application>

Alike this one can disable auto-backup for debug builds - but keep it enabled for release builds.

Simply because disabling auto-backup for release builds might not be the intended outcome.

Martin Zeitler
  • 1
  • 19
  • 155
  • 216
1

Based on @hungryghost's suggestion the I eventually implemented a solution

Problem:Shared preferences can be remembered by Android after app reinstall and blanket instructions in the manifest along the lines of android:allowBackup = "false" are not a solution.

So why not turn the problem into a solution on its own? Here is what I do

  • Check shared preferences for a build specific key.
  • If that key is not found I do two things

    1. Clear out all shared preferences, context.deleteSharedPrefernces(filename)
    2. Now create that build specific key
    3. When I make app changes that require old preferences to be forgotten I simply change the build specific key.
DroidOS
  • 8,530
  • 16
  • 99
  • 171
  • `context.deleteSharedPreferences(filename)` could also be executed at the click of a button (here I have one fragment only accessible in debug builds, barely for test/debug related preferences). – Martin Zeitler Nov 17 '18 at 06:47