Detect if new install or updated version (Android app)
The only solution I can see that doesn't involve an entity outside of the device would be to get the PackageInfo
for your app and check the values of
versionCode
firstInstallTime
lastUpdateTime
On first install, firstInstallTime
and lastUpdateTime
will have the same value (at least on my device they were the same); after an update, the values will be different because lastUpdateTime
will change. Additionally, you know approximately what date and time you create the version that introduces this new behavior, and you also know which version code it will have.
I would extend Application
and implement this checking in onCreate()
, and store the result in SharedPreferences
:
public class MyApplication extends Application {
// take the date and convert it to a timestamp. this is just an example.
private static final long MIN_FIRST_INSTALL_TIME = 1413267061000L;
// shared preferences key
private static final String PREF_SHARE_REQUIRED = "pref_share_required";
@Override
public void onCreate() {
super.onCreate();
checkAndSaveInstallInfo();
}
private void checkAndSaveInstallInfo() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
if (prefs.contains(PREF_SHARE_REQUIRED)) {
// already have this info, so do nothing
return;
}
PackageInfo info = null;
try {
info = getPackageManager().getPackageInfo(getPackageName(), 0);
} catch (NameNotFoundException e) {
// bad times
Log.e("MyApplication", "couldn't get package info!");
}
if (packageInfo == null) {
// can't do anything
return;
}
boolean shareRequired = true;
if (MIN_FIRST_INSTALL_TIME > info.firstInstallTime
&& info.firstInstallTime != info.lastUpdateTime) {
/*
* install occurred before a version with this behavior was released
* and there was an update, so assume it's a legacy user
*/
shareRequired = false;
}
prefs.edit().putBoolean(PREF_SHARE_REQUIRED, shareRequired).apply();
}
}
This is not foolproof, there are ways to circumvent this if the user really wants to, but I think this is about as good as it gets. If you want to track these things better and avoid tampering by the user, you should start storing user information on a server (assuming you have any sort of backend).
public static boolean isFirstInstall(Context context) {
try {
long firstInstallTime = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).firstInstallTime;
long lastUpdateTime = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).lastUpdateTime;
return firstInstallTime == lastUpdateTime;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return true;
}
}
public static boolean isInstallFromUpdate(Context context) {
try {
long firstInstallTime = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).firstInstallTime;
long lastUpdateTime = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).lastUpdateTime;
return firstInstallTime != lastUpdateTime;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return false;
}
}