Tentukan apakah aplikasi Android digunakan untuk pertama kali

112

Saya sedang mengembangkan aplikasi android. Saya perlu melakukan sesuatu saat aplikasi diluncurkan untuk pertama kali, yaitu kode hanya berjalan saat pertama kali program diluncurkan.

Boardy
sumber
1
Ketika saya pertama kali mulai membuat aplikasi, saya hanya memikirkan penggunaan pertama setelah aplikasi dipasang. Saya kemudian menyadari bahwa saya juga perlu menangani dan membedakan proses pertama setelah peningkatan. @ jawaban schnatterer di bawah dan jawaban saya di sini menunjukkan bagaimana melakukan ini. Berhati-hatilah dengan jawaban yang tidak memperhitungkan peningkatan.
Suragch
@Suragch Anda bertindak seolah-olah itu adalah praktik yang buruk untuk tidak mempertimbangkan peningkatan tetapi dalam beberapa kasus seperti memiliki pengenalan aplikasi Anda TIDAK ingin melakukannya :)
creativecreatorormaybenot
@creativecreatorormaybenot, itu benar. Ada kalanya Anda hanya peduli tentang penginstalan awal dan bukan peningkatan berikutnya. Boolean sederhana sudah cukup untuk situasi itu. Namun, bagaimana jika suatu saat di masa mendatang Anda ingin menambahkan pengenalan yang berbeda untuk pengguna saat ini tentang semua fitur baru yang baru saja Anda tambahkan di pembaruan terakhir? Menurut saya, lebih berpandangan jauh ke depan untuk memeriksa nomor versi daripada boolean. Ini setidaknya memberi Anda pilihan di masa depan untuk menanggapi satu cara untuk pemasangan baru dan cara lain untuk peningkatan.
Suragch
1
Kemudian Anda hanya menambahkannya untuk versi ini tetapi saya mengerti
creativecreatorormaybenot
Anda dapat memeriksa stackoverflow.com/a/7217834/2689076
Vaibhav

Jawaban:

56

Ide lainnya adalah menggunakan pengaturan di Preferensi Bersama. Ide umum yang sama seperti memeriksa file kosong, tetapi Anda tidak memiliki file kosong yang mengambang, tidak digunakan untuk menyimpan apa pun

Kevin Dion
sumber
3
Berhati-hatilah karena pendekatan semacam ini tidak dapat berfungsi pada Samsung Galaxy S dengan Android Froyo. Itu karena bug dalam penyimpanan SharedPreferences. Ini tautan ke pertanyaan SO itu: stackoverflow.com/questions/7296163/… dan ini tiketnya di kode google: code.google.com/p/android/issues/detail?id=14359
Francesco Rigoni
4
Hati-hati untuk Android 6.0 (API 23 - Marshmallow) atau di atasnya auto backup ( developer.android.com/guide/topics/data/autobackup.html) diaktifkan secara default. Jika pengguna mencopot pemasangan dan kemudian memasang kembali aplikasi, preferensi bersama akan dipulihkan. Jadi pada penginstalan ulang Anda tidak dapat memeriksa apakah itu berjalan untuk pertama kalinya setelah menginstal ulang jika ini menjadi perhatian.
Alan
1
@Alan Anda benar, jawaban ini tidak lagi valid dari Android Marshmallow.
Ioane Sharvadze
1
@Alan Anda tidak dapat membayangkan berapa lama saya mencari jawaban seperti milik Anda. Anda membuat hari saya. Terima kasih!
Antonio
@Alan Tetapi pencadangan otomatis juga menghemat sebagian besar data lainnya. Jadi, aplikasi yang diinstal ulang mungkin diharapkan dalam keadaan tidak dijalankan pertama kali. Dan pengguna sudah pernah menggunakan aplikasi sebelumnya, jadi tidak perlu panduan. Jadi saya berpendapat untuk banyak kasus itu adalah hal yang baik ini terjadi.
smdufb
112

Anda dapat menggunakan SharedPreferences untuk mengidentifikasi apakah ini "Pertama kali" aplikasi diluncurkan. Cukup gunakan variabel Boolean ("my_first_time") dan ubah nilainya menjadi false ketika tugas Anda untuk "pertama kali" selesai.

Ini adalah kode saya untuk mengetahui saat pertama kali Anda membuka aplikasi:

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(); 
}
harrakiss
sumber
17
Akankah itu menangani ketika aplikasi akan diperbarui ke versi berikutnya di google play store?
Shajeel Afzal
4
SharedPreferences dipertahankan selama peningkatan. Jadi, saya berasumsi bahwa ketika ditingkatkan dari PlayStore, nilai lama tersedia. Sebenarnya itu berlaku untuk metode lain yaitu memeriksa keberadaan file juga. Jadi, metode pintas dalam hal ini adalah menggunakan preferensi / nama file atau nilai yang berbeda.
Tejasvi Hegde
@ShajeelAfzal beberapa hal seperti ini dapat membantu Anda membatalkan checkAndInitAppFirstTime () {final String PREFS_NAME = "TheAppVer"; String terakhir CHECK_VERSION = "1"; // Diperlukan ver ... String akhir KEY_NAME = "CheckVersion"; SharedPreferences pengaturan = getSharedPreferences (PREFS_NAME, 0); if (! settings.getString (KEY_NAME, "0"). sama dengan (CHECK_VERSION)) {// aplikasi sedang diluncurkan untuk pertama kalinya, lakukan sesuatu atau CHECK_VERSION berbeda // ... settings.edit (). putString ( KEY_NAME, CHECK_VERSION) .commit (); }}
Tejasvi Hegde
@aman verma: sesuai deskripsi getBoolean di developer.android.com/reference/android/content/… parameter ke - 2 getBoolean adalah nilai default jika parameter pertama tidak keluar, jadi jika "my_first_time" belum disetel ekspresi defaultnya adalah true.
pengguna2798692
63

Saya menyarankan untuk tidak hanya menyimpan bendera boolean, tetapi juga kode versi lengkapnya. Dengan cara ini Anda juga dapat membuat kueri di awal jika ini adalah permulaan pertama dalam versi baru. Anda dapat menggunakan informasi ini untuk menampilkan dialog "Yang baru", misalnya.

Kode berikut harus bekerja dari kelas android apa pun yang "merupakan konteks" (aktivitas, layanan, ...). Jika Anda lebih suka memilikinya dalam kelas terpisah (POJO), Anda dapat mempertimbangkan untuk menggunakan "konteks statis", seperti yang dijelaskan di sini misalnya.

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

Ini bisa digunakan dari aktivitas seperti ini:

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

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

Logika dasar dapat diverifikasi menggunakan uji JUnit ini:

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

Dengan sedikit usaha, Anda mungkin bisa menguji hal-hal terkait android (PackageManager dan SharedPreferences) juga. Ada yang tertarik menulis tes? :)

Perhatikan bahwa kode di atas hanya akan berfungsi dengan baik jika Anda tidak main-main dengan android:versionCodeAndroidManifest.xml Anda!

schnatterer
sumber
2
Tolong jelaskan bagaimana menggunakan metode ini. Di mana Anda menginisialisasi objek SharedPreferences?
Shajeel Afzal
1
tidak berhasil untuk saya - tutorial pertama saya selalu diluncurkan
pzo
1
kode ini jauh lebih lurus ke depan tanpa efek samping dari menyatakan konteks dan preferensi di tempat lain public AppStart checkAppStart(Context context, SharedPreferences sharedPreferences)adalah tanda tangan metode yang jauh lebih baik
Akan
2
Membuat inti pembaruan dari jawaban ini di sini gist.github.com/williscool/2a57bcd47a206e980eee Saya memiliki masalah dengan kode asli yang akan macet di loop penelusuran saya selamanya karena nomor versi tidak pernah dihitung ulang di checkAppStartblok pertama . jadi saya memutuskan untuk membagikan kode yang diperbarui dan melihat apakah ada yang memiliki saran tentangnya
Akankah
1
@Apakah terima kasih atas masukan Anda. Anda benar, kodenya bisa disederhanakan dan dibuat lebih kuat. Ketika saya pertama kali memposting jawabannya, saya mengekstrak kode dari skenario yang lebih kompleks , di mana saya ingin mengakses AppStartdari aktivitas yang berbeda. Jadi saya menempatkan logika dalam metode layanan terpisah. Itulah mengapa ada contextvariabel dan AppStartdisimpan dalam variabel statis untuk memfasilitasi panggilan metode idempoten.
schnatterer
4

Saya memecahkan untuk menentukan apakah aplikasi tersebut pertama kali Anda atau tidak, tergantung pada apakah itu pembaruan.

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

Hasil perhitungan:

  • 0: Jika ini pertama kalinya.
  • 1: Ini telah dimulai.
  • 2: Ini telah dimulai sekali, tetapi bukan versi itu, yaitu pembaruan.
Webserveis
sumber
3

Anda dapat menggunakan Android SharedPreferences .

Android SharedPreferences memungkinkan kita menyimpan data aplikasi primitif pribadi dalam bentuk key-value pair.

KODE

Buat kelas khusus 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;
    }

}

Sekarang Buka Aktivitas Anda & Inisialisasi .

 private     SharedPreference                sharedPreferenceObj; // Declare Global

Sekarang Panggil ini di bagian OnCreate

 sharedPreferenceObj=new SharedPreference(YourActivity.this);

Sekarang Memeriksa

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
 }
IntelliJ Amiya
sumber
2

Berikut beberapa kode untuk ini -

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

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

if (!exists) {
    doSomething();                                      
}
else {
    doSomethingElse();
}
Arunabh Das
sumber
1

Anda cukup memeriksa keberadaan file kosong, jika tidak ada, lalu jalankan kode Anda dan buat file.

misalnya

if(File.Exists("emptyfile"){
    //Your code here
    File.Create("emptyfile");
}
MechMK1
sumber
Saya berpikir untuk melakukan itu tetapi berpikir pasti ada cara yang lebih baik
Boardy
Saya tidak tahu apa-apa, tapi apa kekurangan sumber daya yang Anda terima dengan itu? 4 byte untuk file dan satu "jika" di awal. Sistem-rutinitas akan melakukan hal yang sama, mereka akan melakukan hal yang persis sama atau membuat tabel dengan aplikasi yang telah
diluncurkan
Dengan cara yang sama Anda dapat menggunakan sharedpreferences, yang jika tidak ada, Anda akan menampilkan splash screen dll ... dan hanya membuatnya saat program pertama kali dijalankan (obv setelah memeriksanya). Lihat jawaban Kevin di atas
stealthcopter
1

Saya membuat kelas sederhana untuk memeriksa apakah kode Anda berjalan untuk pertama kalinya / n-kali!

Contoh

Buat preferensi unik

FirstTimePreference prefFirstTime = new FirstTimePreference(getApplicationContext());

Gunakan runTheFirstTime, pilih kunci untuk memeriksa acara Anda

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

Gunakan runTheFirstNTimes, pilih kunci dan berapa kali dieksekusi

if(prefFirstTime.runTheFirstNTimes("anotherKey" , 5)) {
    Toast.makeText(this, "ciccia Test coutdown: "+ prefFirstTime.getCountDown("anotherKey"),
                   Toast.LENGTH_LONG).show();
}
  • Gunakan getCountDown () untuk menangani kode Anda dengan lebih baik

FirstTimePreference.java

Alu84
sumber
1

Hanya ada dukungan untuk ini di revisi pustaka dukungan 23.3.0 (di v4 yang berarti kompatibilitas kembali ke Android 1.6).

Dalam aktivitas Launcher Anda, panggilan pertama:

AppLaunchChecker.onActivityCreate(activity);

Kemudian hubungi:

AppLaunchChecker.hasStartedFromLauncher(activity);

Yang akan ditampilkan jika ini pertama kali aplikasi diluncurkan.

Lucas Arrefelt
sumber
Urutan panggilan ini harus dibalik, setelah AppLaunchChecker.onActivityCreate () dipanggil, AppLaunchChecker.hasStartedFromLauncher () akan menampilkan true.
Gary Kipnis
Ini cukup menyesatkan. Tidak disebutkan apakah aplikasi "pernah diluncurkan"; melainkan, menyatakan apakah aplikasi "pernah diluncurkan oleh pengguna dari peluncur". Jadi, ada kemungkinan aplikasi atau tautan dalam lain mungkin telah meluncurkan aplikasi.
Farid
1

Jika Anda mencari cara sederhana, ini dia.

Buat kelas utilitas seperti ini,

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

}

Di Aktivitas Utama Anda, onCreate ()

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

untuk kotlin

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

}
K.Hayoev
sumber
Terima kasih banyak telah memberikan jawaban di Kotlin
MMG
0

Mengapa tidak menggunakan Pembantu Database? Ini akan memiliki onCreate bagus yang hanya dipanggil saat pertama kali aplikasi dimulai. Ini akan membantu orang-orang yang ingin melacak ini setelah ada aplikasi awal diinstal tanpa pelacakan.

slott
sumber
Apakah itu membuat database? Bagaimana cara menggunakan DatabaseHelper tanpa membuat database yang sebenarnya? Dan saya pikir, onCreate()dipanggil untuk setiap versi baru. Juga, bukankah itu akan dianggap berlebihan atau menggunakan sesuatu untuk tujuan yang tidak diinginkan?
ADTC
onCreate hanya dipicu saat aplikasi diinstal pertama kali. Saat versi db bertambah, onUpdated dipicu.
slott
Yah berlebihan adalah kata yang kasar :) - Jika Anda memiliki opsi yaitu. aplikasi Anda belum tayang, lalu siapkan flag SharedPrefs dan gunakan itu untuk menentukan apakah itu booting pertama atau tidak. Saya memiliki kasus di mana aplikasi telah berada di alam liar selama beberapa waktu dan kami menggunakan DB sehingga onCreate sangat cocok untuk saya.
slott
0

Saya ingin memiliki "jumlah pembaruan" dalam preferensi bersama saya. Jika tidak ada (atau nilai nol default) maka ini adalah "penggunaan pertama" aplikasi saya.

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

Jadi sekarang, setiap kali ada pembaruan pada aplikasi yang harus diketahui pengguna, saya menaikkan UPDATE_COUNT

Edward Falk
sumber
-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);
AZ_
sumber
-2

Hai teman-teman, saya melakukan sesuatu seperti ini. Dan itu berhasil untuk saya

buat bidang Boolean dalam preferensi bersama. Nilai default adalah true {isFirstTime: true} setelah pertama kali disetel ke false. Tidak ada yang sederhana dan dapat diandalkan selain ini di sistem android.

DropAndTrap
sumber
Uh, jangan melakukan hardcode pada jalur seperti itu! Jika Anda melakukannya, Context.getSharedPreferences()itu akan berakhir di tempat yang sama, kecuali itu akan berhasil di mana
Takhion
setuju dengan Anda :)
DropAndTrap