Определите, используется ли приложение Android в первый раз
112
В настоящее время я разрабатываю приложение для Android. Мне нужно что-то сделать при первом запуске приложения, т.е. код запускается только при первом запуске программы.
Когда я впервые начал создавать приложения, я думал только о первом запуске после установки приложения. Позже я понял, что мне также необходимо обрабатывать и различать первые запуски после обновлений. Ответ @ schnatterer ниже, и мой ответ здесь покажет, как это сделать. Будьте осторожны с ответами, которые не принимают во внимание обновления.
Suragch
@Suragch, ты ведешь себя так, как будто это плохая практика - не принимать во внимание обновления, но в некоторых случаях, например, когда ты представляешь приложение, ты НЕ ХОТИТЕ этого делать :)
creativecreatorormaybenot
@creativecreatorormaybenot, это правда. Бывают случаи, когда вам нужна только первоначальная установка, а не последующие обновления. Для таких ситуаций достаточно простого логического значения. Однако что, если в какой-то момент в будущем вы захотите добавить другое введение для текущих пользователей обо всех новых функциях, которые вы только что добавили в последнем обновлении? На мой взгляд, более дальновидно проверять номер версии, а не логическое значение. Это, по крайней мере, дает вам возможность в будущем ответить одним способом для новой установки и другим способом для обновления.
Suragch
1
Тогда вы просто добавляете его для этой версии, но я получаю yoz
Другая идея - использовать настройку в общих настройках. Та же общая идея, что и проверка пустого файла, но тогда у вас нет пустого файла, плавающего вокруг, не используемого для хранения чего-либо.
Остерегайтесь Android 6.0 (API 23 - Marshmallow) или выше, автоматическое резервное копирование ( developer.android.com/guide/topics/data/autobackup.html) включено по умолчанию. Если пользователь удалит, а затем переустановит приложение, общие настройки будут восстановлены. Таким образом, при переустановке вы не можете проверить, запускается ли он в первый раз после переустановки, если это вызывает какие-либо проблемы.
Алан
1
@Alan, вы правы, этот ответ больше не действителен для Android Marshmallow.
Иоанн Шарвадзе
1
@ Алан, ты не представляешь, как долго я искал такой ответ, как твой. Вы сделали мой день. Спасибо!
Антонио
@Alan Но автоматическое резервное копирование также сохраняет большинство других данных. Таким образом, вероятно, что переустановленное приложение не будет запускаться первым. И пользователь уже использовал приложение раньше, поэтому в руководстве нет необходимости. Так что в большинстве случаев я считаю, что это хорошо.
smdufb 08
112
Вы можете использовать SharedPreferences, чтобы определить, запускается ли приложение «впервые». Просто используйте логическую переменную («my_first_time») и измените ее значение на false, когда ваша задача «в первый раз» завершится .
Это мой код, который нужно поймать при первом открытии приложения:
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();}
Сможет ли он справиться, когда приложение будет обновлено до следующей версии в магазине Google Play?
Шажил Афзал
4
SharedPreferences сохраняется во время обновления. Итак, я предполагаю, что при обновлении из PlayStore будет доступно старое значение. Фактически, это применимо и к другим методам, т.е. проверке существования файла. Итак, метод ярлыка в этом случае заключается в использовании другого предпочтения / имени файла или значения.
Tejasvi Hegde
@ShajeelAfzal что-то вроде этого может помочь вам public void CheckAndInitAppFirstTime () {final String PREFS_NAME = "TheAppVer"; последняя строка CHECK_VERSION = "1"; // Обязательная версия ... final String KEY_NAME = "CheckVersion"; Настройки SharedPreferences = getSharedPreferences (PREFS_NAME, 0); if (! settings.getString (KEY_NAME, "0"). equals (CHECK_VERSION)) {// приложение запускается в первый раз, сделайте что-нибудь или CHECK_VERSION отличается // ... settings.edit (). putString ( KEY_NAME, CHECK_VERSION) .commit (); }}
Tejasvi Hegde
@aman verma: согласно описанию getBoolean на сайте developer.android.com/reference/android/content/… 2-й параметр getBoolean является значением по умолчанию, если первый параметр не завершается, поэтому, если "my_first_time" не было установлено по умолчанию выражение истинно.
user2798692 08
63
Я предлагаю хранить не только логический флаг, но и полный код версии. Таким образом, вы также можете запросить в начале, является ли это первым запуском в новой версии. Вы можете использовать эту информацию, например, для отображения диалогового окна «Что нового».
Следующий код должен работать с любым классом Android, который «является контекстом» (действия, услуги, ...). Если вы предпочитаете иметь его в отдельном (POJO) классе, вы можете рассмотреть возможность использования «статического контекста», как описано здесь, например.
/**
* 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;}}
Его можно использовать в таком действии:
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;}// ...}// ...}
Базовую логику можно проверить с помощью этого теста 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));}
Приложив немного больше усилий, вы, вероятно, сможете протестировать и все, что связано с Android (PackageManager и SharedPreferences). Кому-нибудь интересно написать тест? :)
Обратите внимание, что приведенный выше код будет работать правильно только в том случае, если вы не возитесь со своим android:versionCodeв AndroidManifest.xml!
Объясните, пожалуйста, как пользоваться этим методом. Где вы инициализируете объект SharedPreferences?
Шажил Афзал
1
не работает для меня - он всегда запускает мой первый учебник
pzo
1
этот код намного более прямолинейный, без побочных эффектов объявления контекста и предпочтений в другом месте public AppStart checkAppStart(Context context, SharedPreferences sharedPreferences)- гораздо лучшая сигнатура метода
Will
2
Суть обновления этого ответа здесь gist.github.com/williscool/2a57bcd47a206e980eee. У меня возникла проблема с исходным кодом, из-за которой он навсегда застрял в моем цикле пошагового руководства, потому что номер версии никогда не пересчитывался в первом checkAppStartблоке. поэтому я решил поделиться своим обновленным кодом и посмотреть, есть ли у кого-нибудь предложения по этому поводу
Will
1
@ Спасибо за ваш вклад. Вы правы, код можно упростить и сделать более надежным. Когда я впервые опубликовал ответ, я извлек код из более сложного сценария , к которому я хотел получить доступ AppStartиз различных действий. Поэтому я вынес логику в отдельный сервисный метод. Вот почему существует contextпеременная, которая AppStartхранилась в статической переменной для облегчения вызовов идемпотентных методов.
schnatterer
4
Решил определить, приложение у вас первое или нет, в зависимости от того, обновление ли.
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}}}
Вычислить результаты:
0: Если это впервые.
1: Это началось когда-либо.
2: Он запускался один раз, но не в этой версии, т.е. это обновление.
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}
Порядок этих вызовов должен быть изменен на обратный, после вызова AppLaunchChecker.onActivityCreate () AppLaunchChecker.hasStartedFromLauncher () вернет true.
Гэри Кипнис
Это вводит в заблуждение. Он не говорит, было ли приложение когда-либо запущено; он, скорее, говорит, «запускалось ли приложение когда-либо пользователем из модуля запуска». Таким образом, есть вероятность, что другие приложения или внешние ссылки уже запустили приложение.
Фарид
1
Вы можете просто проверить наличие пустого файла, если он не существует, затем выполнить свой код и создать файл.
Я думал об этом, но подумал, что должен быть лучший способ
Boardy
Я не знаю ни одного, но что за недостаток ресурсов вы получаете из-за этого? 4 байта для файла и одно «если» в начале. Системные процедуры будут делать то же самое, они будут делать то же самое или составить таблицу с приложениями, которые уже были
запущены
Аналогичным образом вы можете использовать общие настройки, которые, если они не существуют, вы показываете экран-заставку и т. Д. И просто создаете его при первом запуске программы (obv после проверки). См. Ответ Кевина выше
Stealthcopter
1
Я сделал простой класс, чтобы проверить, запускается ли ваш код в первый раз / n раз!
Используйте runTheFirstNTimes, выберите ключ и сколько раз выполните
if(prefFirstTime.runTheFirstNTimes("anotherKey",5)){Toast.makeText(this,"ciccia Test coutdown: "+ prefFirstTime.getCountDown("anotherKey"),Toast.LENGTH_LONG).show();}
Используйте getCountDown (), чтобы лучше обрабатывать ваш код
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);}}
В вашей основной деятельности 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();}
Почему бы не использовать помощник по базам данных? У этого будет хороший onCreate, который вызывается только при первом запуске приложения. Это поможет тем людям, которые хотят отслеживать это после того, как первоначальное приложение было установлено без отслеживания.
Это создает базу данных? Как использовать DatabaseHelper без создания реальной базы данных? И я думаю, onCreate()вызывается для каждой новой версии. Кроме того, не будет ли это считаться излишним или использованием чего-либо не по назначению?
ADTC
onCreate срабатывает только при первой установке приложения. Когда версия db увеличивается, запускается onUpdated.
slott
Ну излишне такое резкое слово :) - Если есть возможность т.е. ваше приложение еще не запущено, затем установите флаг SharedPrefs и используйте его, чтобы определить, загружается оно сначала или нет. У меня был случай, когда приложение какое-то время было в дикой природе, и мы использовали БД, поэтому onCreate мне идеально подошел.
slott
0
Мне нравится иметь "счетчик обновлений" в моих общих предпочтениях. Если его там нет (или нулевое значение по умолчанию), то это «первое использование» моего приложения.
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);
Итак, теперь, когда есть обновление приложения, о котором должны знать пользователи, я увеличиваю UPDATE_COUNT
Привет, ребята, я делаю что-то вроде этого. И это работает для меня
создать логическое поле в общих предпочтениях. Значение по умолчанию - истина {isFirstTime: true} после первого раза, когда оно установлено в ложь. В системе Android нет ничего проще и надежнее, чем это.
Э, не надо так жестко указывать путь! Если вы просто сделаете Context.getSharedPreferences()это, он окажется в одном и том же месте, за исключением того, что он будет работать везде
Ответы:
Другая идея - использовать настройку в общих настройках. Та же общая идея, что и проверка пустого файла, но тогда у вас нет пустого файла, плавающего вокруг, не используемого для хранения чего-либо.
источник
Вы можете использовать SharedPreferences, чтобы определить, запускается ли приложение «впервые». Просто используйте логическую переменную («my_first_time») и измените ее значение на false, когда ваша задача «в первый раз» завершится .
Это мой код, который нужно поймать при первом открытии приложения:
источник
Я предлагаю хранить не только логический флаг, но и полный код версии. Таким образом, вы также можете запросить в начале, является ли это первым запуском в новой версии. Вы можете использовать эту информацию, например, для отображения диалогового окна «Что нового».
Следующий код должен работать с любым классом Android, который «является контекстом» (действия, услуги, ...). Если вы предпочитаете иметь его в отдельном (POJO) классе, вы можете рассмотреть возможность использования «статического контекста», как описано здесь, например.
Его можно использовать в таком действии:
Базовую логику можно проверить с помощью этого теста JUnit:
Приложив немного больше усилий, вы, вероятно, сможете протестировать и все, что связано с Android (PackageManager и SharedPreferences). Кому-нибудь интересно написать тест? :)
Обратите внимание, что приведенный выше код будет работать правильно только в том случае, если вы не возитесь со своим
android:versionCode
в AndroidManifest.xml!источник
public AppStart checkAppStart(Context context, SharedPreferences sharedPreferences)
- гораздо лучшая сигнатура методаcheckAppStart
блоке. поэтому я решил поделиться своим обновленным кодом и посмотреть, есть ли у кого-нибудь предложения по этому поводуAppStart
из различных действий. Поэтому я вынес логику в отдельный сервисный метод. Вот почему существуетcontext
переменная, котораяAppStart
хранилась в статической переменной для облегчения вызовов идемпотентных методов.Решил определить, приложение у вас первое или нет, в зависимости от того, обновление ли.
Вычислить результаты:
источник
Вы можете использовать Android SharedPreferences .
КОД
Создайте собственный класс SharedPreference
Теперь откройте свою деятельность и инициализируйте .
Теперь вызовите это в разделе OnCreate
Сейчас проверяю
источник
Вот код для этого -
источник
Именно для этого есть поддержка в версии библиотеки поддержки 23.3.0 (в версии 4, что означает совместимость с Android 1.6).
В своей деятельности Launcher сначала вызовите:
Тогда звоните:
Что вернется, если это был первый запуск приложения.
источник
Вы можете просто проверить наличие пустого файла, если он не существует, затем выполнить свой код и создать файл.
например
источник
Я сделал простой класс, чтобы проверить, запускается ли ваш код в первый раз / n раз!
пример
Создайте уникальные предпочтения
Используйте runTheFirstTime, выберите ключ, чтобы проверить ваше событие
Используйте runTheFirstNTimes, выберите ключ и сколько раз выполните
FirstTimePreference.java
источник
Если вы ищете простой способ, вот он.
Создайте такой служебный класс,
В вашей основной деятельности onCreate ()
источник
для котлина
источник
Почему бы не использовать помощник по базам данных? У этого будет хороший onCreate, который вызывается только при первом запуске приложения. Это поможет тем людям, которые хотят отслеживать это после того, как первоначальное приложение было установлено без отслеживания.
источник
onCreate()
вызывается для каждой новой версии. Кроме того, не будет ли это считаться излишним или использованием чего-либо не по назначению?Мне нравится иметь "счетчик обновлений" в моих общих предпочтениях. Если его там нет (или нулевое значение по умолчанию), то это «первое использование» моего приложения.
Итак, теперь, когда есть обновление приложения, о котором должны знать пользователи, я увеличиваю UPDATE_COUNT
источник
источник
Привет, ребята, я делаю что-то вроде этого. И это работает для меня
создать логическое поле в общих предпочтениях. Значение по умолчанию - истина {isFirstTime: true} после первого раза, когда оно установлено в ложь. В системе Android нет ничего проще и надежнее, чем это.
источник
Context.getSharedPreferences()
это, он окажется в одном и том же месте, за исключением того, что он будет работать везде