Обнаруживать обновление приложения Android и установить класс приложения boolean для отображения/скрытия EULA
Я пытаюсь обнаружить, когда мое приложение было обновлено с помощью BroadcastReceiver и установить логическое значение в моем классе приложений. Это логическое значение будет использоваться в сочетании с несколькими другими логическими параметрами, чтобы определить, показывать или нет диалоговое окно EULA для пользователя.
Я верю, что у меня все правильно настроено, но EULA все еще появляется, когда этого не должно быть. В частности, когда пользователь уже принял EULA в предыдущей версии, EULA не изменилось в обновляемой версии до (в ручном порядке меня), и приложение обновляется.
Я считаю, что причина этого не работает, потому что мое приложение не работает, поэтому метод isAppUpgrade() не вызывается и не устанавливает правильный логический флаг. Может ли кто-нибудь подтвердить, что это так, или что-то не так в моем коде?
FYI - Статический метод EULA.show(Activity, boolean, boolean) вызывается первым в моей основной деятельности.
Здесь некоторый код
Класс приложения
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;
}
}
BroadcastReceiver
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 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>
Ответы
Ответ 1
Намного проще проверить текущую версию приложения.
PackageInfo packageInfo = activity.getPackageManager()
.getPackageInfo(activity.getPackageName(), 0);
int versionCode = packageInfo.versionCode;
Когда ваше приложение запустится, вы проверите свои SharedPreferences для целочисленного значения с кодом версии. Если их нет, или если они не совпадают, отобразите EULA. После того как пользователь примет EULA, напишите значение VersionCode в SharedPreferences.
versionCode
будет соответствовать номеру версии, который вы храните в манифесте.
Ответ 2
В соответствии с первоначальным подходом мне удалось определить, обновляется ли приложение, используя BroadcastReceiver
public 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>
Ответ 3
Обнаруживать, если приложение обновлено
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();
Ответ 4
Вот простой способ решения вашей проблемы.
В вашем коде вы можете легко получить версию versionCode и versionName. В первой установке после регистрации GCM сохранить versionName в sharedPreferences. В своей домашней деятельности вы проверяете isAppUpdated(). если текущий APP VERSION_NAME не сопоставляется с сохраненным VERSION_NAME, то перерегистрируйте идентификатор GCM.
Вот пример кода:
Сохранить имя_пользователя в настройках:
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() return true означает, что вам нужно перерегистрировать GCM ID.
Ответ 5
Не используйте саму версию приложения, так как приложение может быть обновлено без изменения лицензионного соглашения. Предоставьте ресурс, имеющий определенную версию для самого лицензионного соглашения. Может быть строковым ресурсом "eula_version". С каждым изменением в EULA вы обновляете эту строку для обновления вашего приложения. При создании своей деятельности вы проверяете строку в ресурсах по отношению к строке в SharedPreferences. Простой подход состоит только в проверке на ноль или не равно. (Единственный недостаток, который вы могли бы отобразить EULA снова после понижения приложения или деинсталляции/переустановки).
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"); //save on accept EULA Dialog click
String eulaActive = getString(R.string.eula_version)
return eulaPref==null || !eulaPref.equals(eulaActive);
}
Ответ 6
Если вы нацеливаетесь на 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>
И сам приемник:
class AppUpdateReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action == Intent.ACTION_MY_PACKAGE_REPLACED) {
onAppUpdated()
}
}
}