检测新安装或更新版本(Android 应用程序)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26352881/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Detect if new install or updated version (Android app)
提问by Hasam
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. But I only want to impose this restriction to new installs of the app (to be fair to users that have installed the app before the restriction). Sorry for the long intro, my question is how can I find out if the current device has updated the app or is a new install?
我在 Play 商店上有一个应用程序。我想提出一个要求,如果用户想使用应用程序的某个部分,他们必须先邀请朋友才能这样做。但我只想将此限制强加给应用程序的新安装(对在限制之前安装应用程序的用户公平)。抱歉,很长的介绍,我的问题是如何确定当前设备是否已更新应用程序或是否是新安装的?
采纳答案by Philippe A
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.
最坏的情况是,旧用户将被标记为新用户,并且使用受限。
回答by wudizhuo
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;
}
}
回答by Karakuri
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
我能看到的唯一不涉及设备外部实体的解决方案是获取PackageInfo
您的应用程序的值并检查
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.
在第一次安装,firstInstallTime
并且lastUpdateTime
将具有相同的价值(至少我的设备上,他们是相同的); 更新后,值会有所不同,因为lastUpdateTime
会改变。此外,您大致知道您创建引入此新行为的版本的日期和时间,并且您还知道它将具有哪个版本代码。
I would extend Application
and implement this checking in onCreate()
, and store the result in SharedPreferences
:
我会扩展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();
}
}
This is not foolproof, there are ways to circumvent this if the user reallywants 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).
这不是万无一失的,如果用户真的想要的话,有办法规避这一点,但我认为这已经足够了。如果您想更好地跟踪这些内容并避免被用户篡改,您应该开始在服务器上存储用户信息(假设您有任何类型的后端)。
回答by Webserveis
My solution is use SahredPreference
我的解决方案是使用 SahredPreference
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;
}
return 3 posibles values:
返回 3 个可能的值:
- 0: The APP is First Install
- 1: The APP run once time
- 2: The APP is Updated
- 0:APP是首次安装
- 1:APP运行一次
- 2:APP更新
回答by pjco
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 currentinstalls 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 grandfatheredin. Then, going forward, you can set the "has_shared"
default to true
因此,要跟踪这一点,一种方法是找到一条指向应用程序特定版本的信息。无论是带有时间戳的文件,还是SharedPreferences
,甚至是versionCode
(如@DaudArfin 在他的回答中所建议的)来自您希望允许用户不受此限制的应用程序的最后一个版本。那么你需要改变这一点。然后,该更改将成为您之前所有安装的参考点。对于这些用户,将他们的"has_shared"
标志标记为 true。他们成为祖父。然后,您可以将"has_shared"
默认值设置为true
(Original, partial answer below)
(原文,部分答案如下)
Use a SharedPrefence(or similar)
使用SharedPrefence(或类似的)
Use something like SharedPreferences
.
This way you can put a simple value like has_shared = true
and SharedPreferences
will persist through app updates.
使用类似的东西SharedPreferences
。通过这种方式,您可以放置一个简单的值,例如has_shared = true
并SharedPreferences
通过应用程序更新保持不变。
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
然后你只能在 pref 返回 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
SharedPreference 文档:http :
//developer.android.com/training/basics/data-storage/shared-preferences.html
回答by Shahbaz Hashmi
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.
调试时不起作用。所以你必须手动安装。
- Increase the versionCode in your app-level build.gradle (so it counts as an update).
- Click Build -> Build Bundle(s) / APK(s) -> Build APK(s), and select a debug APK.
Run following command in the terminal of Android Studio:
adb install -r C:\Repositories\updatelistener\app\build\outputs\apk\debug\app-debug.apk
- 增加应用级 build.gradle 中的 versionCode(因此它算作更新)。
- 单击 Build -> Build Bundle(s) / APK(s) -> Build APK(s),然后选择一个调试 APK。
在 Android Studio 的终端中运行以下命令:
adb install -r C:\Repositories\updatelistener\app\build\outputs\apk\debug\app-debug.apk
回答by amoljdv06
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;
}
}
}
回答by Daud Arfin
You can get the version code and version name using below code snippet
您可以使用以下代码片段获取版本代码和版本名称
String versionName = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
int versionCode = getPackageManager().getPackageInfo(getPackageName(), 0).versionCode;
Now you can check for the latest version and restrict as per your requirement.
现在您可以检查最新版本并根据您的要求进行限制。