Detect if new install or updated version (Android app)

前端 未结 8 1030
-上瘾入骨i
-上瘾入骨i 2020-12-24 06:41

I have an app on the Play Store. I want to put a requirement that if users want to use a certain part of the app, they have to invite a friend before being able to do so. Bu

相关标签:
8条回答
  • 2020-12-24 06:45

    Check if the old version of your app saves some data on disk or preferences. This data must be safe, i.e. it cannot be deleted by the user (I'm not sure it's possible).

    When the new version is freshly installed, this data won't exist. If the new version is an upgrade from the old version, this data will exist.

    Worst case scenario, an old user will be flagged as a new one and will have a restricted usage.

    0 讨论(0)
  • 2020-12-24 06:45

    We can use broadcast receiver to listen app update.

    Receiver

    class AppUpgradeReceiver : BroadcastReceiver() {
    
      @SuppressLint("UnsafeProtectedBroadcastReceiver")
      override fun onReceive(context: Context?, intent: Intent?) {
        if (context == null) {
            return
        }
        Toast.makeText(context, "Updated to version #${BuildConfig.VERSION_CODE}!", Toast.LENGTH_LONG).show()
      }
    
    }
    

    Manifest

    <receiver android:name=".AppUpgradeReceiver">
    <intent-filter>
        <action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
    </intent-filter>
    

    It doesn't work while debug. So you have to install to manually.

    1. Increase the versionCode in your app-level build.gradle (so it counts as an update).
    2. Click Build -> Build Bundle(s) / APK(s) -> Build APK(s), and select a debug APK.
    3. Run following command in the terminal of Android Studio:

      adb install -r C:\Repositories\updatelistener\app\build\outputs\apk\debug\app-debug.apk
      
    0 讨论(0)
  • 2020-12-24 06:46

    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).

    0 讨论(0)
  • 2020-12-24 06:47
    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;
        }
    }
    
    0 讨论(0)
  • 2020-12-24 06:48

    If you want to perform any operation only once per update then follow below code snippet

    private void performOperationIfInstallFromUpdate(){ 
    try {
            SharedPreferences prefs = getActivity().getPreferences(Context.MODE_PRIVATE);
            String versionName = prefs.getString(versionName, "1.0");
            String currVersionName = getApplicationContext().getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
            if(!versionName.equals(currVersionName)){
                //Perform Operation which want execute only once per update
                //Modify pref 
                SharedPreferences.Editor editor = prefs.edit();
                editor.putString(versionName, currVersionName);
                editor.commit();
            }
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            return BASE_VERSION;
        }
    

    }

    0 讨论(0)
  • 2020-12-24 06:50

    Update

    (thanks for the comments below my answer for prodding for a more specific/complete response).

    Because you can't really retroactively change the code for previous versions of your app, I think the easiest is to allow for all current installs to be grandfathered in.

    So to keep track of that, one way would be to find a piece of information that points to a specific version of your app. Be that a timestamped file, or a SharedPreferences, or even the versionCode (as suggested by @DaudArfin in his answer) from the last version of the app you want to allow users to not have this restriction. Then you need to change this. That change then becomes your reference point for all the previous installs. For those users mark their "has_shared" flag to true. They become grandfathered in. Then, going forward, you can set the "has_shared" default to true

    (Original, partial answer below)

    Use a SharedPrefence (or similar)

    Use something like SharedPreferences. This way you can put a simple value like has_shared = true and SharedPreferences will persist through app updates.

    Something like this when they have signed someone up / shared your app

    SharedPreferences prefs = getActivity().getPreferences(Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = prefs.edit();
    editor.putBoolean("has_shared", true)
    editor.commit();
    

    Then you can only bug people when the pref returns true

    SharedPreferences prefs = getActivity().getPreferences(Context.MODE_PRIVATE);
    boolean defaultValue = false;
    boolean hasShared= prefs.gettBoolean("has_shared", defaultValue);
    if (!hasShared) {
        askUserToShare();
    }
    

    Docs for SharedPreference:
    http://developer.android.com/training/basics/data-storage/shared-preferences.html

    0 讨论(0)
提交回复
热议问题