Déterminer si l'application Android est utilisée pour la première fois
112
Je développe actuellement une application Android. J'ai besoin de faire quelque chose lorsque l'application est lancée pour la première fois, c'est-à-dire que le code ne s'exécute qu'au premier lancement du programme.
Quand j'ai commencé à créer des applications, je ne pensais qu'à la première exécution après l'installation d'une application. J'ai réalisé plus tard que je devais également gérer et différencier les premières exécutions après les mises à niveau. La réponse de @ schnatterer ci-dessous et ma réponse ici montrent comment faire cela. Méfiez-vous des réponses qui ne tiennent pas compte des mises à niveau.
Suragch
@Suragch vous agissez comme si c'était une mauvaise pratique de ne pas prendre en compte les mises à niveau, mais dans certains cas, comme avoir une introduction d'application, vous ne voulez PAS le faire :)
creativecreatorormaybenot
@creativecreatorormaybenot, c'est vrai. Il y a des moments où vous ne vous souciez que de l'installation initiale et non des mises à niveau ultérieures. Un simple booléen suffit pour ces situations. Cependant, que se passe-t-il si à un moment donné dans le futur vous souhaitez ajouter une introduction différente pour les utilisateurs actuels sur toutes les nouvelles fonctionnalités que vous venez d'ajouter dans la dernière mise à jour? À mon avis, il est plus clairvoyant de vérifier le numéro de version plutôt qu'un booléen. Cela vous donne au moins la possibilité à l'avenir de répondre d'une manière pour une nouvelle installation et d'une autre manière pour une mise à niveau.
Suragch le
1
Ensuite, vous l'ajoutez simplement pour cette version mais je reçois yoz
Une autre idée consiste à utiliser un paramètre dans les préférences partagées. Même idée générale que de rechercher un fichier vide, mais vous n'avez pas de fichier vide flottant, n'étant pas utilisé pour stocker quoi que ce soit
attention, ce genre d'approche ne pourrait pas fonctionner sur un Samsung Galaxy S avec Android Froyo. C'est à cause d'un bogue dans l'enregistrement de SharedPreferences. Voici un lien vers une question SO à ce sujet: stackoverflow.com/questions/7296163/… et voici le ticket sur google code: code.google.com/p/android/issues/detail?id=14359
Francesco Rigoni
4
Attention pour Android 6.0 (API 23 - Marshmallow) ou supérieur, la sauvegarde automatique ( developer.android.com/guide/topics/data/autobackup.html) est activée par défaut. Si les utilisateurs désinstalle puis réinstalle l'application, les préférences partagées seront récupérées. Ainsi, lors des réinstallations, vous ne pouvez pas vérifier s'il est en cours d'exécution pour la première fois après la réinstallation si cela pose un problème.
Alan
1
@Alan vous avez raison, cette réponse n'est plus valable depuis Android Marshmallow.
Ioane Sharvadze
1
@Alan vous ne pouvez pas imaginer combien de temps je cherchais une réponse comme la vôtre. Tu as fait ma journée. Merci!
Antonio
@Alan Mais la sauvegarde automatique enregistre également la plupart des autres données. On s'attend donc à ce que l'application réinstallée soit dans un état de non-première exécution. Et l'utilisateur a déjà utilisé l'application auparavant, il n'y a donc pas besoin de conseils. Je dirais donc que dans la plupart des cas, c'est une bonne chose que cela se produise.
smdufb
112
Vous pouvez utiliser les SharedPreferences pour identifier si c'est la «première fois» que l'application est lancée. Utilisez simplement une variable booléenne ("my_first_time") et changez sa valeur en false lorsque votre tâche pour la "première fois" est terminée.
Voici mon code pour attraper la première fois que vous ouvrez l'application:
finalString PREFS_NAME ="MyPrefsFile";SharedPreferences settings = getSharedPreferences(PREFS_NAME,0);if(settings.getBoolean("my_first_time",true)){//the app is being launched for first time, do something Log.d("Comments","First time");// first time task// record the fact that the app has been started at least once
settings.edit().putBoolean("my_first_time",false).commit();}
Sera-t-il géré lorsque l'application sera mise à jour vers la prochaine version sur le Google Play Store?
Shajeel Afzal
4
Les préférences partagées sont conservées pendant la mise à niveau. Donc, je suppose que lors de sa mise à niveau à partir de PlayStore, l'ancienne valeur est disponible. En fait, il est applicable pour d'autres méthodes, c'est-à-dire vérifier l'existence d'un fichier aussi. Ainsi, la méthode de raccourci dans ce cas consiste à utiliser une préférence / un nom de fichier ou une valeur différents.
Tejasvi Hegde
@ShajeelAfzal quelque chose comme ça peut vous aider public void CheckAndInitAppFirstTime () {final String PREFS_NAME = "TheAppVer"; chaîne finale CHECK_VERSION = "1"; // Requis ver ... final String KEY_NAME = "CheckVersion"; Paramètres SharedPreferences = getSharedPreferences (PREFS_NAME, 0); if (! settings.getString (KEY_NAME, "0"). equals (CHECK_VERSION)) {// l'application est lancée pour la première fois, faites quelque chose ou CHECK_VERSION est différent // ... settings.edit (). putString ( KEY_NAME, CHECK_VERSION) .commit (); }}
Tejasvi Hegde
@aman verma: selon la description getBoolean sur developer.android.com/reference/android/content/… Le deuxième paramètre de getBoolean est la valeur par défaut si le premier paramètre ne se ferme pas, donc si "my_first_time" n'a pas été défini l'expression par défaut est true.
user2798692
63
Je suggère de stocker non seulement un drapeau booléen, mais le code de version complet. De cette façon, vous pouvez également demander au début s'il s'agit du premier démarrage d'une nouvelle version. Vous pouvez utiliser ces informations pour afficher une boîte de dialogue "Quoi de neuf", par exemple.
Le code suivant doit fonctionner à partir de n'importe quelle classe Android qui "est un contexte" (activités, services, ...). Si vous préférez l'avoir dans une classe distincte (POJO), vous pouvez envisager d'utiliser un "contexte statique", comme décrit ici par exemple.
/**
* Distinguishes different kinds of app starts: <li>
* <ul>
* First start ever ({@link #FIRST_TIME})
* </ul>
* <ul>
* First start in this version ({@link #FIRST_TIME_VERSION})
* </ul>
* <ul>
* Normal app start ({@link #NORMAL})
* </ul>
*
* @author schnatterer
*
*/publicenumAppStart{
FIRST_TIME, FIRST_TIME_VERSION, NORMAL;}/**
* The app version code (not the version name!) that was used on the last
* start of the app.
*/privatestaticfinalString LAST_APP_VERSION ="last_app_version";/**
* Finds out started for the first time (ever or in the current version).<br/>
* <br/>
* Note: This method is <b>not idempotent</b> only the first call will
* determine the proper result. Any subsequent calls will only return
* {@link AppStart#NORMAL} until the app is started again. So you might want
* to consider caching the result!
*
* @return the type of app start
*/publicAppStart checkAppStart(){PackageInfo pInfo;SharedPreferences sharedPreferences =PreferenceManager.getDefaultSharedPreferences(this);AppStart appStart =AppStart.NORMAL;try{
pInfo = getPackageManager().getPackageInfo(getPackageName(),0);int lastVersionCode = sharedPreferences
.getInt(LAST_APP_VERSION,-1);int currentVersionCode = pInfo.versionCode;
appStart = checkAppStart(currentVersionCode, lastVersionCode);// Update version in preferences
sharedPreferences.edit().putInt(LAST_APP_VERSION, currentVersionCode).commit();}catch(NameNotFoundException e){Log.w(Constants.LOG,"Unable to determine current app version from pacakge manager. Defenisvely assuming normal app start.");}return appStart;}publicAppStart checkAppStart(int currentVersionCode,int lastVersionCode){if(lastVersionCode ==-1){returnAppStart.FIRST_TIME;}elseif(lastVersionCode < currentVersionCode){returnAppStart.FIRST_TIME_VERSION;}elseif(lastVersionCode > currentVersionCode){Log.w(Constants.LOG,"Current version code ("+ currentVersionCode
+") is less then the one recognized on last startup ("+ lastVersionCode
+"). Defenisvely assuming normal app start.");returnAppStart.NORMAL;}else{returnAppStart.NORMAL;}}
Il pourrait être utilisé à partir d'une activité comme celle-ci:
publicclassMainActivityextendsActivity{@Overrideprotectedvoid onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);switch(checkAppStart()){case NORMAL:// We don't want to get on the user's nervesbreak;case FIRST_TIME_VERSION:// TODO show what's newbreak;case FIRST_TIME:// TODO show a tutorialbreak;default:break;}// ...}// ...}
La logique de base peut être vérifiée à l'aide de ce test JUnit:
publicvoid testCheckAppStart(){// First startint oldVersion =-1;int newVersion =1;
assertEquals("Unexpected result",AppStart.FIRST_TIME,
service.checkAppStart(newVersion, oldVersion));// First start this version
oldVersion =1;
newVersion =2;
assertEquals("Unexpected result",AppStart.FIRST_TIME_VERSION,
service.checkAppStart(newVersion, oldVersion));// Normal start
oldVersion =2;
newVersion =2;
assertEquals("Unexpected result",AppStart.NORMAL,
service.checkAppStart(newVersion, oldVersion));}
Avec un peu plus d'effort, vous pourrez probablement tester également les éléments liés à Android (PackageManager et SharedPreferences). Quelqu'un intéressé à écrire le test? :)
Notez que le code ci-dessus ne fonctionnera correctement que si vous ne android:versionCodeplaisantez pas avec votre dans AndroidManifest.xml!
Veuillez expliquer comment utiliser cette méthode. Où vous initialisez l'objet SharedPreferences?
Shajeel Afzal
1
ne fonctionne pas pour moi - il lance toujours mon premier tutoriel
pzo
1
ce code est beaucoup plus simple sans les effets secondaires de la déclaration du contexte et des préférences ailleurs public AppStart checkAppStart(Context context, SharedPreferences sharedPreferences)est une bien meilleure signature de méthode
Will
2
Faites une mise à jour de cette réponse ici gist.github.com/williscool/2a57bcd47a206e980eee J'ai eu un problème avec le code original où il restait bloqué dans ma boucle de visite virtuelle pour toujours car le numéro de version n'était jamais recalculé dans le premier checkAppStartbloc. J'ai donc décidé de partager mon code mis à jour et de voir si quelqu'un a des suggestions à ce sujet
Will
1
@Will merci pour votre contribution. Vous avez raison, le code pourrait être simplifié et rendu plus robuste. Lorsque j'ai publié la réponse pour la première fois, j'ai extrait le code d' un scénario plus complexe , auquel je voulais accéder à AppStartpartir de différentes activités. J'ai donc mis la logique dans une méthode de service distincte. C'est pourquoi il y avait une contextvariable et AppStartétait stockée dans une variable statique pour faciliter les appels de méthode idempotente.
schnatterer
4
J'ai résolu de déterminer si l'application est votre première fois ou non, selon qu'il s'agit d'une mise à jour.
privateint appGetFirstTimeRun(){//Check if App Start First TimeSharedPreferences appPreferences = getSharedPreferences("MyAPP",0);int appCurrentBuildVersion =BuildConfig.VERSION_CODE;int appLastBuildVersion = appPreferences.getInt("app_first_time",0);//Log.d("appPreferences", "app_first_time = " + appLastBuildVersion);if(appLastBuildVersion == appCurrentBuildVersion ){return1;//ya has iniciado la appp alguna vez}else{
appPreferences.edit().putInt("app_first_time",
appCurrentBuildVersion).apply();if(appLastBuildVersion ==0){return0;//es la primera vez}else{return2;//es una versión nueva}}}
Calculer les résultats:
0: si c'est la première fois.
1: Cela n'a jamais commencé.
2: Il a démarré une fois, mais pas cette version, c'est à dire qu'il s'agit d'une mise à jour.
if(sharedPreferenceObj.getApp_runFirst().equals("FIRST")){// That's mean First Time Launch// After your Work , SET Status NO
sharedPreferenceObj.setApp_runFirst("NO");}else{// App is not First Time Launch}
Je pensais faire ça mais je pensais qu'il devait y avoir une meilleure façon
Boardy
Je n'en connais pas, mais quel est le manque de ressources que vous recevez par là? 4 octets pour le fichier et un "si" au début. Les routines système feraient la même chose, elles feraient exactement la même chose ou
créeraient
De la même manière, vous pouvez utiliser des préférences partagées qui, si elles n'existent pas, afficheront un écran de démarrage, etc. Voir la réponse de Kevin ci
Stealthcopter
1
J'ai fait une classe simple pour vérifier si votre code s'exécute pour la première fois / n fois!
Utilisez runTheFirstNTimes, choisissez une clé et combien de fois exécuter
if(prefFirstTime.runTheFirstNTimes("anotherKey",5)){Toast.makeText(this,"ciccia Test coutdown: "+ prefFirstTime.getCountDown("anotherKey"),Toast.LENGTH_LONG).show();}
Utilisez getCountDown () pour mieux gérer votre code
L'ordre de ces appels doit être inversé, une fois AppLaunchChecker.onActivityCreate () appelé, AppLaunchChecker.hasStartedFromLauncher () retournera true.
Gary Kipnis
C'est assez trompeur. Il ne dit pas si l'application est "jamais lancée"; il indique plutôt si l'application "a déjà été lancée par un utilisateur depuis le lanceur". Il est donc possible que d'autres applications ou liens profonds aient déjà lancé l'application.
Farid
1
Si vous cherchez un moyen simple, le voici.
Créez une classe utilitaire comme celle-ci,
publicclassApplicationUtils{/**
* Sets the boolean preference value
*
* @param context the current context
* @param key the preference key
* @param value the value to be set
*/publicstaticvoid setBooleanPreferenceValue(Context context,String key,booleanvalue){SharedPreferences sp =PreferenceManager.getDefaultSharedPreferences(context);
sp.edit().putBoolean(key,value).apply();}/**
* Get the boolean preference value from the SharedPreference
*
* @param context the current context
* @param key the preference key
* @return the the preference value
*/publicstaticboolean getBooleanPreferenceValue(Context context,String key){SharedPreferences sp =PreferenceManager.getDefaultSharedPreferences(context);return sp.getBoolean(key,false);}}
Dans votre activité principale, onCreate ()
if(!ApplicationUtils.getBooleanPreferenceValue(this,"isFirstTimeExecution")){Log.d(TAG,"First time Execution");ApplicationUtils.setBooleanPreferenceValue(this,"isFirstTimeExecution",true);// do your first time execution stuff here,}
fun checkFirstRun(){var prefs_name ="MyPrefsFile"var pref_version_code_key ="version_code"var doesnt_exist:Int=-1;// Get current version codevar currentVersionCode =BuildConfig.VERSION_CODE
// Get saved version codevar prefs:SharedPreferences= getSharedPreferences(prefs_name, MODE_PRIVATE)var savedVersionCode:Int= prefs.getInt(pref_version_code_key, doesnt_exist)// Check for first run or upgradeif(currentVersionCode == savedVersionCode){// This is just a normal runreturn;}elseif(savedVersionCode == doesnt_exist){// TODO This is a new install (or the user cleared the shared preferences)}elseif(currentVersionCode > savedVersionCode){// TODO This is an upgrade}// Update the shared preferences with the current version code
prefs.edit().putInt(pref_version_code_key, currentVersionCode).apply();}
Pourquoi ne pas utiliser l'Assistant de base de données? Cela aura un joli onCreate qui n'est appelé que la première fois que l'application est démarrée. Cela aidera les personnes qui souhaitent suivre cela après l'installation de l'application initiale sans suivi.
Cela crée-t-il une base de données? Comment utiliser DatabaseHelper sans créer une base de données réelle? Et je pense, onCreate()est appelé pour chaque nouvelle version. Aussi, ne serait-il pas considéré comme superflu ou utiliser quelque chose à des fins non intentionnelles?
ADTC
onCreate n'est déclenché que lorsque l'application est installée pour la première fois. Lorsque la version de la base de données est incrémentée, onUpdated est déclenché.
slott
Eh bien superflu est un mot si dur :) - Si vous avez l'option ie. votre application n'est pas encore en ligne, configurez un indicateur SharedPrefs et utilisez-le pour déterminer s'il s'agit du premier démarrage ou non. J'ai eu un cas où l'application était dans la nature depuis un certain temps et nous utilisions une base de données, donc onCreate était un match parfait pour moi.
slott
0
J'aime avoir un "nombre de mises à jour" dans mes préférences partagées. Si ce n'est pas là (ou valeur zéro par défaut), il s'agit de la "première utilisation" de mon application.
privatestaticfinalint UPDATE_COUNT =1;// Increment this on major change...if(sp.getInt("updateCount",0)==0){// first use}elseif(sp.getInt("updateCount",0)< UPDATE_COUNT){// Pop up dialog telling user about new features}...
sp.edit().putInt("updateCount", UPDATE_COUNT);
Alors maintenant, chaque fois qu'il y a une mise à jour de l'application que les utilisateurs devraient connaître, j'incrémente UPDATE_COUNT
Salut les gars, je fais quelque chose comme ça. Et ça marche pour moi
créer un champ booléen dans la préférence partagée. La valeur par défaut est true {isFirstTime: true} après la première fois, définissez-la sur false. Rien ne peut être simple et fiable que cela dans le système Android.
Euh, ne codez pas le chemin comme ça! Si vous le faites simplement, Context.getSharedPreferences()cela se retrouvera au même endroit, sauf que cela fonctionnera partout
Réponses:
Une autre idée consiste à utiliser un paramètre dans les préférences partagées. Même idée générale que de rechercher un fichier vide, mais vous n'avez pas de fichier vide flottant, n'étant pas utilisé pour stocker quoi que ce soit
la source
Vous pouvez utiliser les SharedPreferences pour identifier si c'est la «première fois» que l'application est lancée. Utilisez simplement une variable booléenne ("my_first_time") et changez sa valeur en false lorsque votre tâche pour la "première fois" est terminée.
Voici mon code pour attraper la première fois que vous ouvrez l'application:
la source
Je suggère de stocker non seulement un drapeau booléen, mais le code de version complet. De cette façon, vous pouvez également demander au début s'il s'agit du premier démarrage d'une nouvelle version. Vous pouvez utiliser ces informations pour afficher une boîte de dialogue "Quoi de neuf", par exemple.
Le code suivant doit fonctionner à partir de n'importe quelle classe Android qui "est un contexte" (activités, services, ...). Si vous préférez l'avoir dans une classe distincte (POJO), vous pouvez envisager d'utiliser un "contexte statique", comme décrit ici par exemple.
Il pourrait être utilisé à partir d'une activité comme celle-ci:
La logique de base peut être vérifiée à l'aide de ce test JUnit:
Avec un peu plus d'effort, vous pourrez probablement tester également les éléments liés à Android (PackageManager et SharedPreferences). Quelqu'un intéressé à écrire le test? :)
Notez que le code ci-dessus ne fonctionnera correctement que si vous ne
android:versionCode
plaisantez pas avec votre dans AndroidManifest.xml!la source
public AppStart checkAppStart(Context context, SharedPreferences sharedPreferences)
est une bien meilleure signature de méthodecheckAppStart
bloc. J'ai donc décidé de partager mon code mis à jour et de voir si quelqu'un a des suggestions à ce sujetAppStart
partir de différentes activités. J'ai donc mis la logique dans une méthode de service distincte. C'est pourquoi il y avait unecontext
variable etAppStart
était stockée dans une variable statique pour faciliter les appels de méthode idempotente.J'ai résolu de déterminer si l'application est votre première fois ou non, selon qu'il s'agit d'une mise à jour.
Calculer les résultats:
la source
Vous pouvez utiliser Android SharedPreferences .
CODE
Créer une classe personnalisée SharedPreference
Ouvrez maintenant votre activité et initialisez .
Appelez maintenant ceci dans la section OnCreate
Vérification en cours
la source
Voici un code pour cela -
la source
Vous pouvez simplement vérifier l'existence d'un fichier vide, s'il n'existe pas, puis exécuter votre code et créer le fichier.
par exemple
la source
J'ai fait une classe simple pour vérifier si votre code s'exécute pour la première fois / n fois!
Exemple
Créez des préférences uniques
Utilisez runTheFirstTime, choisissez une clé pour vérifier votre événement
Utilisez runTheFirstNTimes, choisissez une clé et combien de fois exécuter
FirstTimePreference.java
la source
Il y a un support pour cela dans la révision 23.3.0 de la bibliothèque de support (dans la v4, ce qui signifie la compatibilité avec Android 1.6).
Dans votre activité Launcher, appelez d'abord:
Puis appelez:
Ce qui reviendra si c'était la première fois que l'application était lancée.
la source
Si vous cherchez un moyen simple, le voici.
Créez une classe utilitaire comme celle-ci,
Dans votre activité principale, onCreate ()
la source
pour kotlin
la source
Pourquoi ne pas utiliser l'Assistant de base de données? Cela aura un joli onCreate qui n'est appelé que la première fois que l'application est démarrée. Cela aidera les personnes qui souhaitent suivre cela après l'installation de l'application initiale sans suivi.
la source
onCreate()
est appelé pour chaque nouvelle version. Aussi, ne serait-il pas considéré comme superflu ou utiliser quelque chose à des fins non intentionnelles?J'aime avoir un "nombre de mises à jour" dans mes préférences partagées. Si ce n'est pas là (ou valeur zéro par défaut), il s'agit de la "première utilisation" de mon application.
Alors maintenant, chaque fois qu'il y a une mise à jour de l'application que les utilisateurs devraient connaître, j'incrémente UPDATE_COUNT
la source
la source
Salut les gars, je fais quelque chose comme ça. Et ça marche pour moi
créer un champ booléen dans la préférence partagée. La valeur par défaut est true {isFirstTime: true} après la première fois, définissez-la sur false. Rien ne peut être simple et fiable que cela dans le système Android.
la source
Context.getSharedPreferences()
cela se retrouvera au même endroit, sauf que cela fonctionnera partout