Z tego przewodnika dowiesz się, jak obsługiwać aktualizacje w aplikacji w aplikacji za pomocą Kotlina lub Javy. Istnieją oddzielne przewodniki na wypadek, gdy implementacja używa kodu natywnego (C/C++), oraz na wypadek, gdy implementacja używa Unity.
Konfigurowanie środowiska programistycznego
Biblioteka aktualizacji w aplikacji w Google Play należy do podstawowych bibliotek Google Play. Aby zintegrować Google Play w aplikacji, uwzględnij tę zależność Gradle Zaktualizuj bibliotekę.
Odlotowe
// 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") ... }
Sprawdzanie dostępności aktualizacji
Zanim poprosisz o aktualizację, sprawdź, czy jest dostępna aktualizacja aplikacji.
Aby sprawdzić dostępność aktualizacji, użyj AppUpdateManager
:
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. } });
Zwrócona instancja AppUpdateInfo
zawiera stan dostępności aktualizacji. W zależności od stanu aktualizacji instancja zawiera też:
- Jeśli aktualizacja jest dostępna i aktualizacja jest dozwolona, instancja również zawiera intencję rozpoczęcia aktualizacji.
- Jeśli aktualizacja w aplikacji jest już w toku, instancja podaje też stan tej aktualizacji.
Sprawdź aktualność aktualizacji
Oprócz sprawdzenia, czy jest dostępna aktualizacja, warto też sprawdzić, ile czasu minęło od ostatniego powiadomienia o aktualizacji w Sklepie Play. Pomoże Ci to zdecydować, czy chcesz przeprowadzić elastyczne, czy natychmiastowe uaktualnienie. Na przykład możesz odczekać kilka dni, przed powiadomieniem użytkownika o elastycznej aktualizacji i kilka dni później bez natychmiastowej aktualizacji.
Użyj clientVersionStalenessDays()
, aby sprawdzić, ile dni minęło od udostępnienia aktualizacji w Sklepie Play:
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. } });
Sprawdź priorytet aktualizacji
Interfejs Google Play Developer API pozwala określić priorytet każdej aktualizacji. Dzięki temu aplikacja może zdecydować, jak zdecydowanie zalecić aktualizację użytkownikowi. Rozważ na przykład tę strategię ustawiania priorytetu aktualizacji:
- Niewielkie ulepszenia interfejsu: aktualizacja o niskim priorytecie; prośba o nieelastyczne ani natychmiastowe uaktualnienie. Aktualizuj tylko wtedy, gdy użytkownik nie wchodzi w interakcję z Twoją aplikacją.
- Ulepszenia dotyczące wydajności: aktualizacja o średnim priorytecie; poproś o elastyczne aktualizacje.
- Krytyczna aktualizacja zabezpieczeń: wysoki priorytet; zalecana natychmiastowa aktualizacja.
Aby określić priorytet, Google Play używa liczby całkowitej z zakresu od 0 do 5, gdzie 0 jest domyślną wartością, a 5 – najwyższym priorytetem. Aby ustawić priorytet
aktualizacji, użyj pola inAppUpdatePriority
w kolumnie Edits.tracks.releases
Google Play Developer API. Wszystkie nowo dodane wersje w ramach danej wersji mają ten sam priorytet. Priorytet można ustawić tylko podczas wdrażania nowej wersji i nie można go później zmienić.
Ustaw priorytet za pomocą interfejsu Google Play Developer API zgodnie z opisem w dokumentacji interfejsu Play Developer API.
Priorytet aktualizacji w aplikacji należy określić w
Edit.tracks
zasób przekazany w
Edit.tracks: update
. Ten przykład pokazuje publikowanie aplikacji z kodem wersji 88
i inAppUpdatePriority
5:
{ "releases": [{ "versionCodes": ["88"], "inAppUpdatePriority": 5, "status": "completed" }] }
W kodzie aplikacji możesz sprawdzić poziom priorytetu danej aktualizacji za pomocą funkcji updatePriority()
.
Zwracany priorytet uwzględnia inAppUpdatePriority
dla wszystkich aplikacji
między wersją zainstalowaną a najnowszą dostępną
niezależnie od ścieżki wersji. Przeanalizujmy następujący scenariusz:
- Publikujesz wersję 1 na ścieżce produkcyjnej bez priorytetu.
- Publikujesz wersję 2 na ścieżce testu wewnętrznego o priorytecie 5.
- Publikujesz wersję 3 na ścieżce produkcyjnej bez priorytetu.
Gdy użytkownicy w wersji produkcyjnej zaktualizują wersję 1 na wersję 3, otrzymają priorytet 5, mimo że wersja 2 została opublikowana na innej ścieżce.
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. } });
Rozpocznij aktualizację
Gdy potwierdzisz, że aktualizacja jest dostępna, możesz poprosić o jej zainstalowanie:
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());
Każdej instancji AppUpdateInfo
można użyć do rozpoczęcia aktualizacji tylko raz. Aby spróbować ponownie,
aktualizację w przypadku niepowodzenia, poproś o nowy AppUpdateInfo
i sprawdź ponownie
że aktualizacja jest dostępna i może być dozwolona.
Możesz zarejestrować program uruchamiający wyniki aktywności, używając wbudowanego
ActivityResultContracts.StartIntentSenderForResult
umowy. Zapoznaj się z sekcją na temat
powiadomienie o stanie aktualizacji.
Kolejne kroki zależą od tego, czy zależy Ci na elastycznym aktualizację lub natychmiastową aktualizację.
Konfigurowanie aktualizacji przy użyciu AppUpdateOptions
AppUpdateOptions
zawiera pole AllowAssetPackDeletion
, które określa, czy aktualizacja jest
mogą czyścić pakiety zasobów w przypadku
ograniczona ilość miejsca na urządzeniu. Domyślnie to pole jest ustawione na false
, ale możesz użyć metody setAllowAssetPackDeletion()
, aby ustawić je na 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());
Otrzymanie informacji o stanie połączenia zwrotnego
Po rozpoczęciu aktualizacji zarejestrowany wywołanie zwrotne funkcji inicjującej wynik aktywności otrzymuje wynik okna potwierdzenia:
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. } } });
Z funkcji onActivityResult()
callback możesz otrzymać kilka wartości:
RESULT_OK
: użytkownik zaakceptował aktualizację. W przypadku natychmiastowych aktualizacji możesz nie otrzymać tego wywołania zwrotnego, ponieważ aktualizacja powinna być już zakończona, zanim kontrola zostanie zwrócona do aplikacji.RESULT_CANCELED
: użytkownik odrzucił lub anulował aktualizację.ActivityResult.RESULT_IN_APP_UPDATE_FAILED
: Jakiś inny błąd uniemożliwił użytkownikowi udzielenie zgody lub nie można kontynuować.
Elastyczna aktualizacja
Gdy rozpoczniesz elastyczne aktualizowanie, użytkownikowi najpierw wyświetli się okno z prośbą o zgodę. Jeśli użytkownik wyrazi zgodę, pobieranie rozpocznie się w tle, a on będzie mógł nadal korzystać z aplikacji. W tej sekcji opisano, jak monitorować i przeprowadzać elastyczne aktualizacje w aplikacji.
Monitorowanie stanu aktualizacji elastycznej
Po rozpoczęciu pobierania elastycznej aktualizacji aplikacja musi monitorować stan aktualizacji, aby wiedzieć, kiedy można zainstalować aktualizację, i wyświetlić postęp w interfejsie aplikacji.
Stan trwającej aktualizacji możesz monitorować, rejestrując listenera na potrzeby aktualizacji stanu instalacji. W interfejsie aplikacji możesz też dodać pasek postępu, informowania użytkowników o postępach pobierania.
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);
Instalowanie elastycznej aktualizacji
Po wykryciu stanu InstallStatus.DOWNLOADED
musisz ponownie uruchomić aplikację
by zainstalować aktualizację.
W przeciwieństwie do natychmiastowych aktualizacji Google Play nie aktywuje aplikacji automatycznie. Uruchom ponownie, aby uzyskać elastyczną aktualizację. Dzieje się tak, ponieważ podczas elastycznej aktualizacji użytkownik może nadal korzystać z aplikacji, dopóki nie zdecyduje się na zainstalowanie aktualizacji.
Zalecamy podanie powiadomienia (lub innego elementu interfejsu) informujący użytkownika, że aktualizacja jest gotowa do instalacji, i poprosiła o potwierdzenie. przed ponownym uruchomieniem aplikacji.
Poniższy przykład pokazuje implementację stylu Material Design pasek powiadomień, który wysyła żądanie potwierdzenie ponownego uruchomienia aplikacji przez użytkownika:
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(); }
Gdy wywołasz funkcję appUpdateManager.completeUpdate()
na pierwszym planie, platforma wyświetla interfejs pełnoekranowy, który uruchamia aplikację w tle. Gdy platforma zainstaluje aktualizację, aplikacja zostanie zrestartowana jako
jego głównej działalności.
Jeśli zamiast tego wywołujesz completeUpdate()
, gdy aplikacja jest w
w tle, aktualizacja zostanie zainstalowana dyskretnie
nie zasłaniając interfejsu urządzenia.
Za każdym razem, gdy użytkownik przenosi Twoją aplikację na pierwszy plan, sprawdź, czy
aktualizacja oczekuje na zainstalowanie. Jeśli DOWNLOADED
zawiera aktualizację Twojej aplikacji
, poproś użytkownika o zainstalowanie aktualizacji. W przeciwnym razie dane
nadal zajmują pamięć urządzenia użytkownika.
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(); } }); }
Natychmiastowa aktualizacja
Gdy rozpoczniesz natychmiastową aktualizację, a użytkownik wyrazi na nią zgodę, Google Play wyświetla postęp aktualizacji nad interfejsem aplikacji przez cały przez cały czas trwania aktualizacji. Jeśli użytkownik zamknie aplikację w trakcie Aktualizacja powinna być nadal pobierana i instalowana w tle bez dodatkowego potwierdzenia ze strony użytkownika.
Gdy jednak aplikacja wróci na pierwszy plan, sprawdź, czy aktualizacja nie została wstrzymana w stanie UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS
. Jeśli aktualizacja utknęła w tym stanie, wznów ją:
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()); } }); }
Proces aktualizacji zwraca wynik zgodny z opisem w dokumentacji dotyczącej startUpdateFlowForResult(), Aplikacja powinna być w szczególności w stanie obsługiwać przypadki, gdy użytkownik odrzuci zaktualizuje albo anuluje pobieranie. Gdy użytkownik wykona jedno z tych działań, interfejs Google Play zostanie zamknięty. Aplikacja powinna określić najlepszy sposób postępowania.
Jeśli to możliwe, pozwól użytkownikowi kontynuować bez aktualizacji i ponownie poproś o to później. Jeśli aplikacja bez aktualizacji nie będzie mogła działać, warto wyświetlić komunikat informacyjny przed ponownym rozpoczęciem aktualizacji lub prośbą o Zamknij aplikację. Dzięki temu użytkownik będzie wiedział, że może ponownie uruchomić aplikację. gdy będą gotowi do zainstalowania wymaganej aktualizacji.
Dalsze kroki
Testowanie aktualizacji aplikacji. czy integracja działa poprawnie.