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

lmvvr0a8  于 2023-01-11  发布在  Android
关注(0)|答案(9)|浏览(204)

我在Play商店有一个应用。我想提出一个要求,如果用户想使用应用的某个部分,他们必须邀请朋友才能使用。但我只想对新安装的应用施加这个限制(公平地说,对于限制前已经安装应用的用户)。抱歉介绍太长,我的问题是,我如何才能知道当前设备是否更新了应用程序,或者是新安装的?

nbysray5

nbysray51#

我的解决方案是使用SharedPreference

private int getFirstTimeRun() {
    SharedPreferences sp = getSharedPreferences("MYAPP", 0);
    int result, currentVersionCode = BuildConfig.VERSION_CODE;
    int lastVersionCode = sp.getInt("FIRSTTIMERUN", -1);
    if (lastVersionCode == -1) result = 0; else
        result = (lastVersionCode == currentVersionCode) ? 1 : 2;
    sp.edit().putInt("FIRSTTIMERUN", currentVersionCode).apply();
    return result;
}

返回3个posibles值:

  • 0:APP为首次安装
  • 1:APP运行一次
  • 2:APP更新
njthzxwz

njthzxwz2#

更新

  • (感谢我的答复下面的评论,以促使作出更具体/完整的答复)。*

因为你真的不能追溯改变你的应用程序以前版本的代码,我认为最简单的是允许所有***当前***安装的祖父。
因此,要跟踪这一点,一种方法是找到指向应用特定版本的信息。无论是带时间戳的文件还是SharedPreferences,甚至是versionCode(正如@DaudArfin在回答中所建议的)从上一个版本的应用程序开始,你想让用户没有这个限制。那么你需要改变这一点。然后,该更改将成为所有先前安装的参考点。对于这些用户,请将其"has_shared"标记标记标记为true。他们将在中成为"grandfathered"。然后,您可以将"has_shared"默认设置设置为true
(原件,部分答复见下文)

使用共享首选项(或类似选项)

使用类似SharedPreferences的值,这样你就可以输入一个类似has_shared = true的简单值,SharedPreferences将在应用更新过程中持续存在。
当用户注册/共享您的应用程序时会出现类似情况

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

那么只有当pref返回true时,您才能窃听用户

SharedPreferences prefs = getActivity().getPreferences(Context.MODE_PRIVATE);
boolean defaultValue = false;
boolean hasShared= prefs.gettBoolean("has_shared", defaultValue);
if (!hasShared) {
    askUserToShare();
}
    • 共享首选项的文档:**

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

yquaqz18

yquaqz183#

您可以使用下面的代码片段获得版本代码和版本名称

String versionName = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;

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

现在您可以检查最新版本并根据您的要求进行限制。

a2mppw5e

a2mppw5e4#

我们可以使用广播接收器来收听应用程序更新。

接收器

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()
  }

}

清单

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

调试时不起作用,所以你必须手动安装。
1.增加应用级build.gradle中的versionCode(以便将其视为更新)。
1.点击构建-〉构建捆绑包/ APK-〉构建APK,然后选择调试APK。
1.在Android Studio的终端中运行以下命令:

adb install -r C:\Repositories\updatelistener\app\build\outputs\apk\debug\app-debug.apk
e3bfsja2

e3bfsja25#

如果您希望每次更新只执行一次任何操作,请按照以下代码片段

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;
    }

}

tgabmvqs

tgabmvqs6#

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;
    }
}
vfwfrxfs

vfwfrxfs7#

我认为唯一不涉及设备外部实体的解决方案是获取应用的PackageInfo并检查

  • versionCode
  • firstInstallTime
  • lastUpdateTime

在第一次安装时,firstInstallTimelastUpdateTime将具有相同的值(至少在我的设备上它们是相同的);在更新之后,值将不同,因为lastUpdateTime将改变。2另外,您知道创建引入此新行为的版本的大致日期和时间,并且您还知道它将具有哪个版本代码。
我将扩展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();
    }
}

这并不是万无一失的,如果用户真的想这么做,有很多方法可以绕过这个问题,但我认为这是最好的办法了。如果你想更好地跟踪这些信息,避免用户篡改,你应该开始在服务器上存储用户信息(假设你有任何后端)。

jhdbpxl9

jhdbpxl98#

检查旧版本的应用是否在磁盘或偏好设置中保存了一些数据。这些数据必须是安全的,即用户无法删除(我不确定是否可能)。
新版本刚安装时,此数据将不存在。如果新版本是旧版本的升级版本,则此数据将存在。
最坏的情况是,旧用户将被标记为新用户,并限制其使用。

mv1qrgav

mv1qrgav9#

一个简洁的Kotlin解答,基于考夫林的出色回答:

val isFreshInstall = with(packageManager.getPackageInfo(packageName, 0)) {
     firstInstallTime == lastUpdateTime
 }

这可以直接从Activity中调用,因为“活动”是一个上下文(因此可以访问packageManager等)。
如果你想在多个地方/上下文中使用它,可以很容易地将它转换成一个扩展属性:

val Context.isFreshInstall get() = with(packageManager.getPackageInfo(packageName, 0)) {
    firstInstallTime == lastUpdateTime
}

这样,您就可以在任何“活动”中写入if (isFreshInstall),或者在任何“片段”中写入if (requireContext().isFreshInstall)

相关问题