Attualmente sto sviluppando un'app per Android. Devo fare qualcosa quando l'app viene avviata per la prima volta, ovvero il codice viene eseguito solo la prima volta che viene avviato il programma.
Attualmente sto sviluppando un'app per Android. Devo fare qualcosa quando l'app viene avviata per la prima volta, ovvero il codice viene eseguito solo la prima volta che viene avviato il programma.
Risposte:
Un'altra idea è usare un'impostazione nelle Preferenze condivise. Stessa idea generale della ricerca di un file vuoto, ma in questo caso non hai un file vuoto che fluttua, non utilizzato per memorizzare nulla
È possibile utilizzare SharedPreferences per identificare se è la "prima volta" che l'app viene avviata. Usa semplicemente una variabile booleana ("my_first_time") e cambia il suo valore in false quando la tua attività per la "prima volta" è terminata.
Questo è il mio codice per catturare la prima volta che apri l'app:
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();
}
Suggerisco di memorizzare non solo un flag booleano, ma il codice completo della versione. In questo modo puoi anche interrogare all'inizio se è il primo avvio in una nuova versione. È possibile utilizzare queste informazioni per visualizzare una finestra di dialogo "Novità", ad esempio.
Il codice seguente dovrebbe funzionare da qualsiasi classe Android che "è un contesto" (attività, servizi, ...). Se preferisci averlo in una classe separata (POJO), potresti considerare l'utilizzo di un "contesto statico", come descritto qui per esempio.
/**
* 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;
}
}
Potrebbe essere utilizzato da un'attività come questa:
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;
}
// ...
}
// ...
}
La logica di base può essere verificata utilizzando questo test 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));
}
Con un po 'più di sforzo potresti probabilmente testare anche le cose relative ad Android (PackageManager e SharedPreferences). Qualcuno interessato a scrivere il test? :)
Nota che il codice sopra funzionerà correttamente solo se non giochi con il tuo android:versionCodein AndroidManifest.xml!
public AppStart checkAppStart(Context context, SharedPreferences sharedPreferences)è una firma del metodo molto migliore
checkAppStartblocco. così ho deciso di condividere il mio codice aggiornato e vedere se qualcuno ha suggerimenti al riguardo
AppStartda diverse attività. Quindi ho inserito la logica in un metodo di servizio separato. Ecco perché c'era una contextvariabile ed AppStartera memorizzata all'interno di una variabile statica per facilitare le chiamate di metodi idempotenti.
Ho risolto per determinare se l'applicazione è la prima volta o meno, a seconda che si tratti di un aggiornamento.
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
}
}
}
Risultati di calcolo:
Puoi usare Android SharedPreferences .
Android SharedPreferences ci consente di memorizzare i dati di applicazioni primitive private sotto forma di coppia chiave-valore.
CODICE
Crea una classe personalizzata 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;
}
}
Ora apri la tua attività e inizializza .
private SharedPreference sharedPreferenceObj; // Declare Global
Ora chiamalo nella sezione OnCreate
sharedPreferenceObj=new SharedPreference(YourActivity.this);
Ora controllo
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
}
Ecco del codice per questo -
String path = Environment.getExternalStorageDirectory().getAbsolutePath() +
"/Android/data/myapp/files/myfile.txt";
boolean exists = (new File(path)).exists();
if (!exists) {
doSomething();
}
else {
doSomethingElse();
}
Potresti semplicemente verificare l'esistenza di un file vuoto, se non esiste, quindi eseguire il codice e creare il file.
per esempio
if(File.Exists("emptyfile"){
//Your code here
File.Create("emptyfile");
}
Ho creato una semplice classe per verificare se il tuo codice è in esecuzione per la prima volta / n volte!
Esempio
Crea preferenze uniche
FirstTimePreference prefFirstTime = new FirstTimePreference(getApplicationContext());
Usa runTheFirstTime, scegli una chiave per controllare il tuo evento
if (prefFirstTime.runTheFirstTime("myKey")) {
Toast.makeText(this, "Test myKey & coutdown: " + prefFirstTime.getCountDown("myKey"),
Toast.LENGTH_LONG).show();
}
Usa runTheFirstNTimes, scegli una chiave e quante volte esegui
if(prefFirstTime.runTheFirstNTimes("anotherKey" , 5)) {
Toast.makeText(this, "ciccia Test coutdown: "+ prefFirstTime.getCountDown("anotherKey"),
Toast.LENGTH_LONG).show();
}
C'è supporto per proprio questo nella revisione della libreria di supporto 23.3.0 (nella v4 che significa compatibilità con Android 1.6).
Nella tua attività Launcher, prima chiama:
AppLaunchChecker.onActivityCreate(activity);
Quindi chiama:
AppLaunchChecker.hasStartedFromLauncher(activity);
Che tornerà se questa è stata la prima volta che l'app è stata avviata.
Se stai cercando un modo semplice, eccolo qui.
Crea una classe di utilità come questa,
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);
}
}
Nella tua attività 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,
}
per 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();
}
Perché non utilizzare Database Helper? Questo avrà un bel onCreate che viene chiamato solo la prima volta che l'app viene avviata. Ciò aiuterà le persone che desiderano tenerne traccia dopo che l'app iniziale è stata installata senza tracciamento.
onCreate()sia necessaria ogni nuova versione. Inoltre, non sarebbe considerato superfluo o utilizzare qualcosa per uno scopo non intenzionale?
Mi piace avere un "conteggio degli aggiornamenti" nelle mie preferenze condivise. Se non è presente (o il valore predefinito è zero), questo è il "primo utilizzo" della mia app.
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);
Quindi ora, ogni volta che c'è un aggiornamento per l'app di cui gli utenti dovrebbero conoscere, 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);
Ciao ragazzi, sto facendo qualcosa del genere. E per me funziona
creare un campo booleano nella preferenza condivisa. Il valore predefinito è true {isFirstTime: true} dopo la prima volta impostarlo su false. Niente può essere semplice e affidabile di questo nel sistema Android.
Context.getSharedPreferences()finirà nello stesso posto, tranne che funzionerà ovunque