确定Android应用程序是否是第一次使用

Determine if android app is the first time used

我目前正在开发一个Android应用程序。 当应用程序第一次启动时,我需要做一些事情,即代码仅在程序第一次启动时运行。


您可以使用SharedPreferences来确定它是否是"第一次"启动应用程序。
只需使用布尔变量("my_first_time"),并在"第一次"任务结束时将其值更改为false。

这是我第一次打开应用程序时捕获的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
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();
}


我建议不仅要存储布尔标志,还要存储完整的版本代码。
这样,您也可以在开头查询它是否是新版本中的第一个开始。例如,您可以使用此信息显示"Whats new"对话框。

以下代码应该适用于"是一个上下文"(活动,服务,......)的任何android类。如果您希望将它放在单独的(POJO)类中,则可以考虑使用"静态上下文",例如此处所述。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/**
 * 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 not idempotent 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;
    }
}

它可以从这样的活动中使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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测试验证基本逻辑:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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));
}

通过更多的努力,你可以测试android相关的东西(PackageManager和SharedPreferences)。
有兴趣写测试的人吗? :)

请注意,如果您没有在AndroidManifest.xml中使用android:versionCode,上述代码将只能正常工作!


另一个想法是使用共享首选项中的设置。与检查空文件相同的一般想法,但是你没有漂浮的空文件,不用于存储任何东西


您可以使用Android SharedPreferences。

Android SharedPreferences allows us to store private primitive
application data in the form of key-value pair .

创建自定义类SharedPreference

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 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.commit();
    }

    public String getApp_runFirst()
    {
        String  App_runFirst= pref.getString(KEY_SET_APP_RUN_FIRST_TIME,"FIRST");
        return  App_runFirst;
    }

}

现在打开你的活动&amp;初始化。

1
 private     SharedPreference                sharedPreferenceObj; // Declare Global

现在在OnCreate部分调用它

1
 sharedPreferenceObj=new SharedPreference(YourActivity.this);

现在检查

1
2
3
4
5
6
7
8
9
10
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
 }

我解决了确定应用程序是否是您的第一次,具体取决于它是否是更新。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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:它已启动一次,但不是那个版本,即它是一个更新。

这是一些代码 -

1
2
3
4
5
6
7
8
9
10
11
String path = Environment.getExternalStorageDirectory().getAbsolutePath() +
                   "/Android/data/myapp/files/myfile.txt";

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

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


如果您正在寻找一种简单的方法,那么就是这样。

创建这样的实用程序类,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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).commit();
 }

 /**
  * 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()

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

在支持库版本23.3.0中支持这一点(在v4中,这意味着可以恢复到Android 1.6)。

在您的Launcher活动中,首先致电:

1
AppLaunchChecker.onActivityCreate(activity);

然后打电话:

1
AppLaunchChecker.hasStartedFromLauncher(activity);

如果这是第一次启动应用程序,将返回


我做了一个简单的类来检查你的代码是否第一次运行/ n次!

创建一个独特的偏好

1
FirstTimePreference prefFirstTime = new FirstTimePreference(getApplicationContext());

使用runTheFirstTime,选择一个键来检查您的事件

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

使用runTheFirstNTimes,选择一个键以及执行的次数

1
2
3
4
if(prefFirstTime.runTheFirstNTimes("anotherKey" , 5)) {
    Toast.makeText(this,"ciccia Test coutdown:"+ prefFirstTime.getCountDown("anotherKey"),
                   Toast.LENGTH_LONG).show();
}
  • 使用getCountDown()可以更好地处理代码

FirstTimePreference.java


您可以简单地检查是否存在空文件,如果它不存在,则执行您的代码并创建该文件。

例如

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


我喜欢在我的共享首选项中有一个"更新计数"。如果它不存在(或默认零值)那么这是我的应用程序的"第一次使用"。

1
2
3
4
5
6
7
8
9
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


为什么不使用数据库助手?这将有一个很好的onCreate,它只在应用程序第一次启动时调用。这将有助于那些想要在初始应用程序之后进行跟踪的人没有跟踪。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
    /**
     * @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);

嗨伙计们,我正在做这样的事情。它的作品适合我

在共享首选项中创建一个布尔字段。默认值为true
{isFirstTime:真正}
在第一次设置为false之后。在android系统中,没有比这更简单和可靠的东西了。