Determine si la aplicación de Android se está utilizando por primera vez
112
Actualmente estoy desarrollando una aplicación para Android. Necesito hacer algo cuando la aplicación se inicia por primera vez, es decir, el código solo se ejecuta la primera vez que se inicia el programa.
Cuando comencé a crear aplicaciones, solo pensaba en la primera ejecución después de instalar una aplicación. Más tarde me di cuenta de que también necesitaba manejar y diferenciar las primeras ejecuciones después de las actualizaciones. La respuesta de @ schnatterer a continuación y mi respuesta aquí muestran cómo hacer esto. Tenga cuidado con las respuestas que no tienen en cuenta las actualizaciones.
Suragch
@Suragch estás actuando como es una mala práctica de no tomar en cuenta las actualizaciones pero en algunos casos como tener una introducción aplicación que no quiero hacerlo :)
creativecreatorormaybenot
@creativecreatorormaybenot, eso es cierto. Hay momentos en los que solo le importa la instalación inicial y no las actualizaciones posteriores. Un simple booleano es suficiente para esas situaciones. Sin embargo, ¿qué sucede si en algún momento en el futuro desea agregar una introducción diferente para los usuarios actuales sobre todas las funciones nuevas que acaba de agregar en la última actualización? En mi opinión, es más previsible comprobar el número de versión en lugar de un booleano. Esto al menos le da la opción en el futuro de responder de una forma para una nueva instalación y de otra forma para una actualización.
Suragch
1
Luego, solo lo agrega para esta versión, pero obtengo yoz
Otra idea es utilizar una configuración en las preferencias compartidas. La misma idea general que buscar un archivo vacío, pero luego no tiene un archivo vacío flotando, no se usa para almacenar nada
Tenga cuidado con Android 6.0 (API 23 - Marshmallow) o una copia de seguridad automática superior ( developer.android.com/guide/topics/data/autobackup.html) está habilitada de forma predeterminada. Si los usuarios desinstalan y luego reinstalan la aplicación, se recuperarán las preferencias compartidas. Por lo tanto, en las reinstalaciones no puede verificar si se está ejecutando por primera vez después de la reinstalación si esto le preocupa.
Alan
1
@Alan, tienes razón, esta respuesta ya no es válida desde Android Marshmallow.
Ioane Sharvadze
1
@Alan no puedes imaginar cuánto tiempo estuve buscando una respuesta como la tuya. Me has alegrado el día. ¡Gracias!
Antonio
@Alan Pero la copia de seguridad automática también guarda la mayoría de los datos. Por lo tanto, es probable que se espere que la aplicación reinstalada esté en un estado que no sea de primera ejecución. Y el usuario ya ha utilizado la aplicación antes, por lo que no es necesario que lo oriente. Por lo tanto, diría que en la mayoría de los casos es bueno que esto suceda.
smdufb
112
Puede utilizar SharedPreferences para identificar si es la "primera vez" que se inicia la aplicación. Simplemente use una variable booleana ("my_first_time") y cambie su valor a falso cuando su tarea por "primera vez".
Este es mi código para capturar la primera vez que abre la aplicación:
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();}
¿Manejará cuándo la aplicación se actualizará a la próxima versión en Google Play Store?
Shajeel Afzal
4
Las preferencias compartidas se mantienen durante la actualización. Entonces, supongo que cuando se actualiza desde PlayStore, el valor anterior está disponible. De hecho, es aplicable para otros métodos, es decir, también para verificar la existencia del archivo. Por lo tanto, el método de acceso directo en ese caso es usar una preferencia / nombre de archivo o valor diferente.
Tejasvi Hegde
@ShajeelAfzal algo como esto puede ayudarte a public void CheckAndInitAppFirstTime () {final String PREFS_NAME = "TheAppVer"; Cadena final CHECK_VERSION = "1"; // Requerido ver ... final String KEY_NAME = "CheckVersion"; Configuración de SharedPreferences = getSharedPreferences (PREFS_NAME, 0); if (! settings.getString (KEY_NAME, "0"). equals (CHECK_VERSION)) {// la aplicación se inicia por primera vez, haz algo o CHECK_VERSION es diferente // ... settings.edit (). putString ( KEY_NAME, CHECK_VERSION) .commit (); }}
Tejasvi Hegde
@aman verma: según la descripción de getBoolean en developer.android.com/reference/android/content/… El segundo parámetro de getBoolean es el valor predeterminado si el primer parámetro no sale, por lo que si "my_first_time" no se ha configurado la expresión por defecto es verdadera.
user2798692
62
Sugiero no solo almacenar una bandera booleana, sino el código de versión completo. De esta forma también puede consultar al principio si es el primer inicio en una nueva versión. Puede utilizar esta información para mostrar un cuadro de diálogo "Novedades", por ejemplo.
El siguiente código debería funcionar desde cualquier clase de Android que "sea un contexto" (actividades, servicios, ...). Si prefiere tenerlo en una clase separada (POJO), podría considerar usar un "contexto estático", como se describe aquí, por ejemplo.
/**
* 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;}}
Podría usarse a partir de una actividad como esta:
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 lógica básica se puede verificar usando esta prueba 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));}
Con un poco más de esfuerzo, probablemente también podría probar las cosas relacionadas con Android (PackageManager y SharedPreferences). ¿Alguien interesado en escribir la prueba? :)
Tenga en cuenta que el código anterior solo funcionará correctamente si no se mete con su android:versionCodeen AndroidManifest.xml.
Explique cómo utilizar este método. ¿Dónde está inicializando el objeto SharedPreferences?
Shajeel Afzal
1
no funciona para mí - siempre
inicia
1
este código es mucho más sencillo sin los efectos secundarios de declarar el contexto y las preferencias en otros lugares public AppStart checkAppStart(Context context, SharedPreferences sharedPreferences)es una firma de método mucho mejor
Will
2
Hice una actualización de la esencia de esta respuesta aquí gist.github.com/williscool/2a57bcd47a206e980eee Tuve un problema con el código original en el que se atascaba en mi ciclo de recorrido para siempre porque el número de versión nunca se recalculaba en el primer checkAppStartbloque. así que decidí compartir mi código actualizado y ver si alguien tiene sugerencias al respecto
Will
1
@Will gracias por su aporte. Tiene razón, el código podría simplificarse y hacerse más robusto. Cuando publiqué la respuesta por primera vez, extraje el código de un escenario más complejo , donde quería acceder AppStartdesde diferentes actividades. Así que puse la lógica en un método de servicio separado. Es por eso que había una contextvariable y AppStartse almacenaba dentro de una variable estática para facilitar las llamadas a métodos idempotentes.
schnatterer
4
Resolví determinar si la aplicación es tu primera vez o no, dependiendo de si es una actualización.
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}}}
Calcular resultados:
0: si es la primera vez.
1: Ha comenzado siempre.
2: Ha comenzado una vez, pero no esa versión, es decir, es una actualización.
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}
Estaba pensando en hacer eso, pero pensé que debía haber una mejor manera
Boardy
No sé ninguno, pero ¿cuál es la falta de recursos que recibe con eso? 4 bytes para el archivo y un "si" al principio. Las rutinas del sistema harían lo mismo, harían exactamente lo mismo o crearían una tabla con aplicaciones que ya se han lanzado
MechMK1
De manera similar, puede usar las preferencias compartidas, que si no existen, muestra una pantalla de presentación, etc. y simplemente crea cuando el programa se ejecuta por primera vez (obv después de verificarlo). Vea la respuesta de Kevin arriba
stealthcopter
1
¡Hice una clase simple para verificar si su código se está ejecutando por primera vez / n veces!
Use runTheFirstNTimes, elija una clave y cuántas veces ejecutar
if(prefFirstTime.runTheFirstNTimes("anotherKey",5)){Toast.makeText(this,"ciccia Test coutdown: "+ prefFirstTime.getCountDown("anotherKey"),Toast.LENGTH_LONG).show();}
El orden de estas llamadas debe invertirse, una vez que se haya llamado AppLaunchChecker.onActivityCreate (), AppLaunchChecker.hasStartedFromLauncher () devolverá verdadero.
Gary Kipnis
Esto es bastante engañoso. No dice si la aplicación "se lanzó alguna vez"; más bien, dice si la aplicación "alguna vez la lanzó un usuario desde el lanzador". Por lo tanto, existe la posibilidad de que otras aplicaciones o enlaces profundos ya hayan iniciado la aplicación.
Farid
1
Si buscas una forma sencilla, aquí la tienes.
Cree una clase de utilidad como esta,
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);}}
En su actividad principal, 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();}
¿Por qué no utilizar el Asistente de base de datos? Esto tendrá un buen onCreate que solo se llama la primera vez que se inicia la aplicación. Esto ayudará a aquellas personas que quieran realizar un seguimiento de esto después de que se haya instalado la aplicación inicial sin seguimiento.
¿Eso crea una base de datos? ¿Cómo utilizar DatabaseHelper sin crear una base de datos real? Y creo que onCreate()se llama para cada nueva versión. Además, ¿no se consideraría superfluo o usar algo para un propósito no deseado?
ADTC
onCreate solo se activa cuando la aplicación se instala por primera vez. Cuando se incrementa la versión de db, se activa onUpdated.
slott
Bueno, superflua es una palabra tan dura :) - Si tiene la opción, es decir. su aplicación aún no está activa, luego configure un indicador SharedPrefs y utilícelo para determinar si es el primer inicio o no. Tuve un caso en el que la aplicación había estado en estado salvaje durante algún tiempo y estábamos usando una base de datos, por lo que onCreate era una combinación perfecta para mí.
slott
0
Me gusta tener un "recuento de actualizaciones" en mis preferencias compartidas. Si no está allí (o el valor cero predeterminado), entonces este es el "primer uso" de mi aplicación.
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);
Así que ahora, cada vez que hay una actualización de la aplicación que los usuarios deben conocer, incremento UPDATE_COUNT
Hola chicos, estoy haciendo algo como esto. Y funciona para mi
cree un campo booleano en preferencia compartida. El valor predeterminado es verdadero {isFirstTime: true} después de la primera vez, configúrelo en falso. Nada puede ser simple y confiable que esto en el sistema Android.
¡Uh, no codifiques el camino así! Si simplemente lo Context.getSharedPreferences()hace, terminará en el mismo lugar, excepto que funcionará en todas partes
Respuestas:
Otra idea es utilizar una configuración en las preferencias compartidas. La misma idea general que buscar un archivo vacío, pero luego no tiene un archivo vacío flotando, no se usa para almacenar nada
fuente
Puede utilizar SharedPreferences para identificar si es la "primera vez" que se inicia la aplicación. Simplemente use una variable booleana ("my_first_time") y cambie su valor a falso cuando su tarea por "primera vez".
Este es mi código para capturar la primera vez que abre la aplicación:
fuente
Sugiero no solo almacenar una bandera booleana, sino el código de versión completo. De esta forma también puede consultar al principio si es el primer inicio en una nueva versión. Puede utilizar esta información para mostrar un cuadro de diálogo "Novedades", por ejemplo.
El siguiente código debería funcionar desde cualquier clase de Android que "sea un contexto" (actividades, servicios, ...). Si prefiere tenerlo en una clase separada (POJO), podría considerar usar un "contexto estático", como se describe aquí, por ejemplo.
Podría usarse a partir de una actividad como esta:
La lógica básica se puede verificar usando esta prueba JUnit:
Con un poco más de esfuerzo, probablemente también podría probar las cosas relacionadas con Android (PackageManager y SharedPreferences). ¿Alguien interesado en escribir la prueba? :)
Tenga en cuenta que el código anterior solo funcionará correctamente si no se mete con su
android:versionCode
en AndroidManifest.xml.fuente
public AppStart checkAppStart(Context context, SharedPreferences sharedPreferences)
es una firma de método mucho mejorcheckAppStart
bloque. así que decidí compartir mi código actualizado y ver si alguien tiene sugerencias al respectoAppStart
desde diferentes actividades. Así que puse la lógica en un método de servicio separado. Es por eso que había unacontext
variable yAppStart
se almacenaba dentro de una variable estática para facilitar las llamadas a métodos idempotentes.Resolví determinar si la aplicación es tu primera vez o no, dependiendo de si es una actualización.
Calcular resultados:
fuente
Puede utilizar Preferencias compartidas de Android .
CÓDIGO
Crear una clase personalizada SharedPreference
Ahora abra su actividad e inicialice .
Ahora llame a esto en la sección OnCreate
Ahora comprobando
fuente
Aquí hay un código para esto:
fuente
Simplemente puede verificar la existencia de un archivo vacío, si no existe, luego ejecute su código y cree el archivo.
p.ej
fuente
¡Hice una clase simple para verificar si su código se está ejecutando por primera vez / n veces!
Ejemplo
Crea preferencias únicas
Use runTheFirstTime, elija una clave para verificar su evento
Use runTheFirstNTimes, elija una clave y cuántas veces ejecutar
FirstTimePreference.java
fuente
Solo hay soporte para esto en la revisión de la biblioteca de soporte 23.3.0 (en la v4, lo que significa compatibilidad con Android 1.6).
En su actividad de Lanzador, primero llame a:
Luego llame:
Que volverá si esta fue la primera vez que se lanzó la aplicación.
fuente
Si buscas una forma sencilla, aquí la tienes.
Cree una clase de utilidad como esta,
En su actividad principal, onCreate ()
fuente
para kotlin
fuente
¿Por qué no utilizar el Asistente de base de datos? Esto tendrá un buen onCreate que solo se llama la primera vez que se inicia la aplicación. Esto ayudará a aquellas personas que quieran realizar un seguimiento de esto después de que se haya instalado la aplicación inicial sin seguimiento.
fuente
onCreate()
se llama para cada nueva versión. Además, ¿no se consideraría superfluo o usar algo para un propósito no deseado?Me gusta tener un "recuento de actualizaciones" en mis preferencias compartidas. Si no está allí (o el valor cero predeterminado), entonces este es el "primer uso" de mi aplicación.
Así que ahora, cada vez que hay una actualización de la aplicación que los usuarios deben conocer, incremento UPDATE_COUNT
fuente
fuente
Hola chicos, estoy haciendo algo como esto. Y funciona para mi
cree un campo booleano en preferencia compartida. El valor predeterminado es verdadero {isFirstTime: true} después de la primera vez, configúrelo en falso. Nada puede ser simple y confiable que esto en el sistema Android.
fuente
Context.getSharedPreferences()
hace, terminará en el mismo lugar, excepto que funcionará en todas partes