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.
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.
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
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:
final String 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();
}
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
*
*/
public enum AppStart {
FIRST_TIME, FIRST_TIME_VERSION, NORMAL;
}
/**
* The app version code (not the version name!) that was used on the last
* start of the app.
*/
private static final String 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
*/
public AppStart 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;
}
public AppStart checkAppStart(int currentVersionCode, int lastVersionCode) {
if (lastVersionCode == -1) {
return AppStart.FIRST_TIME;
} else if (lastVersionCode < currentVersionCode) {
return AppStart.FIRST_TIME_VERSION;
} else if (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.");
return AppStart.NORMAL;
} else {
return AppStart.NORMAL;
}
}
Pode ser usado a partir de uma atividade como esta:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
switch (checkAppStart()) {
case NORMAL:
// We don't want to get on the user's nerves
break;
case FIRST_TIME_VERSION:
// TODO show what's new
break;
case FIRST_TIME:
// TODO show a tutorial
break;
default:
break;
}
// ...
}
// ...
}
A lógica básica pode ser verificada usando este teste JUnit:
public void testCheckAppStart() {
// First start
int 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!
public AppStart checkAppStart(Context context, SharedPreferences sharedPreferences)é uma assinatura de método muito melhor
checkAppStartbloco. então decidi compartilhar meu código atualizado e ver se alguém tem sugestões sobre ele
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.
Resolvi determinar se o aplicativo é a primeira vez ou não, dependendo se é uma atualização.
private int appGetFirstTimeRun() {
//Check if App Start First Time
SharedPreferences 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 ) {
return 1; //ya has iniciado la appp alguna vez
} else {
appPreferences.edit().putInt("app_first_time",
appCurrentBuildVersion).apply();
if (appLastBuildVersion == 0) {
return 0; //es la primera vez
} else {
return 2; //es una versión nueva
}
}
}
Resultados do cálculo:
Você pode usar Android SharedPreferences .
O Android SharedPreferences nos permite armazenar dados de aplicativos primitivos privados na forma de par de valores-chave.
CÓDIGO
Crie uma classe personalizada SharedPreference
public class SharedPreference {
android.content.SharedPreferences pref;
android.content.SharedPreferences.Editor editor;
Context _context;
private static final String PREF_NAME = "testing";
// All Shared Preferences Keys Declare as #public
public static final String KEY_SET_APP_RUN_FIRST_TIME = "KEY_SET_APP_RUN_FIRST_TIME";
public SharedPreference(Context context) // Constructor
{
this._context = context;
pref = _context.getSharedPreferences(PREF_NAME, 0);
editor = pref.edit();
}
/*
* Set Method Generally Store Data;
* Get Method Generally Retrieve Data ;
* */
public void setApp_runFirst(String App_runFirst)
{
editor.remove(KEY_SET_APP_RUN_FIRST_TIME);
editor.putString(KEY_SET_APP_RUN_FIRST_TIME, App_runFirst);
editor.apply();
}
public String getApp_runFirst()
{
String App_runFirst= pref.getString(KEY_SET_APP_RUN_FIRST_TIME, "FIRST");
return App_runFirst;
}
}
Agora abra sua atividade e inicialize .
private SharedPreference sharedPreferenceObj; // Declare Global
Agora chame isso na seção OnCreate
sharedPreferenceObj=new SharedPreference(YourActivity.this);
Verificando agora
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
}
Aqui está um código para isso -
String path = Environment.getExternalStorageDirectory().getAbsolutePath() +
"/Android/data/myapp/files/myfile.txt";
boolean exists = (new File(path)).exists();
if (!exists) {
doSomething();
}
else {
doSomethingElse();
}
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
if(File.Exists("emptyfile"){
//Your code here
File.Create("emptyfile");
}
Fiz uma aula simples para verificar se seu código está rodando pela primeira vez / n vezes!
Exemplo
Crie preferências únicas
FirstTimePreference prefFirstTime = new FirstTimePreference(getApplicationContext());
Use runTheFirstTime, escolha uma chave para verificar seu evento
if (prefFirstTime.runTheFirstTime("myKey")) {
Toast.makeText(this, "Test myKey & coutdown: " + prefFirstTime.getCountDown("myKey"),
Toast.LENGTH_LONG).show();
}
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();
}
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:
AppLaunchChecker.onActivityCreate(activity);
Então ligue:
AppLaunchChecker.hasStartedFromLauncher(activity);
Que retornará se esta foi a primeira vez que o aplicativo foi iniciado.
Se procura uma forma simples, aqui está.
Crie uma classe de utilitário como esta,
public class ApplicationUtils {
/**
* Sets the boolean preference value
*
* @param context the current context
* @param key the preference key
* @param value the value to be set
*/
public static void setBooleanPreferenceValue(Context context, String key, boolean value) {
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
*/
public static boolean 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,
}
para kotlin
fun checkFirstRun() {
var prefs_name = "MyPrefsFile"
var pref_version_code_key = "version_code"
var doesnt_exist: Int = -1;
// Get current version code
var currentVersionCode = BuildConfig.VERSION_CODE
// Get saved version code
var prefs: SharedPreferences = getSharedPreferences(prefs_name, MODE_PRIVATE)
var savedVersionCode: Int = prefs.getInt(pref_version_code_key, doesnt_exist)
// Check for first run or upgrade
if (currentVersionCode == savedVersionCode) {
// This is just a normal run
return;
} else if (savedVersionCode == doesnt_exist) {
// TODO This is a new install (or the user cleared the shared preferences)
} else if (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.
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.
private static final int UPDATE_COUNT = 1; // Increment this on major change
...
if (sp.getInt("updateCount", 0) == 0) {
// first use
} else if (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
/**
* @author ALGO
*/
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.UUID;
import android.content.Context;
public class Util {
// ===========================================================
//
// ===========================================================
private static final String INSTALLATION = "INSTALLATION";
public synchronized static boolean isFirstLaunch(Context context) {
String sID = null;
boolean launchFlag = false;
if (sID == null) {
File installation = new File(context.getFilesDir(), INSTALLATION);
try {
if (!installation.exists()) {
writeInstallationFile(installation);
}
sID = readInstallationFile(installation);
launchFlag = true;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return launchFlag;
}
private static String readInstallationFile(File installation) throws IOException {
RandomAccessFile f = new RandomAccessFile(installation, "r");// read only mode
byte[] bytes = new byte[(int) f.length()];
f.readFully(bytes);
f.close();
return new String(bytes);
}
private static void writeInstallationFile(File installation) throws IOException {
FileOutputStream out = new FileOutputStream(installation);
String id = UUID.randomUUID().toString();
out.write(id.getBytes());
out.close();
}
}
> Usage (in class extending android.app.Activity)
Util.isFirstLaunch(this);
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.
Context.getSharedPreferences(), terminará no mesmo lugar, exceto que funcionará em qualquer lugar