web-dev-qa-db-fra.com

Détecter la mise à niveau d'une application Android et définir une classe d'application booléenne pour afficher/masquer le CLUF

J'essaie de détecter le moment où mon application a été mise à niveau à l'aide d'un BroadcastReceiver et de définir un booléen dans ma classe d'applications. Ce booléen sera utilisé avec quelques autres booléens pour déterminer si la boîte de dialogue du CLUF doit être affichée à l'utilisateur.

Je pense avoir tout configuré correctement, mais le CLUF est toujours affiché alors qu'il ne le devrait pas. En particulier lorsque l'utilisateur a déjà accepté le CLUF dans une version précédente, le CLUF n'a pas été modifié dans la version mise à niveau vers (définie manuellement par moi) et l'application est en cours de mise à niveau.

Je crois que cela ne fonctionne pas parce que mon application n'est pas en cours d'exécution. Par conséquent, la méthode isAppUpgrade () n'est pas appelée et ne définit pas l'indicateur booléen correct. Est-ce que quelqu'un peut confirmer que c'est le cas ou y a-t-il quelque chose qui cloche dans mon code?

FYI - La méthode statique EULA.show (Activité, booléen, booléen) est appelée première chose dans mon activité principale.

Voici du code

Classe d'application

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

Classe CLUF

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

Manifeste d'application

<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>
30
hooked82

Il est beaucoup plus facile de vérifier la version actuelle de votre application.

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

Lorsque votre application démarre, vous recherchez dans vos SharedPreferences une valeur entière avec le code de version. S'il n'y en a pas ou s'il ne correspond pas, affichez le CLUF. Une fois que l'utilisateur a accepté le CLUF, écrivez la valeur versionCode dans les SharedPreferences.

versionCode correspondra au numéro de version que vous stockez dans le manifeste.

57
EboMike

Selon l'approche initiale, je suis parvenu à détecter si l'application est mise à niveau à l'aide de 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
        }
    } 
}

Et dans votre manifeste

 <receiver Android:name=".YourUpgradeReceiver">
            <intent-filter>
                <action Android:name="Android.intent.action.PACKAGE_REPLACED"/>
                <data Android:scheme="package"/>
            </intent-filter>
 </receiver>
23

Détecter si l'application a été mise à jour

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();
6
shahrukhamd

N'utilisez pas la version de l'application elle-même, car elle pourrait être mise à jour sans modification du CLUF. Fournissez une ressource avec une version spécifique du CLUF lui-même. Pourrait être une ressource de chaîne "eula_version". À chaque changement de CLUF, vous mettez à jour cette chaîne pour la mise à jour de votre application. Lors de la création de votre activité, vous vérifiez la chaîne dans les ressources par rapport à la chaîne dans les références partagées. L'approche simple consiste uniquement à vérifier par rapport à null ou non égal. (Le seul inconvénient que vous voudriez afficher à nouveau CLUF après la rétrogradation, la désinstallation ou la réinstallation d'une application).

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);
}
0
FrankKrumnow

Voici un moyen simple qui peut résoudre votre problème. Dans votre code, vous pouvez facilement obtenir les codes versionCode et versionName de l'application. Lors de la première installation après l’enregistrement, GCM enregistre le nom de version dans sharedPreferences. Dans votre activité à domicile, cochez isAppUpdated (). si APP actuel VERSION_NAME ne correspond pas à VERSION_NAME stocké, réenregistrez l'ID GCM.

Voici un exemple de code:

Enregistrer le nom de version dans les préférences:

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

Check App est mis à jour:

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

ici, si isAppUpdated () return true signifie que vous devez ré-enregistrer GCM ID.

0
Md. Sajedul Karim

Si vous ciblez une API> 11, la solution de @Marian Klühspies pourrait être simplifiée. Enregistrement du destinataire:

<receiver
    Android:name=".your.receivers.package.AppUpdateReceiver">
    <intent-filter>
        <action Android:name="Android.intent.action.MY_PACKAGE_REPLACED" />
    </intent-filter>
</receiver>

Et le récepteur lui-même:

class AppUpdateReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        if (intent.action == Intent.ACTION_MY_PACKAGE_REPLACED) {
            onAppUpdated()
        }
    }
}
0
a.ch.