2011-01-08 27 views
86

Tôi hiện đang phát triển một ứng dụng Android. Tôi cần phải làm điều gì đó khi ứng dụng được khởi chạy lần đầu tiên, tức là mã chỉ chạy vào lần đầu tiên chương trình được khởi chạy.Xác định xem ứng dụng android có phải là lần đầu tiên sử dụng

+1

Khi tôi lần đầu tiên bắt đầu làm cho các ứng dụng, tôi chỉ nghĩ về thời gian đầu tiên sau khi một ứng dụng được cài đặt. Sau đó tôi nhận ra rằng tôi cũng cần phải xử lý và phân biệt lần chạy đầu tiên sau khi nâng cấp. @ schnatterer của câu trả lời dưới đây và câu trả lời của tôi [ở đây] (http://stackoverflow.com/a/30274315/3681880) cho thấy làm thế nào để làm điều này. Hãy thận trọng với các câu trả lời không tính đến nâng cấp. – Suragch

+0

@Suragch bạn đang hành động như nó là thực tế xấu để không nâng cấp vào tài khoản nhưng trong một số trường hợp như có một giới thiệu ứng dụng bạn KHÔNG muốn làm điều đó :) – creativecreatorormaybenot

+0

@creativecreatorormaybenot, đó là sự thật. Có những lúc bạn chỉ quan tâm đến việc cài đặt ban đầu và không phải nâng cấp tiếp theo. Một boolean đơn giản là đủ cho những tình huống đó. Tuy nhiên, điều gì sẽ xảy ra nếu bạn muốn thêm một giới thiệu khác cho người dùng hiện tại về tất cả các tính năng mới mà bạn vừa thêm vào bản cập nhật gần đây nhất vào một thời điểm nào đó? Theo ý kiến ​​của tôi nó là xa-sighted để kiểm tra số phiên bản chứ không phải là một boolean. Điều này ít nhất cung cấp cho bạn tùy chọn trong tương lai để trả lời một cách cho một cài đặt mới và một cách khác để nâng cấp. – Suragch

Trả lời

42

Một ý tưởng khác là sử dụng cài đặt trong Tùy chọn được chia sẻ. ý tưởng chung giống như kiểm tra một tập tin rỗng, nhưng sau đó bạn không có một tập tin rỗng nổi xung quanh, không được sử dụng để lưu trữ bất cứ điều gì

+2

hãy cẩn thận rằng loại phương pháp này không thể hoạt động trên Samsung Galaxy S với Android Froyo. Đó là vì một lỗi trong SharedPreferences tiết kiệm. Đây là liên kết đến câu hỏi SO trên đó: http://stackoverflow.com/questions/7296163/cant-save-my-preferences-after-app-killed và đây là vé trên mã google: http://code.google .com/p/android/issues/detail? id = 14359 –

+2

Hãy coi chừng cho Android 6.0 (API 23 - Marshmallow) trở lên tự động sao lưu (https://developer.android.com/guide/topics/data/autobackup.html) được bật theo mặc định. Nếu người dùng gỡ cài đặt và sau đó cài đặt lại ứng dụng, tùy chọn được chia sẻ sẽ được khôi phục. Vì vậy, khi cài đặt lại, bạn không thể kiểm tra xem nó có đang chạy lần đầu tiên sau khi cài đặt lại hay không nếu điều này là do bất kỳ mối quan tâm nào. – Alan

+1

@Alan bạn nói đúng, câu trả lời này là ** không còn hợp lệ ** từ Android Marshmallow nữa. –

1

Bạn có thể chỉ cần kiểm tra sự tồn tại của một tệp trống, nếu nó không tồn tại, sau đó thực thi mã của bạn và tạo tệp.

ví dụ:

if(File.Exists("emptyfile"){ 
    //Your code here 
    File.Create("emptyfile"); 
} 
+0

Tôi đã suy nghĩ để làm điều đó nhưng nghĩ rằng phải có một cách tốt hơn – Boardy

+0

Tôi không biết bất kỳ, nhưng thiếu tài nguyên bạn nhận được bằng cách đó là gì? 4 byte cho tệp và một "nếu" ở đầu. Các thói quen hệ thống sẽ thực hiện tương tự, chúng sẽ thực hiện chính xác như vậy hoặc tạo một bảng với các ứng dụng đã được xoá đi –

+0

Theo cách tương tự, bạn có thể sử dụng sharedpreferences, nếu nó không tồn tại. màn hình vv ... và chỉ cần tạo nó khi chương trình lần đầu tiên chạy (obv sau khi kiểm tra cho nó). Xem câu trả lời của Kevin trên – stealthcopter

2

Dưới đây là một số mã cho điều này -

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

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

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

Bạn có thể sử dụng SharedPreferences để xác định xem đó có phải là "Lần đầu tiên" ứng dụng được khởi chạy hay không. Chỉ cần sử dụng Biến Boolean ("my_first_time") và thay đổi giá trị thành false khi nhiệm vụ của bạn "lần đầu" kết thúc.

Đây là mã của tôi để bắt lần đầu tiên bạn mở ứng dụng:

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

Nó sẽ xử lý khi ứng dụng sẽ được cập nhật lên phiên bản tiếp theo trên cửa hàng google play? –

+2

SharedPreferences được duy trì trong quá trình nâng cấp. Vì vậy, tôi giả định rằng khi nó được nâng cấp từ PlayStore, giá trị cũ có sẵn. Trong thực tế, nó được áp dụng cho các phương pháp khác, tức là kiểm tra sự tồn tại của tập tin. Vì vậy, phương pháp phím tắt trong trường hợp đó là sử dụng tên/giá trị tệp hoặc tùy chọn khác nhau. –

+0

@ShajeelAfzal một số điều như thế này có thể giúp bạn khoảng trống công cộng CheckAndInitAppFirstTime() { Chuỗi cuối cùng PREFS_NAME = "TheAppVer"; Chuỗi cuối cùng CHECK_VERSION = "1"; // Yêu cầu ver ... Chuỗi cuối cùng KEY_NAME = "Kiểm tra"; SharedPreferences settings = getSharedPreferences (PREFS_NAME, 0); nếu (! Settings.getString (KEY_NAME, "0"). Bằng (CHECK_VERSION)) { // ứng dụng đang được khởi chạy lần đầu tiên, hãy làm điều gì đó hoặc CHECK_VERSION là khác nhau // ... settings.edit () .putString (KEY_NAME, CHECK_VERSION) .commit(); } } –

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

Tôi đề nghị để không chỉ lưu trữ một lá cờ boolean, nhưng mã phiên bản đầy đủ. Bằng cách này, bạn cũng có thể truy vấn ngay từ đầu nếu đó là lần bắt đầu đầu tiên trong phiên bản mới. Bạn có thể sử dụng thông tin này để hiển thị hộp thoại "Có gì mới".

Mã sau sẽ hoạt động từ bất kỳ lớp học android nào "là ngữ cảnh" (hoạt động, dịch vụ, ...). Nếu bạn muốn có nó trong một lớp riêng biệt (POJO), bạn có thể xem xét sử dụng một "bối cảnh tĩnh", như được mô tả here ví dụ.

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

Nó có thể được sử dụng từ một hoạt động như thế này:

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

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

Logic cơ bản có thể được xác nhận sử dụng thử nghiệm JUnit này:

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

Với một nỗ lực chút bạn có thể có thể kiểm tra các công cụ liên quan đến Android (PackageManager và SharedPreferences). Bất cứ ai quan tâm đến việc viết bài kiểm tra? :)

Lưu ý rằng mã trên sẽ chỉ hoạt động bình thường nếu bạn không gây rối với android:versionCode trong AndroidManifest.xml!

+2

Vui lòng giải thích cách sử dụng phương pháp này. Bạn đang khởi tạo đối tượng SharedPreferences ở đâu? –

+0

Tôi mở rộng câu trả lời một chút. Cách dễ nhất để sử dụng nó là chỉ cần dán đoạn mã vào một hoạt động và gọi 'checkAppStart() ' – schnatterer

+1

không hoạt động cho tôi - nó luôn khởi chạy hướng dẫn thời gian đầu tiên của tôi – pzo

1

Tôi đã thực hiện một lớp đơn giản để kiểm tra xem mã của bạn có đang chạy lần đầu tiên/lần không!

Ví dụ

Tạo một sở thích độc đáo

FirstTimePreference prefFirstTime = new FirstTimePreference(getApplicationContext()); 

Sử dụng runTheFirstTime, chọn một chìa khóa để kiểm tra sự kiện của bạn

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

Sử dụng runTheFirstNTimes, chọn một chìa khóa và bao nhiêu lần thực hiện

if(prefFirstTime.runTheFirstNTimes("anotherKey" , 5)) { 
    Toast.makeText(this, "ciccia Test coutdown: "+ prefFirstTime.getCountDown("anotherKey"), 
        Toast.LENGTH_LONG).show(); 
} 
  • Sử dụng getCountDown() để xử lý tốt hơn mã của bạn

FirstTimePreference.java

-1

Hi guys Tôi đang làm một cái gì đó như thế này. Và các công trình của nó cho tôi

tạo trường Boolean trong tùy chọn chia sẻ. Giá trị mặc định là đúng {isFirstTime: true} sau lần đầu tiên đặt thành false. Không có gì có thể đơn giản và đáng tin cậy hơn điều này trong hệ thống Android.

+0

Uh, đừng mã hóa đường dẫn như thế! Nếu bạn chỉ đơn giản là 'Context.getSharedPreferences()' nó sẽ kết thúc ở cùng một vị trí, ngoại trừ nó sẽ làm việc ở mọi nơi – Takhion

+0

đồng ý với bạn :) – DropAndTrap

0

Tại sao không sử dụng Trình trợ giúp cơ sở dữ liệu? Điều này sẽ có một onCreate tốt đẹp mà chỉ được gọi là lần đầu tiên ứng dụng được bắt đầu. Điều này sẽ giúp những người muốn theo dõi điều này sau khi ứng dụng ban đầu đã được cài đặt mà không cần theo dõi.

+0

Điều đó có tạo ra một cơ sở dữ liệu không? Làm thế nào để sử dụng DatabaseHelper mà không cần tạo một cơ sở dữ liệu thực tế? Và tôi nghĩ, 'onCreate()' được gọi cho mọi phiên bản mới. Ngoài ra, nó sẽ không được coi là thừa hoặc sử dụng một cái gì đó cho một mục đích không mong muốn? – ADTC

+0

onCreate chỉ được kích hoạt khi ứng dụng được cài đặt lần đầu tiên. Khi phiên bản db được tăng lên, onUpdated được kích hoạt. – slott

+0

OK, cảm ơn. Còn các câu hỏi khác thì sao? :) – ADTC

0

Tôi muốn có "số lượng cập nhật" trong tùy chọn được chia sẻ của mình. Nếu nó không có (hoặc giá trị zero mặc định) thì đây là "sử dụng đầu tiên" của ứng dụng của tôi.

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

Vì vậy, bây giờ, bất cứ khi nào có một cập nhật cho các ứng dụng mà người dùng nên biết về, tôi tăng UPDATE_COUNT

1

tôi giải quyết để xác định xem ứng dụng là lần đầu tiên của bạn hay không, tùy thuộc vào việc nó là một cập nhật.

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

kết quả Tính:

  • 0: Nếu đây là lần đầu tiên.
  • 1: Đã bắt đầu từ trước đến nay.
  • 2: Nó đã bắt đầu một lần, nhưng không phải là phiên bản đó, tức là nó là bản cập nhật.
1

Chỉ hỗ trợ cho điều này trong bản sửa đổi thư viện hỗ trợ 23.3.0 (trong v4 nghĩa là khả năng tương thích trở lại Android 1.6).

Trong hoạt động Launcher bạn, trước tiên gọi:

AppLaunchChecker.onActivityCreate(activity); 

Sau đó gọi:

AppLaunchChecker.hasStartedFromLauncher(activity); 

nào sẽ trở lại nếu đây là lần đầu tiên ứng dụng đã được đưa ra.

+0

Thứ tự của các cuộc gọi này phải được đảo ngược, sau khi AppLaunchChecker.onActivityCreate() được gọi, AppLaunchChecker.hasStartedFromLauncher() sẽ trả về true. –

2

Bạn có thể sử dụng Android SharedPreferences.

Android SharedPreferences cho phép chúng tôi lưu trữ dữ liệu nguyên thủy riêng dưới dạng cặp khóa-giá trị.

Tạo một lớp tùy chỉnh 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.commit(); 
    } 

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

} 

Bây giờ Mở của bạn Hoạt động & Initialize.

private  SharedPreference    sharedPreferenceObj; // Declare Global 

Bây giờ Gọi này trong OnCreate phần

sharedPreferenceObj=new SharedPreference(YourActivity.this); 

Bây giờ kiểm tra

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

@InteliJAmia. bạn vui lòng trả lời câu hỏi của tôi không? https://stackoverflow.com/q/48300734/4568864 –

Các vấn đề liên quan