Detect Android app upgrade and set Application class boolean for show/hide of EULA

29,466

Solution 1

It's much easier to just check your current app version.

PackageInfo packageInfo = activity.getPackageManager()
    .getPackageInfo(activity.getPackageName(), 0);
int versionCode = packageInfo.versionCode;

When your app starts, you check your SharedPreferences for an integer value with the version code. If there is none, or if it doesn't match, display the EULA. After the user accepts the EULA, write the versionCode value to the SharedPreferences.

versionCode will match the version number you store in the Manifest.

Solution 2

According to the original approach, I´ve managed it to detect if the app is upgraded by using BroadcastReceiver

public class YourUpgradeReceiver extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) {
        Uri packageName = intent.getData();
        if(packageName.toString().equals("package:" + context.getPackageName())){
            //Application was upgraded
        }
    } 
}

And in your Manifest

 <receiver android:name=".YourUpgradeReceiver">
            <intent-filter>
                <action android:name="android.intent.action.PACKAGE_REPLACED"/>
                <data android:scheme="package"/>
            </intent-filter>
 </receiver>

Solution 3

Detect If App Has Been Updated

SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
int versionCode = sharedPreferences.getInt("VERSION_CODE", BuildConfig.VERSION_CODE);

if(versionCode != BuildConfig.VERSION_CODE) {
    onAppUpdated();
}

sharedPreferences.edit().putInt("VERSION_CODE", BuildConfig.VERSION_CODE).apply();
Share:
29,466
hooked82
Author by

hooked82

I'm a Senior Software Engineer who has mainly focused on C# and ASP.NET. I'm now getting into Android Development, and have finished and published my first application: Pro Version: https://market.android.com/details?id=com.hookedroid.fishingcompanion Lite Version: https://market.android.com/details?id=com.hookedroid.fishingcompanion.lite @fishincompanionfacebook

Updated on March 06, 2020

Comments

  • hooked82
    hooked82 about 4 years

    I'm attempting to detect when my application has been upgraded using a BroadcastReceiver and set a boolean in my Application Class. This boolean will be used in conjunction with a few other booleans to determine whether or not to show the EULA dialog box to the user.

    I belive I've got it all setup correctly, but the EULA is still showing up when it shouldn't. Specifically when the user has already accepted the EULA in a previous version, the EULA hasn't changed in the version being upgraded to(Manually set by me), and the app is being upgraded.

    I believe the reason this isn't working is because my Application isn't running and therefore the isAppUpgrade() method isn't being called and setting the correct boolean flag. Can somebody confirm this is the case, or is there something wrong in my code?

    FYI - The EULA.show(Activity, boolean, boolean) static method is being called first thing in my Main activity.

    Here's some code

    Application Class

    public class MFCApplication extends Application {
    
        private boolean isUpgrade = false;
    
        /**
         * Returns a manually set value of whether the EULA has changed in this version of the App
         * @return true/false
         */
        public boolean hasEULAChanged() {
            return false;
        }
    
        /**
         * Returns whether or not the application has been upgraded.  Set by the UpgradeBroadcastReceiver
         * @return true/false
         */
        public boolean isAppUpgrade() {
            return isUpgrade;
        }
    
        /**
         * Method called by UpgradeBroadcastReceiver if the App has been upgraded
         */
        public void setAppIsUpgrade() {
            this.isUpgrade = true;
        }
    }
    

    BroadcastReceiver

    public class UpgradeBroadcastReceiver extends BroadcastReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent == null)
                return;
            if (context == null)
                return;
    
            String action = intent.getAction();
            if (action == null)
                return;
    
            if (action.equals(Intent.ACTION_PACKAGE_REPLACED)) {
                MFCApplication myApp = ((MFCApplication)((Activity)context).getApplication());
    
                myApp.setAppIsUpgrade();
            }
        }
    }
    

    EULA Class

    public class EULA {
    
        private static final String EULA_ASSET = "EULA";
        private static final String EULA_PREFERENCES = "eula";
        private static Activity mActivity;
    
        private static PackageInfo getPackageInfo() {
            PackageInfo pi = null;
            try {
                pi = mActivity.getPackageManager().getPackageInfo(mActivity.getPackageName(), PackageManager.GET_ACTIVITIES);
            } catch (PackageManager.NameNotFoundException ex) {
                ex.printStackTrace();
            }
            return pi;
        }
    
        public static boolean show(Activity activity, boolean hasEULAChanged, boolean isAppUpgrade) {
            mActivity = activity;
            final SharedPreferences preferences = activity.getSharedPreferences(EULA_PREFERENCES, Activity.MODE_PRIVATE);
            final PackageInfo packageInfo = getPackageInfo();
            String eulaPref = preferences.getString(EULA_PREFERENCES, "0");
            boolean eulaVersionAccepted = packageInfo.versionName.equals(eulaPref);
            if (!eulaVersionAccepted && (hasEULAChanged || !isAppUpgrade)) {
                //The EULA should be shown here, but it isn't
                return false;
            }
            return true;
        }
    }
    

    Application Manifest

    <receiver android:name=".helpers.UpgradeBroadcastReceiver">
        <intent-filter>
            <action android:name="android.intent.action.PACKAGE_REPLACED" />
            <data android:scheme="package" android:path="com.hookedroid.fishingcompanion" />
        </intent-filter>
    </receiver>
    
  • hooked82
    hooked82 almost 13 years
    Thanks EboMike! Just as soon as I posted this, I had realized there was an easier way (It's very later here haha), which is what you're suggesting. I also check that if they have accepted the EULA but the EULA has changed in this version, to show the EULA. Thanks!
  • AndiGeeky
    AndiGeeky over 8 years
    Which one is best approch ? Yours or suggested by 'EboMike' ??
  • Marian Klühspies
    Marian Klühspies over 8 years
    You have to make a simple question for yourself: do you need an event-based approach or is it enough to check for it at a certain point of your app? If you want that information right at the moment when your app is updated, go for my solution (example: background service). If it is enough to know it at the next application start, take the other solution. But you can also take my solution and write something to prefs which you can check afterwards to have the same behavior like EboMikes approach theoretically
  • Brais Gabin
    Brais Gabin almost 8 years
    How can I test this?
  • amitavk
    amitavk about 6 years
    You can also use BuildConfig.VERSION_CODE to grab the version code that's set in your app's build.gradle.
  • FrankKrumnow
    FrankKrumnow over 5 years
    By using the versionCode of the app itself you would display the EULA with every update even if the EULA had not changed. Better provide an extra version code for the EULA itself (perhaps as a string resource "eula_version") and compare that to the SharedPreference version code you saved the last time the user clicked "accept".
  • Fereshteh Naji
    Fereshteh Naji over 5 years
    @BraisGabin for check this, you can make two .APK fie of your application with two version code.like 10 and 11 version code. first install version 10 and then install version 11 and then you can test this.
  • Glaucus
    Glaucus over 5 years
    And just to be clear, your broadcast receiver gets called AFTER the update, correct? So when the receiver is fired it's the new code running not the old code. Correct? That is my assumption but wanted to confirm.