I am facing this situation as well. The general advice is that you can save the installed version to a SharedPreference, which will persist between app installs. If you are in a position to be able to make an update before changing to the subscription model, and have a reasonable expectation that the majority of your users will update the app to this pre-subscription version, then this route is possible. The flow then is to check the version number that was installed previously, compare to the current version number, and if they are upgrading from e.g. v1 to v2, then register the free subscription.
However, there is another route you can take which is to add the MY_PACKAGE_REPLACED intent to your subscription version of the app. Using this, you will receive an event that tells you if the app has been updated, although there is no other information included. In this case, you will need to wait for this event to be received - it is not sent on app startup, but slightly after this. In my app, I wait for onCreateView to be called on my first Fragment before checking.
In this case the flow is similar to the first case, but you have to make a slightly more complicated check. This is the Kotlin code I’m using for this:
ReinstallReceiver is a BroadcastReceiver subclass, that simply sets installState to ReinstallState.Reinstall when it receives the intent.
lastInstalledVersionCode is the version code saved in SharedPreferences or 0 if there is no code.
fun calculateUpgradeType (): UpgradeType {
// Make sure to run this _after_ the ReinstallReceiver might have been called!
// we have a version number, so we must have v2+ already installed
if (lastInstalledVersionCode > 0L) {
// The app has a version number, and was not upgraded, so it must be a normal launch
if (installState == ReinstallState.Unchecked) {
return UpgradeType.V2Launch
}
// The app has been upgraded to another version 2
else if (installState == ReinstallState.Reinstall) {
return UpgradeType.V2Update
}
// we do not have a version number
} else {
// it was not an update, therefore this is a new install of v2
if (installState == ReinstallState.Unchecked) {
return UpgradeType.V2Fresh
}
// it was an update, therefore we must be upgrading from v1
else if (installState == ReinstallState.Reinstall) {
return UpgradeType.V1Upgrade
}
}
return UpgradeType.V2Launch
}
From my testing, this works in every case except:
If the user has v1 installed, but has never opened it OR
The user has bought the app, but has uninstalled it or is installing on a new device.
If this function returns V1Upgrade, then I register the free subscription as above.