Hỗ trợ cập nhật trong ứng dụng (Kotlin hoặc Java)

Bài viết này hướng dẫn cách hỗ trợ cập nhật trong ứng dụng bằng Kotlin hoặc Java. Bên cạnh đó, cũng có hướng dẫn riêng cho các trường hợp trong đó quá trình triển khai sử dụng mã gốc (C/C++) và các trường hợp quá trình triển khai sử dụng Unity.

Thiết lập môi trường phát triển

Thư viện cập nhật trong ứng dụng Play là một phần của Thư viện Google Play Core. Vui lòng gắn phần phụ thuộc Gradle sau đây để tích hợp vào Thư viện cập nhật trong ứng dụng của Play.

Groovy

// In your app’s build.gradle file:
...
dependencies {
    // This dependency is downloaded from the Google’s Maven repository.
    // So, make sure you also include that repository in your project's build.gradle file.
    implementation 'com.google.android.play:app-update:2.1.0'

    // For Kotlin users also add the Kotlin extensions library for Play In-App Update:
    implementation 'com.google.android.play:app-update-ktx:2.1.0'
    ...
}

Kotlin

// In your app’s build.gradle.kts file:
...
dependencies {
    // This dependency is downloaded from the Google’s Maven repository.
    // So, make sure you also include that repository in your project's build.gradle file.
    implementation("com.google.android.play:app-update:2.1.0")

    // For Kotlin users also import the Kotlin extensions library for Play In-App Update:
    implementation("com.google.android.play:app-update-ktx:2.1.0")
    ...
}

Kiểm tra xem có bản cập nhật mới chưa

Trước khi yêu cầu cập nhật, hãy kiểm tra xem có bản cập nhật cho ứng dụng của bạn hay không. Sử dụng AppUpdateManager để kiểm tra bản cập nhật:

Kotlin

val appUpdateManager = AppUpdateManagerFactory.create(context)

// Returns an intent object that you use to check for an update.
val appUpdateInfoTask = appUpdateManager.appUpdateInfo

// Checks that the platform will allow the specified type of update.
appUpdateInfoTask.addOnSuccessListener { appUpdateInfo ->
    if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
        // This example applies an immediate update. To apply a flexible update
        // instead, pass in AppUpdateType.FLEXIBLE
        && appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)
    ) {
        // Request the update.
    }
}

Java

AppUpdateManager appUpdateManager = AppUpdateManagerFactory.create(context);

// Returns an intent object that you use to check for an update.
Task<AppUpdateInfo> appUpdateInfoTask = appUpdateManager.getAppUpdateInfo();

// Checks that the platform will allow the specified type of update.
appUpdateInfoTask.addOnSuccessListener(appUpdateInfo -> {
    if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
          // This example applies an immediate update. To apply a flexible update
          // instead, pass in AppUpdateType.FLEXIBLE
          && appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)) {
              // Request the update.
    }
});

Thực thể AppUpdateInfo được trả về chứa trạng thái sẵn sàng của bản cập nhật. Tuỳ thuộc vào trạng thái của bản cập nhật, thực thể cũng chứa các nội dung sau:

  • Nếu có bản cập nhật và cho phép cập nhật, thực thể này cũng chứa ý định để bắt đầu quá trình cập nhật.
  • Nếu đang cập nhật ứng dụng, thực thể đó cũng sẽ báo cáo trạng thái tiến trình cập nhật.

Kiểm tra tình trạng lỗi thời của bản cập nhật

Ngoài việc kiểm tra xem có bản cập nhật hay không, bạn cũng nên kiểm tra xem đã bao lâu kể từ lần gần nhất người dùng được Cửa hàng Play thông báo về bản cập nhật. Điều này có thể giúp bạn quyết định xem nên tiến hành cập nhật linh hoạt hay cập nhật tức thì. Ví dụ: có thể chờ một vài ngày trước khi thông báo cho người dùng về bản cập nhật linh hoạt và vài ngày sau đó mới yêu cầu cập nhật tức thì.

Sử dụng clientVersionStalenessDays() để kiểm tra số ngày kể từ khi Cửa hàng Play có bản cập nhật:

Kotlin

val appUpdateManager = AppUpdateManagerFactory.create(context)

// Returns an intent object that you use to check for an update.
val appUpdateInfoTask = appUpdateManager.appUpdateInfo

// Checks whether the platform allows the specified type of update,
// and current version staleness.
appUpdateInfoTask.addOnSuccessListener { appUpdateInfo ->
    if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
          && (appUpdateInfo.clientVersionStalenessDays() ?: -1) >= DAYS_FOR_FLEXIBLE_UPDATE
          && appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)) {
              // Request the update.
    }
}

Java

AppUpdateManager appUpdateManager = AppUpdateManagerFactory.create(context);

// Returns an intent object that you use to check for an update.
Task<AppUpdateInfo> appUpdateInfoTask = appUpdateManager.getAppUpdateInfo();

// Checks whether the platform allows the specified type of update,
// and current version staleness.
appUpdateInfoTask.addOnSuccessListener(appUpdateInfo -> {
    if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
          && appUpdateInfo.clientVersionStalenessDays() != null
          && appUpdateInfo.clientVersionStalenessDays() >= DAYS_FOR_FLEXIBLE_UPDATE
          && appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)) {
              // Request the update.
    }
});

Kiểm tra mức độ ưu tiên của bản cập nhật

API Nhà phát triển Google Play cho phép bạn thiết lập mức độ ưu tiên của mỗi bản cập nhật. Điều này cho phép ứng dụng của bạn quyết định mức độ đề xuất bản cập nhật cho người dùng. Ví dụ: nên cân nhắc chiến lược sau đây về việc đặt mức độ ưu tiên cho bản cập nhật:

  • Cải tiến nhỏ về giao diện người dùng: Bản cập nhật có mức độ ưu tiên thấp; không yêu cầu cập nhật linh hoạt cũng như cập nhật tức thì. Chỉ cập nhật khi người dùng không tương tác với ứng dụng.
  • Cải thiện hiệu suất: Cập nhật có mức độ ưu tiên trung bình; yêu cầu cập nhật linh hoạt.
  • Cập nhật bảo mật quan trọng: Cập nhật có mức độ ưu tiên cao; yêu cầu cập nhật ngay.

Để xác định mức độ ưu tiên, Google Play sử dụng giá trị số nguyên từ 0 đến 5, trong đó 0 là giá trị mặc định và 5 là mức độ ưu tiên cao nhất. Để thiết lập mức độ ưu tiên cho một bản cập nhật, hãy sử dụng trường inAppUpdatePriority trong Edits.tracks.releases của API Nhà phát triển Google Play. Tất cả các phiên bản mới thêm vào trong bản phát hành đều có mức độ ưu tiên tương tự với bản phát hành đó. Chỉ có thể thiết lập mức độ ưu tiên vào thời điểm ra mắt bản phát hành mới và sau đó bạn không thay đổi được mức độ ưu tiên này.

Đặt mức độ ưu tiên bằng cách sử dụng API Nhà phát triển Google Play như mô tả trong tài liệu về API Nhà phát triển Play. Mức độ ưu tiên của bản cập nhật trong ứng dụng phải được chỉ định trong tài nguyên Edit.tracks được truyền trong phương thức Edit.tracks: update. Ví dụ sau minh hoạ việc phát hành ứng dụng có mã phiên bản 88 và inAppUpdatePriority 5:

{
  "releases": [{
      "versionCodes": ["88"],
      "inAppUpdatePriority": 5,
      "status": "completed"
  }]
}

Trong mã của ứng dụng, bạn có thể kiểm tra mức độ ưu tiên của một bản cập nhật cụ thể bằng cách sử dụng updatePriority(). Mức độ ưu tiên được trả về có tính đến inAppUpdatePriority của mọi mã phiên bản ứng dụng trong khoảng thời gian từ khi cài đặt phiên bản đến khi có phiên bản mới nhất, bất kể kênh phát hành. Ví dụ: xem xét những tình huống sau:

  • Bạn phát hành phiên bản 1 trên một kênh phát hành công khai không có mức độ ưu tiên.
  • Bạn phát hành phiên bản 2 trên một kênh kiểm thử nội bộ có mức độ ưu tiên 5.
  • Bạn phát hành phiên bản 3 trên một kênh phát hành công khai không có mức độ ưu tiên.

Khi người dùng phiên bản chính thức cập nhật từ phiên bản 1 lên phiên bản 3, họ sẽ nhận được mức độ ưu tiên 5, ngay cả khi phiên bản 2 được phát hành trên một kênh khác.

Kotlin

val appUpdateManager = AppUpdateManagerFactory.create(context)

// Returns an intent object that you use to check for an update.
val appUpdateInfoTask = appUpdateManager.appUpdateInfo

// Checks whether the platform allows the specified type of update,
// and checks the update priority.
appUpdateInfoTask.addOnSuccessListener { appUpdateInfo ->
    if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
          && appUpdateInfo.updatePriority() >= 4 /* high priority */
          && appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)) {
              // Request an immediate update.
    }
}

Java

AppUpdateManager appUpdateManager = AppUpdateManagerFactory.create(context);

// Returns an intent object that you use to check for an update.
Task<AppUpdateInfo> appUpdateInfoTask = appUpdateManager.getAppUpdateInfo();

// Checks whether the platform allows the specified type of update,
// and checks the update priority.
appUpdateInfoTask.addOnSuccessListener(appUpdateInfo -> {
    if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
          && appUpdateInfo.updatePriority() >= 4 /* high priority */
          && appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)) {
              // Request an immediate update.
    }
});

Bắt đầu cập nhật

Sau khi xác nhận đã có bản cập nhật mới, bạn có thể yêu cầu cập nhật bằng AppUpdateManager.startUpdateFlowForResult():

Kotlin

appUpdateManager.startUpdateFlowForResult(
    // Pass the intent that is returned by 'getAppUpdateInfo()'.
    appUpdateInfo,
    // an activity result launcher registered via registerForActivityResult
    activityResultLauncher,
    // Or pass 'AppUpdateType.FLEXIBLE' to newBuilder() for
    // flexible updates.
    AppUpdateOptions.newBuilder(AppUpdateType.IMMEDIATE).build())

Java

appUpdateManager.startUpdateFlowForResult(
    // Pass the intent that is returned by 'getAppUpdateInfo()'.
    appUpdateInfo,
    // an activity result launcher registered via registerForActivityResult
    activityResultLauncher,
    // Or pass 'AppUpdateType.FLEXIBLE' to newBuilder() for
    // flexible updates.
    AppUpdateOptions.newBuilder(AppUpdateType.IMMEDIATE).build());

Mỗi thực thể AppUpdateInfo chỉ có thể được sử dụng một lần để bắt đầu cập nhật. Để thử cập nhật lại trong trường hợp không thành công, hãy yêu cầu AppUpdateInfo mới và kiểm tra lại xem đã có bản cập nhật hay chưa và có được phép cập nhật hay không.

Bạn có thể đăng ký trình chạy kết quả hoạt động bằng cách sử dụng hợp đồng ActivityResultContracts.StartIntentSenderForResult tích hợp. Hãy xem mục này trong phần nhận lệnh gọi lại để biết trạng thái cập nhật.

Các bước tiếp theo phụ thuộc vào việc bạn yêu cầu cập nhật linh hoạt hay cập nhật tức thì.

Định cấu hình cập nhật bằng AppUpdateOptions

AppUpdateOptions chứa một trường AllowAssetPackDeletion xác định liệu bản cập nhật có được phép xoá gói tài sản hay không trong trường hợp thiết bị bị giới hạn bộ nhớ. Theo mặc định, trường này được đặt thành false, nhưng bạn có thể sử dụng phương thức setAllowAssetPackDeletion() để đặt thành true:

Kotlin

appUpdateManager.startUpdateFlowForResult(
    // Pass the intent that is returned by 'getAppUpdateInfo()'.
    appUpdateInfo,
    // an activity result launcher registered via registerForActivityResult
    activityResultLauncher,
    // Or pass 'AppUpdateType.FLEXIBLE' to newBuilder() for
    // flexible updates.
    AppUpdateOptions.newBuilder(AppUpdateType.IMMEDIATE)
        .setAllowAssetPackDeletion(true)
        .build())

Java

appUpdateManager.startUpdateFlowForResult(
    // Pass the intent that is returned by 'getAppUpdateInfo()'.
    appUpdateInfo,
    // an activity result launcher registered via registerForActivityResult
    activityResultLauncher,
    // Or pass 'AppUpdateType.FLEXIBLE' to newBuilder() for
    // flexible updates.
    AppUpdateOptions.newBuilder(AppUpdateType.IMMEDIATE)
        .setAllowAssetPackDeletion(true)
        .build());

Nhận lệnh gọi lại để biết trạng thái cập nhật

Sau khi bắt đầu cập nhật, lệnh gọi lại trình chạy kết quả hoạt động đã đăng ký sẽ nhận được kết quả hộp thoại xác nhận:

Kotlin

registerForActivityResult(StartIntentSenderForResult()) { result: ActivityResult ->
    // handle callback
    if (result.resultCode != RESULT_OK) {
        log("Update flow failed! Result code: " + result.resultCode);
        // If the update is canceled or fails,
        // you can request to start the update again.
    }
}

Java

registerForActivityResult(
    new ActivityResultContracts.StartIntentSenderForResult(),
    new ActivityResultCallback<ActivityResult>() {
        @Override
        public void onActivityResult(ActivityResult result) {
            // handle callback
            if (result.getResultCode() != RESULT_OK) {
                log("Update flow failed! Result code: " + result.getResultCode());
                // If the update is canceled or fails,
                // you can request to start the update again.
            }
        }
    });

Bạn có thể nhận được một số giá trị khi thực hiện lệnh gọi lại onActivityResult():

  • RESULT_OK: Người dùng đã chấp nhận bản cập nhật. Đối với các bản cập nhật tức thì, bạn có thể không nhận được lệnh gọi lại này vì quá trình cập nhật đã hoàn tất trước khi ứng dụng có thể kiểm soát trở lại.
  • RESULT_CANCELED: Người dùng từ chối hoặc huỷ cập nhật.
  • ActivityResult.RESULT_IN_APP_UPDATE_FAILED: Một số lỗi khác ngăn người dùng đồng ý hoặc cập nhật.

Xử lý bản cập nhật linh hoạt

Khi bạn bắt đầu chạy bản cập nhật linh hoạt, một hộp thoại sẽ xuất hiện đầu tiên để yêu cầu người dùng đồng ý cập nhật. Nếu người dùng đồng ý, thì quá trình tải xuống sẽ bắt đầu trong nền và người dùng có thể tiếp tục tương tác với ứng dụng. Phần dưới đây mô tả cách theo dõi và hoàn tất quá trình cập nhật linh hoạt trong ứng dụng.

Theo dõi trạng thái cập nhật linh hoạt

Sau khi quá trình tải xuống bản cập nhật linh hoạt bắt đầu, ứng dụng cần theo dõi trạng thái cập nhật để biết khi nào có thể cài đặt bản cập nhật và hiển thị tiến trình thực hiện trong giao diện người dùng của ứng dụng.

Bạn có thể theo dõi trạng thái tiến trình cập nhật bằng cách đăng ký trình nghe để cập nhật trạng thái cài đặt. Bạn cũng có thể cung cấp thanh tiến trình trong giao diện người dùng của ứng dụng để người dùng nắm bắt tiến trình tải xuống.

Kotlin

// Create a listener to track request state updates.
val listener = InstallStateUpdatedListener { state ->
    // (Optional) Provide a download progress bar.
    if (state.installStatus() == InstallStatus.DOWNLOADING) {
      val bytesDownloaded = state.bytesDownloaded()
      val totalBytesToDownload = state.totalBytesToDownload()
      // Show update progress bar.
    }
    // Log state or install the update.
}

// Before starting an update, register a listener for updates.
appUpdateManager.registerListener(listener)

// Start an update.

// When status updates are no longer needed, unregister the listener.
appUpdateManager.unregisterListener(listener)

Java

// Create a listener to track request state updates.
InstallStateUpdatedListener listener = state -> {
  // (Optional) Provide a download progress bar.
  if (state.installStatus() == InstallStatus.DOWNLOADING) {
      long bytesDownloaded = state.bytesDownloaded();
      long totalBytesToDownload = state.totalBytesToDownload();
      // Implement progress bar.
  }
  // Log state or install the update.
};

// Before starting an update, register a listener for updates.
appUpdateManager.registerListener(listener);

// Start an update.

// When status updates are no longer needed, unregister the listener.
appUpdateManager.unregisterListener(listener);

Cài đặt bản cập nhật linh hoạt

Khi phát hiện trạng thái InstallStatus.DOWNLOADED, bạn cần khởi động lại ứng dụng để cài đặt bản cập nhật.

Khác với các bản cập nhật tức thì, Google Play không tự động kích hoạt quá trình khởi động lại ứng dụng đối với bản cập nhật linh hoạt. Nguyên nhân là do trong quá trình cập nhật linh hoạt, người dùng vẫn muốn tiếp tục tương tác với ứng dụng cho đến khi họ quyết định cài đặt bản cập nhật.

Bạn nên gửi thông báo (hoặc một chỉ báo khác trên giao diện người dùng) để báo cho người dùng biết rằng bản cập nhật đã sẵn sàng cài đặt và yêu cầu xác nhận trước khi khởi động lại ứng dụng.

Ví dụ sau minh hoạ cách triển khai thanh thông báo nhanh trong Material Design, thông báo này yêu cầu người dùng xác nhận để khởi động lại ứng dụng:

Kotlin

val listener = { state ->
    if (state.installStatus() == InstallStatus.DOWNLOADED) {
        // After the update is downloaded, show a notification
        // and request user confirmation to restart the app.
        popupSnackbarForCompleteUpdate()
    }
    ...
}

// Displays the snackbar notification and call to action.
fun popupSnackbarForCompleteUpdate() {
    Snackbar.make(
        findViewById(R.id.activity_main_layout),
        "An update has just been downloaded.",
        Snackbar.LENGTH_INDEFINITE
    ).apply {
        setAction("RESTART") { appUpdateManager.completeUpdate() }
        setActionTextColor(resources.getColor(R.color.snackbar_action_text_color))
        show()
    }
}

Java

InstallStateUpdatedListener listener = state -> {
    if (state.installStatus() == InstallStatus.DOWNLOADED) {
        // After the update is downloaded, show a notification
        // and request user confirmation to restart the app.
        popupSnackbarForCompleteUpdate();
    }
    ...
};

// Displays the snackbar notification and call to action.
private void popupSnackbarForCompleteUpdate() {
  Snackbar snackbar =
      Snackbar.make(
          findViewById(R.id.activity_main_layout),
          "An update has just been downloaded.",
          Snackbar.LENGTH_INDEFINITE);
  snackbar.setAction("RESTART", view -> appUpdateManager.completeUpdate());
  snackbar.setActionTextColor(
      getResources().getColor(R.color.snackbar_action_text_color));
  snackbar.show();
}

Khi gọi appUpdateManager.completeUpdate() ở nền trước, nền tảng sẽ hiển thị giao diện người dùng toàn màn hình và sẽ tiến hành khởi động lại ứng dụng trong nền. Sau khi nền tảng hoàn tất cài đặt bản cập nhật, ứng dụng sẽ khởi động lại và trở thành hoạt động chính của nền tảng.

Thay vào đó, nếu gọi completeUpdate() khi ứng dụng ở chế độ nền, thì bản cập nhật sẽ được tự động cài đặt mà không che khuất giao diện người dùng của thiết bị.

Bất cứ khi nào người dùng đưa ứng dụng của bạn lên nền trước, hãy kiểm tra xem ứng dụng có bản cập nhật đang chờ cài đặt hay không. Nếu ứng dụng có bản cập nhật ở trạng thái DOWNLOADED, hãy nhắc người dùng cài đặt bản cập nhật. Nếu không, dữ liệu cập nhật sẽ tiếp tục chiếm dung lượng lưu trữ trên thiết bị của người dùng.

Kotlin

// Checks that the update is not stalled during 'onResume()'.
// However, you should execute this check at all app entry points.
override fun onResume() {
    super.onResume()

    appUpdateManager
        .appUpdateInfo
        .addOnSuccessListener { appUpdateInfo ->
            ...
            // If the update is downloaded but not installed,
            // notify the user to complete the update.
            if (appUpdateInfo.installStatus() == InstallStatus.DOWNLOADED) {
                popupSnackbarForCompleteUpdate()
            }
        }
}

Java

// Checks that the update is not stalled during 'onResume()'.
// However, you should execute this check at all app entry points.
@Override
protected void onResume() {
  super.onResume();

  appUpdateManager
      .getAppUpdateInfo()
      .addOnSuccessListener(appUpdateInfo -> {
              ...
              // If the update is downloaded but not installed,
              // notify the user to complete the update.
              if (appUpdateInfo.installStatus() == InstallStatus.DOWNLOADED) {
                  popupSnackbarForCompleteUpdate();
              }
          });
}

Xử lý bản cập nhật tức thì

Khi bắt đầu cập nhật tức thì và người dùng đồng ý bắt đầu cập nhật, Google Play sẽ cho thấy tiến trình cập nhật ở bên trên giao diện người dùng của ứng dụng trong toàn bộ thời gian cập nhật. Nếu người dùng đóng hoặc dừng ứng dụng trong quá trình cập nhật, bản cập nhật sẽ tiếp tục tải xuống và cài đặt trong nền mà không cần người dùng xác nhận bổ sung.

Tuy nhiên, khi ứng dụng quay lại chế độ nền trước, bạn nên xác nhận rằng bản cập nhật không bị trì hoãn ở trạng thái UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS. Nếu quá trình cập nhật bị trì hoãn trong trạng thái này, hãy tiếp tục quá trình cập nhật:

Kotlin

// Checks that the update is not stalled during 'onResume()'.
// However, you should execute this check at all entry points into the app.
override fun onResume() {
    super.onResume()

    appUpdateManager
        .appUpdateInfo
        .addOnSuccessListener { appUpdateInfo ->
            ...
            if (appUpdateInfo.updateAvailability()
                == UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS
            ) {
                // If an in-app update is already running, resume the update.
                appUpdateManager.startUpdateFlowForResult(
                  appUpdateInfo,
                  activityResultLauncher,
                  AppUpdateOptions.newBuilder(AppUpdateType.IMMEDIATE).build())
            }
        }
}

Java

// Checks that the update is not stalled during 'onResume()'.
// However, you should execute this check at all entry points into the app.
@Override
protected void onResume() {
  super.onResume();

  appUpdateManager
      .getAppUpdateInfo()
      .addOnSuccessListener(
          appUpdateInfo -> {
            ...
            if (appUpdateInfo.updateAvailability()
                == UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS) {
                // If an in-app update is already running, resume the update.
                appUpdateManager.startUpdateFlowForResult(
                  appUpdateInfo,
                  activityResultLauncher,
                  AppUpdateOptions.newBuilder(AppUpdateType.IMMEDIATE).build());
            }
          });
}

Quá trình cập nhật sẽ trả về kết quả như được mô tả trong tài liệu tham khảo cho startUpdateFlowForResult(). Cụ thể, ứng dụng phải có thể xử lý các trường hợp mà người dùng từ chối cập nhật hoặc huỷ quá trình tải xuống. Khi người dùng thực hiện một trong những hành động này, giao diện người dùng của Google Play sẽ đóng lại. Ứng dụng lúc đó sẽ cần xác định cách tốt nhất để tiếp tục.

Nếu có thể, hãy cho phép người dùng tiếp tục mà không cần cập nhật và nhắc họ cập nhật sau. Nếu ứng dụng của bạn không thể hoạt động khi không được cập nhật, bạn nên hiện một thông báo trước khi bắt đầu lại quy trình cập nhật hoặc nhắc người dùng đóng ứng dụng. Nhờ đó, người dùng sẽ biết rằng họ có thể chạy lại ứng dụng một khi đã sẵn sàng cài đặt bản cập nhật cần thiết.

Các bước tiếp theo

Kiểm thử bản cập nhật trong ứng dụng cho ứng dụng để xác minh rằng quá trình tích hợp hoạt động chính xác.