Determine se o aplicativo Android está sendo usado pela primeira vez
112
Atualmente, estou desenvolvendo um aplicativo Android. Preciso fazer algo quando o aplicativo é iniciado pela primeira vez, ou seja, o código só é executado na primeira vez que o programa é iniciado.
Quando comecei a fazer aplicativos, estava pensando apenas na primeira execução após a instalação de um aplicativo. Mais tarde, percebi que também precisava lidar e diferenciar as primeiras execuções após as atualizações. A resposta de @chnatterer abaixo e minha resposta aqui mostram como fazer isso. Tenha cuidado com as respostas que não levam em consideração as atualizações.
Suragch
@Suragch, você está agindo como se não fosse uma prática ruim não levar as atualizações em consideração, mas em alguns casos, como a introdução de um aplicativo, você NÃO quer fazer :)
creativecreatorormaybenot
@creativecreatorormaybenot, isso é verdade. Há momentos em que você só se preocupa com a instalação inicial e não com as atualizações subsequentes. Um booleano simples é suficiente para essas situações. No entanto, e se em algum momento no futuro você quiser adicionar uma introdução diferente para os usuários atuais sobre todos os novos recursos que acabou de adicionar na última atualização? Na minha opinião, é mais perspicaz verificar o número da versão do que um booleano. Isso pelo menos lhe dá a opção no futuro de responder de uma forma para uma nova instalação e outra para uma atualização.
Suragch
1
Então você apenas adiciona para esta versão, mas eu recebo yoz
Outra ideia é usar uma configuração nas Preferências compartilhadas. A mesma ideia geral que verificar se há um arquivo vazio, mas você não tem um arquivo vazio flutuando por aí, não sendo usado para armazenar nada
Cuidado com o Android 6.0 (API 23 - Marshmallow) ou backup automático superior ( developer.android.com/guide/topics/data/autobackup.html)está habilitado por padrão. Se o usuário desinstalar e reinstalar o aplicativo, as preferências compartilhadas serão recuperadas. Portanto, nas reinstalações, você não pode verificar se está sendo executado pela primeira vez após a reinstalação, se isso for motivo de preocupação.
Alan
1
@Alan você está certo, esta resposta não é mais válida para o Android Marshmallow.
Ioane Sharvadze
1
@Alan você não pode imaginar quanto tempo eu estive procurando por uma resposta como a sua. Você fez meu dia. Obrigado!
Antonio
@Alan Mas o backup automático também salva a maioria dos outros dados. Portanto, é provável que o aplicativo reinstalado não esteja em um estado de não execução inicial. E o usuário já usou o aplicativo antes, então não há necessidade de orientação. Portanto, na maioria dos casos, eu diria que é uma coisa boa que isso aconteça.
smdufb
112
Você pode usar o SharedPreferences para identificar se é a "primeira vez" que o aplicativo é iniciado. Apenas use uma variável booleana ("my_first_time") e altere seu valor para false quando sua tarefa pela "primeira vez" terminar.
Este é o meu código para detectar a primeira vez que você abrir o aplicativo:
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();}
Será que ele aguentará quando o aplicativo será atualizado para a próxima versão na loja do Google Play?
Shajeel Afzal
4
SharedPreferences são mantidos durante a atualização. Portanto, presumo que, ao ser atualizado da PlayStore, o valor antigo estará disponível. Na verdade, é aplicável para outros métodos, ou seja, verificar a existência do arquivo também. Portanto, o método de atalho nesse caso é usar uma preferência / nome de arquivo ou valor diferente.
Tejasvi Hegde de
@ShajeelAfzal algo como isso pode ajudá-lo public void CheckAndInitAppFirstTime () {final String PREFS_NAME = "TheAppVer"; final String CHECK_VERSION = "1"; // Ver necessário ... final String KEY_NAME = "CheckVersion"; Configurações de SharedPreferences = getSharedPreferences (PREFS_NAME, 0); if (! settings.getString (KEY_NAME, "0"). equals (CHECK_VERSION)) {// o aplicativo está sendo iniciado pela primeira vez, faça algo ou CHECK_VERSION é diferente // ... settings.edit (). putString ( KEY_NAME, CHECK_VERSION) .commit (); }}
Tejasvi Hegde
@aman verma: de acordo com a descrição getBoolean em developer.android.com/reference/android/content/… o segundo parâmetro de getBoolean é o valor padrão se o primeiro parâmetro não sair, portanto, se "my_first_time" não tiver sido definido a expressão padrão é verdadeira.
user2798692
62
Eu sugiro não apenas armazenar um sinalizador booleano, mas o código de versão completo. Desta forma, você também pode consultar no início se é o primeiro início de uma nova versão. Você pode usar essas informações para exibir uma caixa de diálogo "O que há de novo", por exemplo.
O código a seguir deve funcionar em qualquer classe Android que "seja um contexto" (atividades, serviços, ...). Se você preferir tê-lo em uma classe separada (POJO), pode considerar o uso de um "contexto estático", conforme descrito aqui, por exemplo.
/**
* 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;}}
Pode ser usado a partir de uma atividade 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;}// ...}// ...}
A lógica básica pode ser verificada usando este teste 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));}
Com um pouco mais de esforço, você provavelmente poderá testar as coisas relacionadas ao Android (PackageManager e SharedPreferences) também. Alguém está interessado em escrever o teste? :)
Observe que o código acima só funcionará corretamente se você não mexer no seu android:versionCodeAndroidManifest.xml!
Explique como usar este método. Onde você está inicializando o objeto SharedPreferences?
Shajeel Afzal
1
não funciona para mim - sempre inicia meu tutorial pela primeira vez
pzo
1
este código é muito mais direto, sem os efeitos colaterais de declarar o contexto e as preferências em outro lugar, public AppStart checkAppStart(Context context, SharedPreferences sharedPreferences)é uma assinatura de método muito melhor
Will
2
Fiz uma atualização da essência desta resposta aqui gist.github.com/williscool/2a57bcd47a206e980eee. Tive um problema com o código original em que ele ficava preso no meu loop de orientação para sempre porque o número da versão nunca estava sendo recalculado no primeiro checkAppStartbloco. então decidi compartilhar meu código atualizado e ver se alguém tem sugestões sobre ele
Will
1
@Agradecemos por sua contribuição. Você está certo, o código poderia ser simplificado e tornado mais robusto. Quando postei a resposta pela primeira vez, extraí o código de um cenário mais complexo , onde queria acessar AppStartde diferentes atividades. Portanto, coloquei a lógica em um método de serviço separado. É por isso que havia uma contextvariável e AppStartfoi armazenada em uma variável estática para facilitar chamadas de métodos idempotentes.
Schnatterer
4
Resolvi determinar se o aplicativo é a primeira vez ou não, dependendo se é uma atualização.
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}}}
Resultados do cálculo:
0: Se for a primeira vez.
1: Isso já começou.
2: Foi iniciado uma vez, mas não naquela versão, ou seja, é uma atualização.
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}
Eu estava pensando em fazer isso, mas pensei que deveria haver uma maneira melhor
Boardy
Não conheço nenhum, mas qual é a falta de recursos que você recebe com isso? 4 bytes para o arquivo e um "if" no início. Rotinas de sistema fariam o mesmo, fariam exatamente o mesmo ou
criariam
De maneira semelhante, você pode usar as preferências compartilhadas, que se não existirem, você mostra uma tela inicial, etc ... e apenas a cria quando o programa é executado pela primeira vez (obviamente após a verificação). Veja a resposta de Kevin acima
stealthcopter
1
Fiz uma aula simples para verificar se seu código está rodando pela primeira vez / n vezes!
Use runTheFirstNTimes, escolha uma chave e quantas vezes execute
if(prefFirstTime.runTheFirstNTimes("anotherKey",5)){Toast.makeText(this,"ciccia Test coutdown: "+ prefFirstTime.getCountDown("anotherKey"),Toast.LENGTH_LONG).show();}
Use getCountDown () para lidar melhor com seu código
A ordem dessas chamadas deve ser invertida, depois que AppLaunchChecker.onActivityCreate () for chamado, AppLaunchChecker.hasStartedFromLauncher () retornará verdadeiro.
Gary Kipnis
Isso é bastante enganador. Não diz se o aplicativo "já foi lançado"; em vez disso, diz se o aplicativo "já foi iniciado por um usuário a partir do inicializador". Portanto, existe a possibilidade de que outros aplicativos ou links diretos já tenham iniciado o aplicativo.
Farid de
1
Se procura uma forma simples, aqui está.
Crie uma classe de utilitário 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);}}
Em sua atividade 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 que não usar o Database Helper? Isso terá um onCreate agradável que só é chamado na primeira vez que o aplicativo é iniciado. Isso ajudará as pessoas que desejam rastrear isso depois que o aplicativo inicial for instalado sem rastreamento.
Isso cria um banco de dados? Como usar o DatabaseHelper sem criar um banco de dados real? E eu acho que onCreate()é chamado para cada nova versão. Além disso, não seria considerado supérfluo ou usar algo para um propósito não intencional?
ADTC de
onCreate só é acionado quando o aplicativo é instalado pela primeira vez. Quando a versão do banco de dados é incrementada, onUpdated é acionado.
Slott de
Bem, supérfluo é uma palavra tão dura :) - Se você tiver a opção ou seja. seu aplicativo ainda não está ativo, então configure um sinalizador SharedPrefs e use-o para determinar se é a primeira inicialização ou não. Tive um caso em que o aplicativo estava em uso há algum tempo e estávamos usando um banco de dados, então o onCreate era uma combinação perfeita para mim.
Slott de
0
Gosto de ter uma "contagem de atualização" em minhas preferências compartilhadas. Se não estiver lá (ou o valor padrão zero), este é o "primeiro uso" do meu aplicativo.
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);
Agora, sempre que houver uma atualização do aplicativo que os usuários devam conhecer, eu incremento UPDATE_COUNT
Olá pessoal, estou fazendo algo assim. E funciona para mim
crie um campo booleano na preferência compartilhada. O valor padrão é verdadeiro {isFirstTime: verdadeiro} após definir pela primeira vez como falso. Nada pode ser simples e confiável do que isso no sistema Android.
Uh, não codifique o caminho assim! Se você simplesmente fizer Context.getSharedPreferences(), terminará no mesmo lugar, exceto que funcionará em qualquer lugar
Respostas:
Outra ideia é usar uma configuração nas Preferências compartilhadas. A mesma ideia geral que verificar se há um arquivo vazio, mas você não tem um arquivo vazio flutuando por aí, não sendo usado para armazenar nada
fonte
Você pode usar o SharedPreferences para identificar se é a "primeira vez" que o aplicativo é iniciado. Apenas use uma variável booleana ("my_first_time") e altere seu valor para false quando sua tarefa pela "primeira vez" terminar.
Este é o meu código para detectar a primeira vez que você abrir o aplicativo:
fonte
Eu sugiro não apenas armazenar um sinalizador booleano, mas o código de versão completo. Desta forma, você também pode consultar no início se é o primeiro início de uma nova versão. Você pode usar essas informações para exibir uma caixa de diálogo "O que há de novo", por exemplo.
O código a seguir deve funcionar em qualquer classe Android que "seja um contexto" (atividades, serviços, ...). Se você preferir tê-lo em uma classe separada (POJO), pode considerar o uso de um "contexto estático", conforme descrito aqui, por exemplo.
Pode ser usado a partir de uma atividade como esta:
A lógica básica pode ser verificada usando este teste JUnit:
Com um pouco mais de esforço, você provavelmente poderá testar as coisas relacionadas ao Android (PackageManager e SharedPreferences) também. Alguém está interessado em escrever o teste? :)
Observe que o código acima só funcionará corretamente se você não mexer no seu
android:versionCode
AndroidManifest.xml!fonte
public AppStart checkAppStart(Context context, SharedPreferences sharedPreferences)
é uma assinatura de método muito melhorcheckAppStart
bloco. então decidi compartilhar meu código atualizado e ver se alguém tem sugestões sobre eleAppStart
de diferentes atividades. Portanto, coloquei a lógica em um método de serviço separado. É por isso que havia umacontext
variável eAppStart
foi armazenada em uma variável estática para facilitar chamadas de métodos idempotentes.Resolvi determinar se o aplicativo é a primeira vez ou não, dependendo se é uma atualização.
Resultados do cálculo:
fonte
Você pode usar Android SharedPreferences .
CÓDIGO
Crie uma classe personalizada SharedPreference
Agora abra sua atividade e inicialize .
Agora chame isso na seção OnCreate
Verificando agora
fonte
Aqui está um código para isso -
fonte
Você pode simplesmente verificar a existência de um arquivo vazio, se ele não existir, executar seu código e criar o arquivo.
por exemplo
fonte
Fiz uma aula simples para verificar se seu código está rodando pela primeira vez / n vezes!
Exemplo
Crie preferências únicas
Use runTheFirstTime, escolha uma chave para verificar seu evento
Use runTheFirstNTimes, escolha uma chave e quantas vezes execute
FirstTimePreference.java
fonte
Há suporte apenas para isso na revisão da biblioteca de suporte 23.3.0 (na v4, que significa compatibilidade com o Android 1.6).
Em sua atividade do Launcher, primeiro chame:
Então ligue:
Que retornará se esta foi a primeira vez que o aplicativo foi iniciado.
fonte
Se procura uma forma simples, aqui está.
Crie uma classe de utilitário como esta,
Em sua atividade principal, onCreate ()
fonte
para kotlin
fonte
Por que não usar o Database Helper? Isso terá um onCreate agradável que só é chamado na primeira vez que o aplicativo é iniciado. Isso ajudará as pessoas que desejam rastrear isso depois que o aplicativo inicial for instalado sem rastreamento.
fonte
onCreate()
é chamado para cada nova versão. Além disso, não seria considerado supérfluo ou usar algo para um propósito não intencional?Gosto de ter uma "contagem de atualização" em minhas preferências compartilhadas. Se não estiver lá (ou o valor padrão zero), este é o "primeiro uso" do meu aplicativo.
Agora, sempre que houver uma atualização do aplicativo que os usuários devam conhecer, eu incremento UPDATE_COUNT
fonte
fonte
Olá pessoal, estou fazendo algo assim. E funciona para mim
crie um campo booleano na preferência compartilhada. O valor padrão é verdadeiro {isFirstTime: verdadeiro} após definir pela primeira vez como falso. Nada pode ser simples e confiável do que isso no sistema Android.
fonte
Context.getSharedPreferences()
, terminará no mesmo lugar, exceto que funcionará em qualquer lugar