检测新安装或更新版本(Android应用程序)

Has*_*sam 27 android

我在Play商店有一个应用程序.我想要求如果用户想要使用应用程序的某个部分,他们必须先邀请朋友才能这样做.但我只想对应用程序的新安装施加此限制(对于在限制之前安装了应用程序的用户公平).很抱歉这个长篇介绍,我的问题是如何确定当前设备是否已更新应用程序或是否是新安装?

wud*_*huo 86

public static boolean isFirstInstall() {
    try {
        long firstInstallTime =   App.getContext().getPackageManager().getPackageInfo(getPackageName(), 0).firstInstallTime;
        long lastUpdateTime = App.getContext().getPackageManager().getPackageInfo(getPackageName(), 0).lastUpdateTime;
        return firstInstallTime == lastUpdateTime;
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
        return true;
    }
}



public static boolean isInstallFromUpdate() {
    try {
        long firstInstallTime =   App.getContext().getPackageManager().getPackageInfo(getPackageName(), 0).firstInstallTime;
        long lastUpdateTime = App.getContext().getPackageManager().getPackageInfo(getPackageName(), 0).lastUpdateTime;
        return firstInstallTime != lastUpdateTime;
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 回答问题时,最好详细解释,以便站点的其他用户更容易理解。 (2认同)
  • 这个解决方案适合我,非常干净.尼斯. (2认同)
  • 对我来说,它不起作用。如果我不断重复打开应用程序,则firstInstallTime和lastUpdateTime总是不同的。我认为只有在全新安装的情况下,lastUpdateTime和firstInstallTime才能相等。 (2认同)
  • 它不适用于 Android 30,并且两次都是相同的,但在较低版本上它可以正常工作。 (2认同)

Kar*_*uri 19

我能看到的唯一不涉及设备外部实体的解决方案是获取PackageInfo应用程序并检查其值

在第一次安装,firstInstallTime并且lastUpdateTime将具有相同的价值(至少我的设备上,他们是相同的); 更新后,值会有所不同,因为lastUpdateTime会更改.此外,您大致知道创建引入此新行为的版本的日期和时间,并且您还知道它将具有哪个版本代码.

我会扩展Application并实现此检查onCreate(),并将结果存储在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();
    }
}
Run Code Online (Sandbox Code Playgroud)

这不是万无一失的,如果用户真的想要,有办法绕过这个,但我认为这是好的.如果您想更好地跟踪这些内容并避免被用户篡改,您应该开始在服务器上存储用户信息(假设您有任何类型的后端).


Phi*_*e A 6

检查旧版本的应用是否在磁盘或首选项上保存了一些数据.这些数据必须是安全的,即用户不能删除(我不确定是否可能).

刚安装新版本时,此数据将不存在.如果新版本是旧版本的升级,则此数据将存在.

在最坏的情况下,旧用户将被标记为新用户并且将具有受限制的使用.


Vin*_*man 5

一个简洁的 Kotlin 解决方案,基于仍然优秀的 wudizhuo 答案:

 val isFreshInstall = with(packageManager.getPackageInfo(packageName, 0)) {
     firstInstallTime == lastUpdateTime
 }
Run Code Online (Sandbox Code Playgroud)

这可以直接从内部调用,Activity因为 Activity 是一个上下文(因此可以访问packageManager等)

如果您想在多个地方/上下文中使用它,它可以很容易地变成扩展属性:

val Context.isFreshInstall get() = with(packageManager.getPackageInfo(packageName, 0)) {
    firstInstallTime == lastUpdateTime
}
Run Code Online (Sandbox Code Playgroud)

这样,您可以简单地if (isFreshInstall)在任何 Activity 或if (requireContext().isFreshInstall)任何 Fragment 中写入。