My Android app comes both as a free and paid version. I have created a library project and two additional Application projects, one 'Free' and one 'Paid' version (signed with the same key, of course). Note that these Application projects are pretty much empty, no settings etc. Hence, the library contains 99% of the code.
My app creates both an SQLite
database and a SharedPreferences
file with user data. Is it possible to copy these files between the free and paid versions? (The preferences are more important than the database.)
E.g.
- User runs the free version. A database and configuration file are created.
- User installs the paid version and runs it.
- The paid version checks for any free version data and copies it. This is what I want!
If you don't wish to go to the trouble of implementing a
ContentProvider
, or if it is possible that both apps may remain installed and used, there is a different solution.Code and usage
Let us assume that the data in question is in a class:
Then, add a class to both apps as follows:
So far, this is a fairly standard shared preferences storage system. Now is where the fun starts. First, make sure that there is a private method for getting the data stored above, and a private method for broadcasting it.
Create a
BroadcastReceiver
class to catch data responses from the other app for our data:Now, provide the static access function for the apps to use. Note that it doesn't return anything, that's done by the response catcher above.
That's the core of it. We need one other class, and a tweak to the manifest. The class (to catch the requests from the other app for the data:
In the manifest, be sure to declare this class as a Receiver with the action name matching
StoredInfoManager.responseActionString
Using this is relative simple. The class you are using the data in must extend BroadcastReceiver:
Security
The weakness of this method is that anyone can register a receiver to catch the communication between the two apps. The code above circumvents this:
Make the request broadcast hard to fake through the use of a password. This answer sin't a place to discuss how you might make that password secure, but it is important to realise that you can't store data when you create the password to check it against later - it's a different app that will be checking.
Make the response harder to catch by using a unique action code each time.
Neither of these is fool proof. If you're simply passing around favourite app colours, you probably don't need any of the security measures. If you're passing around more sensitive information, you need both, and you need to think about making the password appropriately secure.
Other improvement
I've collected information from a number of stackoverflow answers to provide a way to copy all SharedPreference data from one app to another. In my particular case I'm using product flavours for a free and a pro app, and I want to copy from free to pro.
CAUTION: This only works if you have not released either version on the play store. If you add (or remove) sharedUserId to your app after it is on the play store, your users won't be able to update without uninstalling. I learnt this the hard way. Thanks Google..
Add sharedUserId to your manifest in both apps. Note that this will only work if both apps are signed with the same certificate.
Then call this method when you first intialize the pro app.
Also, according to this answer you will want to call
getSettingsFromFreeApp()
before any other call to get preferences in your app.This, of course, only works if you are signing the free and paid apps with the same cert (which most sane people do).