Java 检测Android应用程序升级并为EULA的显示/隐藏设置应用程序类布尔值
我试图检测何时使用BroadcastReceiver升级了我的应用程序,并在我的应用程序类中设置布尔值。此布尔值将与其他几个布尔值一起使用,以确定是否向用户显示EULA对话框 我相信我已经把它全部设置好了,但是EULA仍然在不应该出现的时候出现。特别是当用户已经在以前的版本中接受EULA时,EULA在升级到的版本中没有更改(由我手动设置),并且应用程序正在升级 我认为这不起作用的原因是因为我的应用程序没有运行,因此没有调用isAppUpgrade()方法并设置正确的布尔标志。有人能证实这是真的吗?或者我的代码中有什么错误吗 仅供参考-在我的主要活动中,首先调用EULA.show(Activity,boolean,boolean)静态方法 这里有一些代码 应用程序类Java 检测Android应用程序升级并为EULA的显示/隐藏设置应用程序类布尔值,java,android,broadcastreceiver,Java,Android,Broadcastreceiver,我试图检测何时使用BroadcastReceiver升级了我的应用程序,并在我的应用程序类中设置布尔值。此布尔值将与其他几个布尔值一起使用,以确定是否向用户显示EULA对话框 我相信我已经把它全部设置好了,但是EULA仍然在不应该出现的时候出现。特别是当用户已经在以前的版本中接受EULA时,EULA在升级到的版本中没有更改(由我手动设置),并且应用程序正在升级 我认为这不起作用的原因是因为我的应用程序没有运行,因此没有调用isAppUpgrade()方法并设置正确的布尔标志。有人能证实这是真的吗
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;
}
}
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;
}
}
广播接收机
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类
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;
}
}
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;
}
}
应用程序清单
<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>
只需检查您当前的应用程序版本就容易多了
PackageInfo packageInfo = activity.getPackageManager()
.getPackageInfo(activity.getPackageName(), 0);
int versionCode = packageInfo.versionCode;
当应用程序启动时,您可以使用版本代码检查SharedReferences中的整数值。如果没有,或者不匹配,则显示EULA。用户接受EULA后,将versionCode值写入SharedReferences
versionCode
将与您存储在清单中的版本号匹配。根据最初的方法,我已使用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
}
}
}
在你的舱单上
<receiver android:name=".YourUpgradeReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REPLACED"/>
<data android:scheme="package"/>
</intent-filter>
</receiver>
检测应用程序是否已更新
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();
这里有一个简单的方法可以解决你的问题。 在您的代码中,您可以轻松获得应用程序版本代码和版本名称。在注册GCM后的首次安装中,将版本名保存在SharedReferences中。在家庭活动中,您可以选中isAppUpdated()。如果当前应用程序版本名称与存储的版本名称不匹配,则重新注册GCM ID 以下是示例代码: 在首选项中保存版本名:
public static void saveVersionNameAndCode(Context context){
try{
PackageInfo packageInfo = context.getPackageManager()
.getPackageInfo(context.getPackageName(), 0);
int versionCode = packageInfo.versionCode;
String versionName=packageInfo.versionName;
CommonTasks.showLog("Saving APP VersionCode and Version Name");
// SAVE YOUR DATA
}catch(Exception e){
}
}
public static boolean isAppUpdated(Context context){
boolean result=false;
try{
PackageInfo packageInfo = context.getPackageManager()
.getPackageInfo(context.getPackageName(), 0);
int versionCode = packageInfo.versionCode;
String versionName=packageInfo.versionName;
String prevVersionName= GET STORED VERSION_NAME;
if(prevVersionName!=null && !prevVersionName.equals("") &&
!prevVersionName.equals(versionName)){
showLog("App Updated");
result=true;
}else{
showLog("App Not updated");
}
}catch(Exception e){
}
return result;
}
检查应用程序是否升级:
public static void saveVersionNameAndCode(Context context){
try{
PackageInfo packageInfo = context.getPackageManager()
.getPackageInfo(context.getPackageName(), 0);
int versionCode = packageInfo.versionCode;
String versionName=packageInfo.versionName;
CommonTasks.showLog("Saving APP VersionCode and Version Name");
// SAVE YOUR DATA
}catch(Exception e){
}
}
public static boolean isAppUpdated(Context context){
boolean result=false;
try{
PackageInfo packageInfo = context.getPackageManager()
.getPackageInfo(context.getPackageName(), 0);
int versionCode = packageInfo.versionCode;
String versionName=packageInfo.versionName;
String prevVersionName= GET STORED VERSION_NAME;
if(prevVersionName!=null && !prevVersionName.equals("") &&
!prevVersionName.equals(versionName)){
showLog("App Updated");
result=true;
}else{
showLog("App Not updated");
}
}catch(Exception e){
}
return result;
}
这里,如果isAppUpdated()返回true,则意味着您必须重新注册GCM ID。请勿使用应用程序版本本身,因为应用程序可以在不更改EULA的情况下进行更新。 为EULA本身提供具有特定版本的资源。可以是字符串资源“eula_版本”。随着EULA的每次更改,您都会为应用程序的更新更新该字符串。创建活动后,请对照SharedReferences中的字符串检查资源中的字符串。简单的方法只是检查null或notequal。(唯一的缺点是,在应用程序降级或卸载/重新安装后,您会再次显示EULA)
如果你的目标是API>11,那么@Marian Klühspies的答案可能会简化。注册接收人:
<receiver
android:name=".your.receivers.package.AppUpdateReceiver">
<intent-filter>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
</intent-filter>
</receiver>
谢谢你,迈克!就在我发布这篇文章的时候,我意识到有一个更简单的方法(这是很晚的事情了,哈哈),这就是你的建议。我还检查他们是否已接受EULA,但此版本中的EULA已更改,以显示EULA。谢谢您还可以使用BuildConfig.VERSION_代码获取在应用程序的build.gradle中设置的版本代码。通过使用应用程序本身的版本代码,您将在每次更新时显示EULA,即使EULA没有更改。最好为EULA本身提供一个额外的版本代码(可能作为字符串资源“EULA_version”),并将其与上次用户单击“accept”时保存的SharedReference版本代码进行比较。事实上,在更换应用程序时,我确实有一个意图,但可能只是因为我通过eclipse安装了应用程序?哪种方法最好?您的或“EboMike”建议的?您必须为自己提出一个简单的问题:您是否需要基于事件的方法,或者在应用程序的某个特定点检查是否足够?如果您想在应用程序更新时立即获得这些信息,请选择我的解决方案(例如:后台服务)。如果在下一次应用程序启动时就知道这一点就足够了,那么采用另一种解决方案。但是你也可以用我的解决方案,写一些东西给prefs,你可以在事后检查它是否有像EboMikes方法一样的行为理论上我怎么能测试这个呢?@branchabin为了检查这个,你可以用两个版本代码为你的应用程序制作两个.APK fie。比如10和11版本代码。首先安装版本10,然后安装版本11,然后您就可以测试它了。为了清楚起见,您的广播接收器在更新后会被调用,对吗?因此,当接收器被触发时,运行的是新代码,而不是旧代码。对的这是我的假设,但我想确认一下。