Android 앱을 처음 사용하는지 확인


112

현재 Android 앱을 개발 중입니다. 앱이 처음 실행될 때 뭔가를해야합니다. 즉, 프로그램이 처음 실행될 때만 코드가 실행됩니다.


1
처음 앱을 만들기 시작했을 때는 앱을 설치 한 후 처음 실행할 때만 생각했습니다. 나중에 업그레이드 후 첫 실행을 처리하고 차별화해야한다는 것을 나중에 깨달았습니다. 아래 @schnatterer의 대답과 여기에 내 대답 이 어떻게하는지 보여줍니다. 업그레이드를 고려하지 않는 답변에주의하십시오.
— Suragch 2015

@Suragch 당신은 업그레이드를 고려하지 않는 것이 나쁜 습관처럼 행동하고 있지만 어떤 경우에는 앱 소개와 같은 경우에는 그것을 원하지 않습니다 :)
— creativecreatormaybenot

@creativecreatorormaybenot, 사실입니다. 초기 설치에만 관심이 있고 후속 업그레이드에는 관심이없는 경우가 있습니다. 이러한 상황에는 간단한 부울이면 충분합니다. 그러나 나중에 최근 업데이트에서 방금 추가 한 모든 새로운 기능에 대해 현재 사용자를위한 다른 소개를 추가하려면 어떻게해야합니까? 제 생각에는 부울보다 버전 번호를 확인하는 것이 더 먼 시각입니다. 이것은 적어도 미래에 새로운 설치와 업그레이드에 대해 한 가지 방법으로 응답 할 수있는 옵션을 제공합니다.
— Suragch

1
그럼 그냥이 버전을 추가하지만 yoz 얻을
— creativecreatorormaybenot을

답변:


56

또 다른 아이디어는 공유 기본 설정의 설정을 사용하는 것입니다. 빈 파일을 확인하는 것과 동일한 일반적인 아이디어이지만 아무것도 저장하는 데 사용되지 않는 빈 파일이 떠 다니지 않습니다.


3
이런 종류의 접근 방식은 Android Froyo를 사용하는 Samsung Galaxy S에서 작동하지 않습니다. 그것은 SharedPreferences 저장의 버그 때문입니다. 다음은 이에 대한 SO 질문에 대한 링크입니다. stackoverflow.com/questions/7296163/… 그리고 여기에 Google 코드 티켓이 있습니다. code.google.com/p/android/issues/detail?id=14359
— Francesco Rigoni

4
Android 6.0 (API 23-Marshmallow) 이상 자동 백업 ( developer.android.com/guide/topics/data/autobackup.html) 이 기본적으로 활성화되어 있습니다. 사용자가 앱을 제거한 다음 다시 설치하면 공유 기본 설정이 복구됩니다. 따라서 재설치시 이것이 문제가되는 경우 재설치 후 처음으로 실행 중인지 확인할 수 없습니다.
— Alan

1
@Alan 맞습니다.이 답변은 더 이상 Android Marshmallow에서 유효하지 않습니다 .
— Ioane Sharvadze

1
@Alan 당신은 내가 당신과 같은 대답을 얼마나 오랫동안 찾고 있었는지 상상할 수 없습니다. 당신은 내 하루를 만들었습니다. 감사!
— Antonio

@Alan 그러나 자동 백업은 대부분의 다른 데이터도 저장합니다. 따라서 재설치 된 앱은 아마도 처음 실행되지 않은 상태 일 것으로 예상됩니다. 그리고 사용자는 이전에 이미 앱을 사용 했으므로 안내가 필요하지 않습니다. 그래서 저는 대부분의 경우 이런 일이 일어나는 것이 좋은 일이라고 주장합니다.
— smdufb

112

SharedPreferences 를 사용하여 앱이 "처음 실행"되었는지 확인할 수 있습니다 . 그냥 사용 부울 변수 ( "my_first_time")를하고 해당 값을 변경 거짓 "처음"에 대한 귀하의 작업이 끝나면.

이것은 앱을 처음 열 때 잡는 코드입니다.

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(); 
}

17
Google Play 스토어에서 앱이 다음 버전으로 업데이트되는시기를 처리합니까?
— Shajeel Afzal 2014-06-29

4
SharedPreferences는 업그레이드 중에 유지됩니다. 따라서 PlayStore에서 업그레이드 할 때 이전 값을 사용할 수 있다고 가정합니다. 사실 파일의 존재를 확인하는 다른 방법에도 적용 할 수 있습니다. 따라서이 경우 단축키 방법은 다른 기본 설정 / 파일 이름 또는 값을 사용하는 것입니다.
— Tejasvi Hegde 2014

@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 2014

@aman verma : developer.android.com/reference/android/content/… 의 getBoolean 설명에 따라 getBoolean의 두 번째 매개 변수는 첫 번째 매개 변수가 종료되지 않는 경우 기본값이므로 "my_first_time"이 설정되지 않은 경우 표현식의 기본값은 true입니다.
— user2798692

62

부울 플래그뿐만 아니라 전체 버전 코드를 저장하는 것이 좋습니다. 이렇게하면 새 버전에서 처음 시작하는 경우 처음에 쿼리 할 수도 있습니다. 예를 들어이 정보를 사용하여 "새로운 기능"대화 상자를 표시 할 수 있습니다.

다음 코드는 "컨텍스트 인"모든 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
 * 
 */
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;
    }
}

다음과 같은 활동에서 사용할 수 있습니다.

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;
        }

        // ...
    }
    // ...
}

이 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));
}

조금 더 노력하면 아마도 안드로이드 관련 항목 (PackageManager 및 SharedPreferences)도 테스트 할 수 있습니다. 시험 작성에 관심이있는 사람이 있습니까? :)

위의 코드는 android:versionCodeAndroidManifest.xml에서 엉망이되지 않는 경우에만 제대로 작동합니다 .


2
이 방법을 사용하는 방법을 설명하십시오. SharedPreferences 객체를 어디에서 초기화하고 있습니까?
— Shajeel Afzal 2014-06-29

1
나를 위해 작동하지 않습니다 - 그것은 항상 내 처음 튜토리얼을 시작
— PZO

1
이 코드는 컨텍스트와 선호도를 다른 곳에서 선언하는 부작용없이 훨씬 더 간단합니다 public AppStart checkAppStart(Context context, SharedPreferences sharedPreferences). 훨씬 더 나은 메서드 시그니처
— Will

2
여기 에이 답변의 업데이트 요점을 작성했습니다 .gist.github.com / williscool / 2a57bcd47a206e980eee 버전 번호가 첫 번째 checkAppStart블록 에서 다시 계산되지 않았기 때문에 내 연습 루프에 영원히 멈출 원래 코드에 문제가 있습니다. 그래서 난 내 업데이트 된 코드를 공유하고 누군가가 그것에 대해 제안이 있는지 결정
— 윌를

1
@ 당신의 의견에 감사드립니다. 당신 말이 맞습니다. 코드를 단순화하고 더 강력하게 만들 수 있습니다. 처음 답변을 게시했을 때 다른 활동에서 액세스하려는 더 복잡한 시나리오 에서 코드를 추출했습니다 AppStart. 그래서 논리를 별도의 서비스 방법에 넣었습니다. 거기에 이유의 그 context변수와 AppStart나무 등 메서드 호출을 용이하게하기 위해 정적 변수에 저장되었다.
— schnatterer

4

업데이트 여부에 따라 응용 프로그램이 처음인지 아닌지 확인하기 위해 해결했습니다.

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
        }
    }
}

계산 결과 :

  • 0 : 처음 인 경우.
  • 1 : 시작되었습니다.
  • 2 : 한 번 시작되었지만 해당 버전이 아닙니다. 즉, 업데이트입니다.

3

Android SharedPreferences 를 사용할 수 있습니다 .

Android SharedPreferences를 사용하면 키-값 쌍 형식으로 비공개 기본 애플리케이션 데이터를 저장할 수 있습니다.

암호

사용자 정의 클래스 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;
    }

}

이제 활동을 열고 초기화하십시오 .

 private     SharedPreference                sharedPreferenceObj; // Declare Global

이제 OnCreate 섹션 에서 이것을 호출 하십시오.

 sharedPreferenceObj=new SharedPreference(YourActivity.this);

지금 확인 중

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
 }

2

여기에 대한 몇 가지 코드가 있습니다.

String path = Environment.getExternalStorageDirectory().getAbsolutePath() +
                    "/Android/data/myapp/files/myfile.txt";

boolean exists = (new File(path)).exists(); 

if (!exists) {
    doSomething();                                      
}
else {
    doSomethingElse();
}

1

빈 파일이 존재하지 않는지 확인한 다음 코드를 실행하고 파일을 생성하면됩니다.

예 :

if(File.Exists("emptyfile"){
    //Your code here
    File.Create("emptyfile");
}

나는 더 나은 방법이 있어야하고 생각했지만, 생각
— Boardy

나는 아무것도 모르지만 그로 인해받는 자원이 부족한 것은 무엇입니까? 파일 용으로 4 바이트, 시작 부분에 하나의 "if". 시스템 루틴은 똑같은 일을 할 것입니다. 그들은 정확히 똑같은 일을하거나 이미 실행 된 애플리케이션으로 테이블을 만들 것입니다
— MechMK1

비슷한 방식으로 sharedpreferences를 사용할 수 있는데, 존재하지 않으면 스플래시 화면 등을 표시하고 프로그램이 처음 실행될 때 생성합니다 (확인 후 obv). 위의 Kevin의 답변 참조
— stealthcopter 2011 년

1

코드가 처음 / n 번 실행되는지 확인하는 간단한 클래스를 만들었습니다!

예

고유 한 선호도 만들기

FirstTimePreference prefFirstTime = new FirstTimePreference(getApplicationContext());

runTheFirstTime을 사용하고 이벤트를 확인할 키를 선택하세요.

if (prefFirstTime.runTheFirstTime("myKey")) {
    Toast.makeText(this, "Test myKey & coutdown: " + prefFirstTime.getCountDown("myKey"),
                   Toast.LENGTH_LONG).show();
}

runTheFirstNTimes 사용, 키 선택 및 실행 횟수 선택

if(prefFirstTime.runTheFirstNTimes("anotherKey" , 5)) {
    Toast.makeText(this, "ciccia Test coutdown: "+ prefFirstTime.getCountDown("anotherKey"),
                   Toast.LENGTH_LONG).show();
}
  • getCountDown ()을 사용하여 코드를 더 잘 처리하십시오.

FirstTimePreference.java


1

지원 라이브러리 개정판 23.3.0 (v4에서는 Android 1.6으로의 호환성을 의미 함)에서 이에 대한 지원이 있습니다.

런처 활동에서 먼저 다음을 호출하십시오.

AppLaunchChecker.onActivityCreate(activity);

그런 다음 전화 :

AppLaunchChecker.hasStartedFromLauncher(activity);

앱이 처음 실행 된 경우 반환됩니다.


이러한 호출의 순서를 반대로해야합니다. AppLaunchChecker.onActivityCreate ()가 호출되면 AppLaunchChecker.hasStartedFromLauncher ()가 true를 반환합니다.
— Gary Kipnis

이것은 오해의 소지가 있습니다. 앱이 "출시 된 적이 없는지"는 말하지 않습니다. 오히려 앱이 "런처에서 사용자에 의해 실행 된 적이 있는지"여부를 나타냅니다. 따라서 다른 앱이나 딥 링크가 이미 앱을 시작했을 가능성이 있습니다.
— Farid

1

간단한 방법을 찾고 있다면 여기에 있습니다.

이와 같은 유틸리티 클래스를 만듭니다.

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);
 }

}

주요 활동에서 onCreate ()

if(!ApplicationUtils.getBooleanPreferenceValue(this,"isFirstTimeExecution")){
Log.d(TAG, "First time Execution");
ApplicationUtils.setBooleanPreferenceValue(this,"isFirstTimeExecution",true);
// do your first time execution stuff here,
}

1

코 틀린

    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();

}

Kotlin
— MMG에서

0

데이터베이스 도우미를 사용하지 않는 이유는 무엇입니까? 이것은 앱이 처음 시작될 때만 호출되는 멋진 onCreate를 가질 것입니다. 이렇게하면 추적없이 초기 앱을 설치 한 후이를 추적하려는 사람들에게 도움이됩니다.


데이터베이스가 생성됩니까? 실제 데이터베이스를 만들지 않고 DatabaseHelper를 사용하는 방법은 무엇입니까? 그리고 나는 onCreate()모든 새로운 버전에 대해 호출됩니다. 또한 불필요한 것으로 간주되거나 의도하지 않은 목적으로 사용되지 않습니까?
— ADTC

onCreate는 앱이 처음 설치 될 때만 트리거됩니다. db 버전이 증가하면 onUpdated가 트리거됩니다.
— 슬로

너무 가혹한 단어입니다 :)-옵션이 있다면. 앱이 아직 라이브 상태가 아닌 다음 SharedPrefs 플래그를 설정하고이를 사용하여 첫 번째 부팅인지 여부를 확인합니다. 나는 앱이 한동안 야생에 있었던 경우가 있었고 우리는 DB를 사용했기 때문에 onCreate가 나에게 완벽하게 일치했습니다.
— slott

0

내 공유 환경 설정에 "업데이트 횟수"가있는 것을 좋아합니다. 이것이 없으면 (또는 기본값 0 값) 내 앱의 "처음 사용"입니다.

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);

이제 사용자가 알아야 할 앱 업데이트가있을 때마다 UPDATE_COUNT 개를 늘립니다.


-1
    /**
     * @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);

-2

안녕하세요 여러분 저는 이런 일을하고 있습니다. 그리고 나를위한 작품

공유 환경 설정에서 Boolean 필드를 만듭니다. 처음으로 false로 설정 한 후 기본값은 true {isFirstTime : true}입니다. 안드로이드 시스템에서 이것보다 간단하고 신뢰할 수있는 것은 없습니다.


어, 그렇게 경로를 하드 코딩하지 마세요! 당신은 단순히 할 경우 Context.getSharedPreferences()이 같은 장소에서 끝날 것, 그것은 어디에서나 작동 제외시켰다
— Takhion

동의합니다 :)
— DropAndTrap
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.