Stellen Sie fest, ob die Android-App zum ersten Mal verwendet wird
112
Ich entwickle gerade eine Android App. Ich muss etwas tun, wenn die App zum ersten Mal gestartet wird, dh der Code wird nur beim ersten Start des Programms ausgeführt.
Als ich anfing, Apps zu erstellen, dachte ich erst an den ersten Lauf nach der Installation einer App. Später wurde mir klar, dass ich auch erste Läufe nach Upgrades handhaben und differenzieren musste. Die Antwort von @ schnatterer unten und meine Antwort hier zeigen, wie das geht. Seien Sie vorsichtig bei Antworten, bei denen Upgrades nicht berücksichtigt werden.
Suragch
@ Suragch Sie verhalten sich so, als wäre es eine schlechte Praxis, Upgrades nicht zu berücksichtigen, aber in einigen Fällen möchten Sie es nicht tun, wenn Sie eine App-Einführung haben :)
creativecreatorormaybenot
@creativecreatorormaybenot, das stimmt. Es gibt Zeiten, in denen Sie sich nur um die Erstinstallation und nicht um nachfolgende Upgrades kümmern. Ein einfacher Boolescher Wert reicht für diese Situationen aus. Was ist jedoch, wenn Sie zu einem späteren Zeitpunkt eine andere Einführung für aktuelle Benutzer zu allen neuen Funktionen hinzufügen möchten, die Sie gerade im letzten Update hinzugefügt haben? Meiner Meinung nach ist es weitsichtiger, die Versionsnummer zu überprüfen, als einen Booleschen Wert. Dies gibt Ihnen zumindest in Zukunft die Möglichkeit, auf eine Weise auf eine Neuinstallation und auf eine andere Weise auf ein Upgrade zu reagieren.
Suragch
1
Dann fügst du es einfach für diese Version hinzu, aber ich bekomme yoz
Eine andere Idee ist, eine Einstellung in den freigegebenen Einstellungen zu verwenden. Dieselbe allgemeine Idee wie das Suchen nach einer leeren Datei, aber dann schwebt keine leere Datei herum und wird nicht zum Speichern verwendet
Beachten Sie, dass die automatische Sicherung für Android 6.0 (API 23 - Marshmallow) oder höher ( developer.android.com/guide/topics/data/autobackup.html) standardmäßig aktiviert ist. Wenn die Benutzer die App deinstallieren und anschließend neu installieren, werden die freigegebenen Einstellungen wiederhergestellt. Bei Neuinstallationen können Sie daher nicht überprüfen, ob es nach der Neuinstallation zum ersten Mal ausgeführt wird, wenn dies von Belang ist.
Alan
1
@ Alan du hast recht, diese Antwort ist von Android Marshmallow nicht mehr gültig .
Ioane Sharvadze
1
@ Alan, du kannst dir nicht vorstellen, wie lange ich nach einer Antwort wie deiner gesucht habe. Du hast meinen Tag gerettet. Vielen Dank!
Antonio
@ Alan Aber die automatische Sicherung speichert auch die meisten anderen Daten. Daher wird erwartet, dass sich die neu installierte App in einem Zustand befindet, in dem sie nicht zum ersten Mal ausgeführt wird. Und der Benutzer hat die App bereits zuvor verwendet, sodass keine Anleitung erforderlich ist. Daher würde ich in den meisten Fällen argumentieren, dass dies gut ist.
smdufb
112
Mithilfe der SharedPreferences können Sie feststellen , ob die App zum ersten Mal gestartet wird. Verwenden Sie einfach eine boolesche Variable ("my_first_time") und ändern Sie ihren Wert in false wenn Ihre Aufgabe zum "ersten Mal" beendet ist.
Dies ist mein Code, um beim ersten Öffnen der App abzufangen:
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();}
Wird es funktionieren, wenn die App im Google Play Store auf die nächste Version aktualisiert wird?
Shajeel Afzal
4
SharedPreferences werden während des Upgrades beibehalten. Ich gehe also davon aus, dass beim Upgrade von PlayStore ein alter Wert verfügbar ist. Tatsächlich ist es auch für andere Methoden anwendbar, z. B. um die Existenz einer Datei zu überprüfen. In diesem Fall besteht die Verknüpfungsmethode darin, unterschiedliche Einstellungen / Dateinamen oder Werte zu verwenden.
Tejasvi Hegde
@ShajeelAfzal so etwas kann dir helfen, CheckAndInitAppFirstTime () {void String PREFS_NAME = "TheAppVer"; final String CHECK_VERSION = "1"; // Erforderliche Version ... final String KEY_NAME = "CheckVersion"; SharedPreferences settings = getSharedPreferences (PREFS_NAME, 0); Wenn (! settings.getString (KEY_NAME, "0"). equals (CHECK_VERSION)) {// die App zum ersten Mal gestartet wird, etwas tun oder CHECK_VERSION anders ist // ... settings.edit (). putString () KEY_NAME, CHECK_VERSION) .commit (); }}
Tejasvi Hegde
@aman verma: gemäß der getBoolean-Beschreibung unter developer.android.com/reference/android/content/… Der zweite Parameter von getBoolean ist der Standardwert, wenn der erste Parameter nicht beendet wird. Wenn also "my_first_time" nicht festgelegt wurde Der Ausdruck ist standardmäßig true.
user2798692
62
Ich schlage vor, nicht nur ein boolesches Flag, sondern den vollständigen Versionscode zu speichern. Auf diese Weise können Sie auch zu Beginn abfragen, ob dies der erste Start in einer neuen Version ist. Mit diesen Informationen können Sie beispielsweise ein Dialogfeld "Was ist neu" anzeigen.
Der folgende Code sollte von jeder Android-Klasse funktionieren, die "ein Kontext" ist (Aktivitäten, Dienste, ...). Wenn Sie es lieber in einer separaten Klasse (POJO) haben möchten, können Sie einen "statischen Kontext" verwenden, wie hier beispielsweise beschrieben.
/**
* 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;}}
Es könnte aus einer Aktivität wie dieser verwendet werden:
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;}// ...}// ...}
Die grundlegende Logik kann mit diesem JUnit-Test überprüft werden:
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));}
Mit etwas mehr Aufwand könnten Sie wahrscheinlich auch die Android-bezogenen Inhalte (PackageManager und SharedPreferences) testen. Hat jemand Interesse daran, den Test zu schreiben? :) :)
Beachten Sie, dass der obige Code nur dann ordnungsgemäß funktioniert, wenn Sie nicht mit Ihrem android:versionCodein AndroidManifest.xml herumspielen!
Bitte erläutern Sie die Verwendung dieser Methode. Wo initialisieren Sie das SharedPreferences-Objekt?
Shajeel Afzal
1
funktioniert bei mir nicht - es startet immer mein erstes Tutorial
pzo
1
Dieser Code ist viel einfacher, ohne die Nebenwirkungen der Deklaration des Kontexts und der Präferenzen an anderer Stelle public AppStart checkAppStart(Context context, SharedPreferences sharedPreferences)ist eine viel bessere Methodensignatur
Will
2
Diese Antwort wurde hier aktualisiert. Gist.github.com/williscool/2a57bcd47a206e980eee Ich hatte ein Problem mit dem ursprünglichen Code, bei dem er für immer in meiner exemplarischen Schleife stecken blieb, da die Versionsnummer im ersten checkAppStartBlock nie neu berechnet wurde . Also habe ich beschlossen, meinen aktualisierten Code zu teilen und zu sehen, ob jemand Vorschläge dazu hat
Will
1
@Will danke für deine Eingabe. Sie haben Recht, der Code könnte vereinfacht und robuster gemacht werden. Als ich die Antwort zum ersten Mal veröffentlichte, extrahierte ich den Code aus einem komplexeren Szenario , auf das ich AppStartvon verschiedenen Aktivitäten aus zugreifen wollte . Also habe ich die Logik in eine separate Servicemethode eingefügt. Aus diesem Grund gab es eine contextVariable, AppStartdie in einer statischen Variablen gespeichert wurde, um idempotente Methodenaufrufe zu ermöglichen.
Schnatterer
4
Ich habe festgestellt, ob die Anwendung Ihr erstes Mal ist oder nicht, je nachdem, ob es sich um ein Update handelt.
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}}}
Ergebnisse berechnen:
0: Wenn dies das erste Mal ist.
1: Es hat jemals begonnen.
2: Es wurde einmal gestartet, aber nicht diese Version, dh es ist ein Update.
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}
Ich dachte darüber nach, dachte aber, dass es einen besseren Weg geben muss
Boardy
Ich kenne keine, aber was ist der Mangel an Ressourcen, die Sie dadurch erhalten? 4 Bytes für die Datei und ein "if" am Anfang. Systemroutinen würden das Gleiche tun, sie würden genau das Gleiche tun oder eine Tabelle mit Anwendungen erstellen, die bereits gestartet wurden
MechMK1
In ähnlicher Weise können Sie gemeinsam genutzte Einstellungen verwenden. Wenn diese nicht vorhanden sind, zeigen Sie einen Begrüßungsbildschirm usw. an und erstellen ihn einfach, wenn das Programm zum ersten Mal ausgeführt wird (obv nach Überprüfung). Siehe Kevins Antwort oben
Stealthcopter
1
Ich habe eine einfache Klasse erstellt, um zu überprüfen, ob Ihr Code zum ersten Mal / n-mal ausgeführt wird!
Verwenden Sie runTheFirstNTimes, wählen Sie einen Schlüssel und wie oft ausgeführt
if(prefFirstTime.runTheFirstNTimes("anotherKey",5)){Toast.makeText(this,"ciccia Test coutdown: "+ prefFirstTime.getCountDown("anotherKey"),Toast.LENGTH_LONG).show();}
Verwenden Sie getCountDown (), um Ihren Code besser zu handhaben
Die Reihenfolge dieser Aufrufe muss umgekehrt werden. Sobald AppLaunchChecker.onActivityCreate () aufgerufen wurde, gibt AppLaunchChecker.hasStartedFromLauncher () true zurück.
Gary Kipnis
Das ist ziemlich irreführend. Es heißt nicht, ob die App "jemals gestartet" wurde; es heißt vielmehr, ob die App "jemals von einem Benutzer vom Launcher aus gestartet wurde". Es besteht also die Möglichkeit, dass andere Apps oder Deep-Links die App bereits gestartet haben.
Farid
1
Wenn Sie nach einem einfachen Weg suchen, hier ist er.
Erstellen Sie eine Dienstprogrammklasse wie folgt:
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);}}
Bei Ihrer Hauptaktivität ist 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();}
Warum nicht den Database Helper verwenden? Dies hat eine schöne onCreate, die nur beim ersten Start der App aufgerufen wird. Dies hilft denjenigen Personen, die dies nachverfolgen möchten, nachdem die erste App ohne Nachverfolgung installiert wurde.
Erstellt das eine Datenbank? Wie verwende ich den DatabaseHelper, ohne eine tatsächliche Datenbank zu erstellen? Und ich denke, onCreate()wird für jede neue Version aufgerufen. Wäre es nicht überflüssig, etwas für einen unbeabsichtigten Zweck zu verwenden?
ADTC
onCreate wird nur ausgelöst, wenn die App zum ersten Mal installiert wird. Wenn die Datenbankversion erhöht wird, wird onUpdated ausgelöst.
Slott
Nun überflüssig ist so ein hartes Wort :) - Wenn Sie die Option haben, dh. Ihre App ist noch nicht live. Richten Sie dann ein SharedPrefs-Flag ein und verwenden Sie dieses, um festzustellen, ob es sich um den ersten Start handelt oder nicht. Ich hatte einen Fall, in dem die App seit einiger Zeit in freier Wildbahn war und wir eine Datenbank verwendeten, sodass onCreate perfekt zu mir passte.
Slott
0
Ich möchte eine "Anzahl der Updates" in meinen gemeinsamen Einstellungen haben. Wenn es nicht vorhanden ist (oder der Standardwert Null ist), ist dies die "erste Verwendung" meiner App.
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);
Immer wenn es ein Update für die App gibt, über das Benutzer Bescheid wissen sollten, erhöhe ich UPDATE_COUNT
Hallo Leute, ich mache so etwas. Und es funktioniert für mich
Erstellen Sie ein boolesches Feld in der gemeinsamen Voreinstellung. Der Standardwert ist true {isFirstTime: true}, nachdem Sie es zum ersten Mal auf false gesetzt haben. Nichts kann einfacher und zuverlässiger sein als dies im Android-System.
Äh, codiere den Pfad nicht so fest! Wenn Sie es einfach tun Context.getSharedPreferences(), wird es am selben Ort enden, außer es wird überall funktionieren
Antworten:
Eine andere Idee ist, eine Einstellung in den freigegebenen Einstellungen zu verwenden. Dieselbe allgemeine Idee wie das Suchen nach einer leeren Datei, aber dann schwebt keine leere Datei herum und wird nicht zum Speichern verwendet
quelle
Mithilfe der SharedPreferences können Sie feststellen , ob die App zum ersten Mal gestartet wird. Verwenden Sie einfach eine boolesche Variable ("my_first_time") und ändern Sie ihren Wert in false wenn Ihre Aufgabe zum "ersten Mal" beendet ist.
Dies ist mein Code, um beim ersten Öffnen der App abzufangen:
quelle
Ich schlage vor, nicht nur ein boolesches Flag, sondern den vollständigen Versionscode zu speichern. Auf diese Weise können Sie auch zu Beginn abfragen, ob dies der erste Start in einer neuen Version ist. Mit diesen Informationen können Sie beispielsweise ein Dialogfeld "Was ist neu" anzeigen.
Der folgende Code sollte von jeder Android-Klasse funktionieren, die "ein Kontext" ist (Aktivitäten, Dienste, ...). Wenn Sie es lieber in einer separaten Klasse (POJO) haben möchten, können Sie einen "statischen Kontext" verwenden, wie hier beispielsweise beschrieben.
Es könnte aus einer Aktivität wie dieser verwendet werden:
Die grundlegende Logik kann mit diesem JUnit-Test überprüft werden:
Mit etwas mehr Aufwand könnten Sie wahrscheinlich auch die Android-bezogenen Inhalte (PackageManager und SharedPreferences) testen. Hat jemand Interesse daran, den Test zu schreiben? :) :)
Beachten Sie, dass der obige Code nur dann ordnungsgemäß funktioniert, wenn Sie nicht mit Ihrem
android:versionCode
in AndroidManifest.xml herumspielen!quelle
public AppStart checkAppStart(Context context, SharedPreferences sharedPreferences)
ist eine viel bessere MethodensignaturcheckAppStart
Block nie neu berechnet wurde . Also habe ich beschlossen, meinen aktualisierten Code zu teilen und zu sehen, ob jemand Vorschläge dazu hatAppStart
von verschiedenen Aktivitäten aus zugreifen wollte . Also habe ich die Logik in eine separate Servicemethode eingefügt. Aus diesem Grund gab es einecontext
Variable,AppStart
die in einer statischen Variablen gespeichert wurde, um idempotente Methodenaufrufe zu ermöglichen.Ich habe festgestellt, ob die Anwendung Ihr erstes Mal ist oder nicht, je nachdem, ob es sich um ein Update handelt.
Ergebnisse berechnen:
quelle
Sie können Android SharedPreferences verwenden .
CODE
Erstellen Sie eine benutzerdefinierte Klasse SharedPreference
Öffnen Sie jetzt Ihre Aktivität und initialisieren Sie sie .
Rufen Sie dies jetzt im Abschnitt OnCreate auf
Jetzt prüfen
quelle
Hier ist ein Code dafür -
quelle
Sie können einfach prüfen, ob eine leere Datei vorhanden ist. Wenn diese nicht vorhanden ist, führen Sie Ihren Code aus und erstellen Sie die Datei.
z.B
quelle
Ich habe eine einfache Klasse erstellt, um zu überprüfen, ob Ihr Code zum ersten Mal / n-mal ausgeführt wird!
Beispiel
Erstellen Sie eindeutige Einstellungen
Verwenden Sie runTheFirstTime und wählen Sie einen Schlüssel aus, um Ihr Ereignis zu überprüfen
Verwenden Sie runTheFirstNTimes, wählen Sie einen Schlüssel und wie oft ausgeführt
FirstTimePreference.java
quelle
Genau dies wird in der Support-Bibliotheksversion 23.3.0 unterstützt (in Version 4 bedeutet dies Kompatibilität zurück zu Android 1.6).
Rufen Sie in Ihrer Launcher-Aktivität zuerst Folgendes auf:
Dann ruf an:
Welches wird zurückkehren, wenn dies das erste Mal war, dass die App gestartet wurde.
quelle
Wenn Sie nach einem einfachen Weg suchen, hier ist er.
Erstellen Sie eine Dienstprogrammklasse wie folgt:
Bei Ihrer Hauptaktivität ist onCreate ()
quelle
für Kotlin
quelle
Warum nicht den Database Helper verwenden? Dies hat eine schöne onCreate, die nur beim ersten Start der App aufgerufen wird. Dies hilft denjenigen Personen, die dies nachverfolgen möchten, nachdem die erste App ohne Nachverfolgung installiert wurde.
quelle
onCreate()
wird für jede neue Version aufgerufen. Wäre es nicht überflüssig, etwas für einen unbeabsichtigten Zweck zu verwenden?Ich möchte eine "Anzahl der Updates" in meinen gemeinsamen Einstellungen haben. Wenn es nicht vorhanden ist (oder der Standardwert Null ist), ist dies die "erste Verwendung" meiner App.
Immer wenn es ein Update für die App gibt, über das Benutzer Bescheid wissen sollten, erhöhe ich UPDATE_COUNT
quelle
quelle
Hallo Leute, ich mache so etwas. Und es funktioniert für mich
Erstellen Sie ein boolesches Feld in der gemeinsamen Voreinstellung. Der Standardwert ist true {isFirstTime: true}, nachdem Sie es zum ersten Mal auf false gesetzt haben. Nichts kann einfacher und zuverlässiger sein als dies im Android-System.
quelle
Context.getSharedPreferences()
, wird es am selben Ort enden, außer es wird überall funktionieren