检查应用程序是否正在首次运行

我是 Android 开发的新手,我想设置一些应用程序的属性基于应用程序首先运行后安装。有没有办法找到应用程序是第一次运行,然后设置其第一次运行的属性?

124734 次浏览

只需检查一些首选项,其默认值表示这是第一次运行。因此,如果您得到默认值,请进行初始化,并将此首选项设置为不同的值,以表明应用程序已经初始化。

我们无法通过 Android API 了解这一点。您必须自己存储一些标志,并使其持久存储在 SharedPreferenceEditor或使用数据库中。

If you want to base some licence related stuff on this flag, I suggest you use an obfuscated preference editor provided by the LVL library. It's simple and clean.

问候, 斯蒂芬

下面是使用 SharedPreferences实现“首次运行”检查的示例。

public class MyActivity extends Activity {


SharedPreferences prefs = null;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Perhaps set content view here


prefs = getSharedPreferences("com.mycompany.myAppName", MODE_PRIVATE);
}


@Override
protected void onResume() {
super.onResume();


if (prefs.getBoolean("firstrun", true)) {
// Do first run stuff here then set 'firstrun' as false
// using the following line to edit/commit prefs
prefs.edit().putBoolean("firstrun", false).commit();
}
}
}

当代码运行 prefs.getBoolean(...)时,如果 SharedPreferences中没有保存 boolean,键为“ firstrun”,那么这表明应用程序从未运行过(因为没有任何程序保存过使用该键的布尔值,或者用户已经清除了应用程序数据,以强制执行“首次运行”场景)。如果这不是第一次运行,那么行 prefs.edit().putBoolean("firstrun", false).commit();将被执行,因此 prefs.getBoolean("firstrun", true)实际上将返回 false,因为它覆盖了作为第二个参数提供的默认 true。

    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()) {
launchFlag = true;
writeInstallationFile(installation);
}
sID = readInstallationFile(installation);


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

没有可靠的方法来检测第一次运行,因为共享首选项的方式并不总是安全的,用户可以从设置中删除共享首选项数据! 一个更好的方法是使用这里的答案 是否有唯一的 Android 设备 ID?来获得设备的唯一 ID,并将其存储在服务器的某个地方,这样当用户启动应用程序时,你就可以请求服务器,并检查它是否在你的数据库中,或者它是新的。

公认的答案并不区分第一次运行和随后的升级。只要在共享首选项中设置一个布尔值,就会告诉你这是否是应用程序首次安装后的第一次运行。以后,如果你想升级你的应用程序,并在升级的第一次运行时做一些更改,你将不能再使用那个布尔值,因为共享首选项会在升级过程中保存。

此方法使用共享首选项来保存版本代码,而不是布尔值。

import com.yourpackage.BuildConfig;
...


private void checkFirstRun() {


final String PREFS_NAME = "MyPrefsFile";
final String PREF_VERSION_CODE_KEY = "version_code";
final int DOESNT_EXIST = -1;


// Get current version code
int currentVersionCode = BuildConfig.VERSION_CODE;


// Get saved version code
SharedPreferences prefs = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
int savedVersionCode = 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();
}

您可能会在主活动中从 onCreate调用这个方法,以便每次启动应用程序时都会检查它。

public class MainActivity extends AppCompatActivity {


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);


checkFirstRun();
}


private void checkFirstRun() {
// ...
}
}

如果需要,可以根据用户以前安装的版本调整代码以执行特定的操作。

Idea came from 这个答案. These also helpful:

如果您在获取版本代码方面遇到困难,请参阅以下问答:

This might help you

public class FirstActivity extends Activity {


SharedPreferences sharedPreferences = null;
Editor editor;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);


setContentView(R.layout.activity_login);


sharedPreferences = getSharedPreferences("com.myAppName", MODE_PRIVATE);
}


@Override
protected void onResume() {
super.onResume();


if (sharedPreferences.getBoolean("firstRun", true)) {
//You can perform anything over here. This will call only first time
editor = sharedPreferences.edit();
editor.putBoolean("firstRun", false)
editor.commit();


}
}
}
SharedPreferences mPrefs;
final String welcomeScreenShownPref = "welcomeScreenShown";


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);


mPrefs = PreferenceManager.getDefaultSharedPreferences(this);


// second argument is the default to use if the preference can't be found
Boolean welcomeScreenShown = mPrefs.getBoolean(welcomeScreenShownPref, false);


if (!welcomeScreenShown) {
// here you can launch another activity if you like


SharedPreferences.Editor editor = mPrefs.edit();
editor.putBoolean(welcomeScreenShownPref, true);
editor.commit(); // Very important to save the preference


}
}

The following is an example of using SharedPreferences to achieve a 'forWhat' check.

    preferences = PreferenceManager.getDefaultSharedPreferences(context);
preferencesEditor = preferences.edit();
public static boolean isFirstRun(String forWhat) {
if (preferences.getBoolean(forWhat, true)) {
preferencesEditor.putBoolean(forWhat, false).commit();
return true;
} else {
return false;
}
}

我不确定这是检查的好方法。如果用户使用按钮“清除数据”从设置情况如何?SharedPreferences 将被清除,您将再次捕获“首次运行”。这是个问题。我想使用 InstallReferrerReceiver是更好的主意。