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

Boa*_*rdy 104 android

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

har*_*iss 104

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

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

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(); 
}
Run Code Online (Sandbox Code Playgroud)

  • 当应用程序更新到Google Play商店的下一个版本时,它会处理吗? (14认同)
  • 在升级期间维护SharedPreferences.因此,我假设当它从PlayStore升级时,可以使用旧值.实际上它也适用于其他方法,即检查文件的存在.因此,在这种情况下,快捷方法是使用不同的首选项/文件名或值. (4认同)
  • @amanverma这不是变量;这是关键。 (2认同)

sch*_*rer 61

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

以下代码应该适用于"是一个上下文"(活动,服务,......)的任何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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

        // ...
    }
    // ...
}
Run Code Online (Sandbox Code Playgroud)

可以使用此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));
}
Run Code Online (Sandbox Code Playgroud)

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

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

  • 请解释如何使用此方法.在哪里初始化SharedPreferences对象? (2认同)
  • 在这里做了这个答案的更新要点https://gist.github.com/williscool/2a57bcd47a206e980eee我遇到了原始代码的问题,它会永远卡在我的演练循环中,因为版本号永远不会在第一次重新计算`checkAppStart`块.所以我决定分享我的更新代码,看看是否有人有关于它的建议 (2认同)

Kev*_*ion 50

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

  • 谨防Android 6.0(API 23 - Marshmallow)或以上自动备份(https://developer.android.com/guide/topics/data/autobackup.html)默认启用.如果用户卸载并重新安装应用程序,则将恢复共享首选项.所以在重新安装时,如果有任何问题,你无法在重新安装后第一次检查它是否正在运行. (4认同)
  • 请注意,这种方法无法在Android Froyo的三星Galaxy S上运行.这是因为SharedPreferences节省了一个错误.以下是关于SO问题的链接:http://stackoverflow.com/questions/7296163/cant-save-my-preferences-after-app-killed,这是Google代码上的门票:http://code.google .COM/p /安卓/问题/细节?ID = 14359 (3认同)

Web*_*eis 5

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

\n\n
private int appGetFirstTimeRun() {\n    //Check if App Start First Time\n    SharedPreferences appPreferences = getSharedPreferences("MyAPP", 0);\n    int appCurrentBuildVersion = BuildConfig.VERSION_CODE;\n    int appLastBuildVersion = appPreferences.getInt("app_first_time", 0);\n\n    //Log.d("appPreferences", "app_first_time = " + appLastBuildVersion);\n\n    if (appLastBuildVersion == appCurrentBuildVersion ) {\n        return 1; //ya has iniciado la appp alguna vez\n\n    } else {\n        appPreferences.edit().putInt("app_first_time",\n                appCurrentBuildVersion).apply();\n        if (appLastBuildVersion == 0) {\n            return 0; //es la primera vez\n        } else {\n            return 2; //es una versi\xc3\xb3n nueva\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

计算结果:

\n\n
    \n
  • 0:如果这是第一次。
  • \n
  • 1:它已经开始了。
  • \n
  • 2:已经启动过一次,但不是那个版本,即是更新。
  • \n
\n