Androidアプリが初めて使用されているかどうかを確認する


112

現在、Androidアプリを開発しています。アプリが初めて起動されたときに何かをする必要があります。つまり、プログラムが初めて起動されたときにコードが実行されるだけです。


1
私が最初にアプリの作成を始めたとき、私はアプリがインストールされた後の最初の実行についてのみ考えていました。後で、アップグレード後の最初の実行も処理して区別する必要があることに気付きました。以下の@schnattererの答えとここでの私の答えは、これを行う方法を示しています。アップグレードを考慮しない回答には注意してください。
Suragch

@Suragchあなたはアップグレードを考慮に入れないのは悪い習慣ですが、アプリの紹介をしたいような場合には、それをしたくないでしょう:)
creativecreatoror16年

@creativecreatorornotnot、それは本当です。最初のインストールのみを気にし、その後のアップグレードは気にしない場合があります。これらの状況では、単純なブール値で十分です。ただし、将来のある時点で、前回の更新で追加したすべての新機能について、現在のユーザーに別の紹介を追加したい場合はどうでしょうか。私の意見では、ブール値ではなくバージョン番号をチェックする方が先見の明があります。これにより、少なくとも、新しいインストールとアップグレードの別の方法に対応するオプションが将来的に提供されます。
Suragch 2016

1
次に、このバージョンに追加するだけですが、私はヨットを取得します
creativecreatoror'be

回答:


56

別のアイデアは、共有設定の設定を使用することです。空のファイルをチェックするのと同じ一般的な考え方ですが、空のファイルが浮かんでおらず、何も格納するために使用されていません。


3
この種類のアプローチは、Android Froyoを搭載したSamsung Galaxy Sでは機能しないことに注意してください。これは、SharedPreferencesの保存にバグがあるためです。ここではその上のSOの質問へのリンクです:stackoverflow.com/questions/7296163/...こことは、Googleのコード上のチケットです:code.google.com/p/android/issues/detail?id=14359
フランチェスコRigoni

4
Android 6.0(API 23-Marshmallow)以上の場合、自動バックアップ(developer.android.com/guide/topics/data/autobackup.html)がデフォルトで有効になっていることに注意してください。ユーザーがアプリをアンインストールしてから再インストールすると、共有設定が復元されます。そのため、再インストールの際に問題がある場合、再インストール後に初めて実行されているかどうかを確認することはできません。
アラン

1
@Alan正解です。この回答はAndroid Marshmallowからは無効になりました
Ioane Sharvadze

1
@アラン、あなたが私があなたのような答えを探していた時間は想像できません。あなたは私の日を作りました。ありがとう!
アントニオ

@Alanしかし、自動バックアップは他のほとんどのデータも保存します。そのため、再インストールされたアプリはおそらく初回起動以外の状態になると予想されます。また、ユーザーが以前にアプリを使用したことがあるので、ガイダンスは必要ありません。だから私はほとんどの場合これが起こるのは良いことだと主張します。
smdufb

112

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

17
アプリがGoogle Playストアで次のバージョンに更新されるときに処理されますか?
Shajeel Afzal 14年

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バーマ:getBoolean説明の通りでdeveloper.android.com/reference/android/content/...最初のパラメータが終了しない場合は「my_first_time」が設定されていないので、場合getBooleanの2番目のパラメータは、デフォルト値であります式のデフォルトは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));
}

もう少し努力すれば、おそらくAndroid関連のもの(PackageManagerおよびSharedPreferences)もテストできます。テストを書くことに興味がある人はいますか?:)

上記のコードはandroid:versionCode、AndroidManifest.xmlをいじらないと正しく機能しないことに注意してください。


2
この方法の使い方を教えてください。SharedPreferencesオブジェクトをどこで初期化していますか?
Shajeel Afzal 14年

1
私にはうまく
いき

1
このコードは、コンテキストを宣言することによる副作用がなく、他の場所での設定public AppStart checkAppStart(Context context, SharedPreferences sharedPreferences)よりもはるかに簡単です。はるかに優れたメソッドシグネチャ
Will

2
この回答の更新要旨をここに作成しましたcheckAppStart。それで、更新したコードを共有して、誰かがそれについて提案があるかどうかを確認することにしました
Will

1
@ご入力いただきありがとうございます。そうです、コードを簡略化してより堅牢にすることができます。最初に回答を投稿したときに、さまざまなアクティビティからアクセスしたい、より複雑なシナリオからコードを抽出しましたAppStart。そのため、ロジックを別のサービスメソッドに配置しました。これが、context変数AppStartがあり、べき等メソッド呼び出しを容易にするために静的変数内に格納された理由です。
schnatterer 2014

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バイト、最初に1つの「if」。システムルーチンも同じように動作し、まったく同じように動作するか、すでに起動されているアプリケーションでテーブルを作成します
MechMK1

同様の方法でsharedpreferencesを使用できます。それが存在しない場合は、スプラッシュスクリーンなどを表示し、プログラムが最初に実行されたときにそれを作成するだけです(確認後に確認)。上記のケビンの回答を参照してください
ステルスコプター

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を返します。
ゲイリーキプニス

これはかなり誤解を招くものです。アプリが「常に起動」されているかどうかは表示されません。むしろ、アプリが「ランチャーからユーザーによって起動された」かどうかを示します。そのため、他のアプリやディープリンクがすでにアプリを起動している可能性があります。
ファリッド

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

onCreateは、アプリが初めてインストールされたときにのみトリガーされます。データベースのバージョンが増加すると、onUpdatedがトリガーされます。
スロット2014

まあ余計なことはそのような厳しい言葉です:)-あなたがオプションを持っている場合、すなわち。アプリがまだライブではない場合は、SharedPrefsフラグを設定し、それを使用して初回起動かどうかを判断します。私はアプリがしばらく流行っていて、DBを使用していたので、onCreateは私にぴったりでした。
スロット、2014

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

こんにちは、私はこのようなことをしています。そして、私にとってはその作品

共有設定でブールフィールドを作成します。デフォルト値はtrueです{isFirstTime:true}初めてfalseに設定した後。Androidシステムでは、これほどシンプルで信頼できるものはありません。


ええと、そのようなパスをハードコーディングしないでください!あなたが単にそうContext.getSharedPreferences()するなら、それはどこでも機能することを除いて、同じ場所に
行き着く

あなたに同意します:)
DropAndTrap 2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.