Bu kılavuzda, Kotlin veya Java kullanarak uygulamanızda uygulama içi güncellemeleri nasıl destekleyeceğiniz açıklanmaktadır. Uygulamanızın yerel kod (C/C++) kullandığı durumlar ve uygulamanızın Unity veya Unreal Engine kullandığı durumlar için ayrı kılavuzlar vardır.
Geliştirme ortamınızı ayarlama
Play Uygulama İçi Güncelleme Kitaplığı, Google Play Core kitaplıklarının bir parçasıdır. Play Uygulama İçi Güncelleme Kitaplığı'nı entegre etmek için aşağıdaki Gradle bağımlılığını ekleyin.
Modern
// 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") ... }
Güncelleme olup olmadığını kontrol etme
Güncelleme isteğinde bulunmadan önce uygulamanız için güncelleme olup olmadığını kontrol edin.
Güncelleme olup olmadığını kontrol etmek için AppUpdateManager yöntemini kullanın:
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. } });
Döndürülen AppUpdateInfo örneği, güncelleme kullanılabilirlik durumunu içerir. Güncellemenin durumuna bağlı olarak örnekte aşağıdakiler de yer alır:
- Güncelleme varsa ve güncellemeye izin veriliyorsa örnekte güncellemeyi başlatma niyeti de bulunur.
- Uygulama içi güncelleme devam ediyorsa örnek, devam eden uygulama güncellemesinin durumunu da bildirir.
Güncellemenin güncelliğini kontrol etme
Güncelleme olup olmadığını kontrol etmenin yanı sıra, kullanıcının Play Store üzerinden bir güncelleme hakkında en son ne zaman bilgilendirildiğini de kontrol etmek isteyebilirsiniz. Bu sayede, esnek güncelleme mi yoksa hemen güncelleme mi başlatmanız gerektiğine karar verebilirsiniz. Örneğin, kullanıcıya esnek bir güncelleme bildirimi göndermeden önce birkaç gün, hemen güncelleme yapmasını istemeden önce de birkaç gün bekleyebilirsiniz.
Güncellemenin Google Play Store'da kullanıma sunulmasından bu yana geçen gün sayısını kontrol etmek için clientVersionStalenessDays() kullanın:
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. } });
Güncelleme önceliğini kontrol etme
Google Play Developer API, her güncellemenin önceliğini ayarlamanıza olanak tanır. Bu sayede uygulamanız, kullanıcıya bir güncellemeyi ne kadar güçlü bir şekilde önereceğine karar verebilir. Örneğin, güncelleme önceliğini ayarlamak için aşağıdaki stratejiyi göz önünde bulundurun:
- Kullanıcı arayüzüyle ilgili küçük iyileştirmeler: Düşük öncelikli güncelleme; esnek güncelleme veya hemen güncelleme istemeyin. Yalnızca kullanıcı uygulamanızla etkileşimde bulunmadığında güncelleyin.
- Performans iyileştirmeleri: Orta öncelikli güncelleme; esnek güncelleme isteyin.
- Kritik güvenlik güncellemesi: Yüksek öncelikli güncelleme; hemen güncelleme isteyin.
Google Play, önceliği belirlemek için 0 ile 5 arasında bir tam sayı değeri kullanır. 0 varsayılan değer, 5 ise en yüksek önceliktir. Bir güncellemenin önceliğini ayarlamak için Google Play Developer API'de Edits.tracks.releases altındaki inAppUpdatePriority alanını kullanın. Sürüme yeni eklenen tüm sürümler, sürümle aynı önceliğe sahip olarak kabul edilir. Öncelik yalnızca yeni bir sürüm yayınlanırken ayarlanabilir ve daha sonra değiştirilemez.
Play Developer API belgelerinde açıklandığı şekilde Google Play Developer API'yi kullanarak önceliği ayarlayın. Uygulama güncellemesi içi önceliği, Edit.tracks: update yönteminde iletilen Edit.tracks kaynağında belirtilmelidir. Aşağıdaki örnekte, sürüm kodu 88 ve inAppUpdatePriority 5 olan bir uygulamanın yayınlanması gösterilmektedir:
{ "releases": [{ "versionCodes": ["88"], "inAppUpdatePriority": 5, "status": "completed" }] }
Uygulamanızın kodunda, updatePriority() kullanarak belirli bir güncellemenin öncelik düzeyini kontrol edebilirsiniz. Döndürülen öncelik, sürüm kanalından bağımsız olarak yüklü sürüm ile mevcut en son sürüm arasındaki tüm uygulama sürüm kodları için inAppUpdatePriority değerini dikkate alır. Örneğin, aşağıdaki senaryoyu düşünün:
- 1. sürümü öncelik olmadan bir üretim kanalında yayınlarsınız.
- 2. sürümü, önceliği 5 olan bir dahili test kanalında yayınladınız.
- 3. sürümü öncelik olmadan bir üretim kanalında yayınlarsınız.
Üretim kullanıcıları 1. sürümden 3. sürüme güncelleme yaptığında, 2. sürüm farklı bir kanalda yayınlanmış olsa bile 5. önceliği alırlar.
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. } });
Güncelleme başlatma
Güncelleme olduğunu onayladıktan sonra AppUpdateManager.startUpdateFlowForResult() kullanarak güncelleme isteğinde bulunabilirsiniz:
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());
Her AppUpdateInfo örneği, bir güncellemeyi başlatmak için yalnızca bir kez kullanılabilir. Güncelleme başarısız olursa tekrar denemek için yeni bir AppUpdateInfo isteyin ve güncellemenin kullanılabilir ve izin verilmiş olduğunu tekrar kontrol edin.
Yerleşik ActivityResultContracts.StartIntentSenderForResult sözleşmesini kullanarak bir etkinlik sonucu başlatıcı kaydedebilirsiniz. Güncelleme durumu için geri çağırma alma bölümüne göz atın.
Sonraki adımlar, esnek güncelleme mi yoksa hemen güncelleme mi istediğinize bağlıdır.
AppUpdateOptions ile güncelleme yapılandırma
AppUpdateOptions, cihaz depolama alanının sınırlı olması durumunda güncellemenin öğe paketlerini temizlemesine izin verilip verilmeyeceğini tanımlayan bir AllowAssetPackDeletion alanı içerir. Bu alan varsayılan olarak false değerine ayarlanır ancak setAllowAssetPackDeletion() yöntemini kullanarak true değerine ayarlayabilirsiniz:
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());
Güncelleme durumu için geri aranma isteğinde bulunma
Güncelleme başlatıldıktan sonra, kayıtlı etkinlik sonucu başlatıcı geri çağırma işlevi onay iletişim kutusu sonucunu alır:
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. } } });
onActivityResult() geri çağırma işlevinden alabileceğiniz birkaç değer vardır:
RESULT_OK: Kullanıcı güncellemeyi kabul etti. Anında güncellemeler için, kontrol uygulamanıza geri verildiğinde güncellemenin zaten tamamlanmış olması gerektiğinden bu geri çağırmayı almayabilirsiniz.RESULT_CANCELED: Kullanıcı, güncellemeyi reddetti veya iptal etti.ActivityResult.RESULT_IN_APP_UPDATE_FAILED: Başka bir hata, kullanıcının izin vermesini veya güncellemenin devam etmesini engelledi.
Esnek güncellemeleri işleme
Esnek bir güncelleme başlattığınızda kullanıcıdan izin istemek için bir iletişim kutusu gösterilir. Kullanıcı izin verirse indirme işlemi arka planda başlar ve kullanıcı uygulamanızla etkileşimde bulunmaya devam edebilir. Bu bölümde, esnek uygulama güncellemesinin nasıl izleneceği ve tamamlanacağı açıklanmaktadır.
Esnek güncelleme durumunu izleme
Esnek bir güncellemenin indirme işlemi başladıktan sonra uygulamanızın, güncellemenin ne zaman yüklenebileceğini öğrenmek ve ilerleme durumunu uygulamanızın kullanıcı arayüzünde göstermek için güncelleme durumunu izlemesi gerekir.
Yükleme durumu güncellemeleri için bir dinleyici kaydederek devam eden bir güncellemenin durumunu izleyebilirsiniz. Kullanıcıları indirme işleminin ilerleme durumu hakkında bilgilendirmek için uygulamanın kullanıcı arayüzünde bir ilerleme çubuğu da gösterebilirsiniz.
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);
Esnek güncelleme yükleme
InstallStatus.DOWNLOADED durumunu tespit ettiğinizde güncellemeyi yüklemek için uygulamayı yeniden başlatmanız gerekir.
Google Play, hemen güncellemenin aksine esnek güncelleme için uygulamanın yeniden başlatılmasını otomatik olarak tetiklemez. Bunun nedeni, esnek güncelleme sırasında kullanıcının, güncellemeyi yüklemek istediğine karar verene kadar uygulamayla etkileşimde bulunmaya devam etmeyi beklemesidir.
Kullanıcıya güncellemenin yüklenmeye hazır olduğunu bildirmek için bir bildirim (veya başka bir kullanıcı arayüzü göstergesi) sağlamanız ve uygulamayı yeniden başlatmadan önce onay istemeniz önerilir.
Aşağıdaki örnekte, uygulamayı yeniden başlatmak için kullanıcıdan onay isteyen bir Materyal Tasarım snackbar'ın nasıl uygulanacağı gösterilmektedir:
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(); }
Ön planda appUpdateManager.completeUpdate() yöntemini çağırdığınızda platform, uygulamayı arka planda yeniden başlatan tam ekran bir kullanıcı arayüzü gösterir.
Platform güncellemeyi yükledikten sonra uygulamanız yeniden başlatılarak ana etkinliğine döner.
Uygulamanız arka plandayken completeUpdate() yöntemini çağırırsanız güncelleme, cihaz kullanıcı arayüzünü engellemeden sessizce yüklenir.
Kullanıcı uygulamanızı her ön plana getirdiğinde uygulamanızın yüklenmeyi bekleyen bir güncellemesi olup olmadığını kontrol edin. Uygulamanızın DOWNLOADED durumunda bir güncellemesi varsa kullanıcıdan güncellemeyi yüklemesini isteyin. Aksi takdirde güncelleme verileri, kullanıcının cihaz depolama alanında yer kaplamaya devam eder.
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(); } }); }
Anında güncellemeyi işleme
Hemen güncelleme başlattığınızda ve kullanıcı güncellemeyi başlatmayı kabul ettiğinde Google Play, güncelleme süresi boyunca güncelleme ilerleme durumunu uygulamanızın kullanıcı arayüzünün üst kısmında gösterir. Kullanıcı güncelleme sırasında uygulamanızı kapatır veya sonlandırırsa güncelleme, arka planda ek kullanıcı onayı olmadan indirilmeye ve yüklenmeye devam etmelidir.
Ancak uygulamanız ön plana döndüğünde güncellemenin UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS durumunda takılı kalmadığını onaylamanız gerekir. Güncelleme bu durumda takılı kalırsa güncellemeyi devam ettirin:
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()); } }); }
Güncelleme akışı, startUpdateFlowForResult() referans belgelerinde açıklandığı gibi bir sonuç döndürür. Özellikle uygulamanız, kullanıcının güncellemeyi reddettiği veya indirmeyi iptal ettiği durumları işleyebilmelidir. Kullanıcı bu işlemlerden birini gerçekleştirdiğinde Google Play kullanıcı arayüzü kapanır. Uygulamanız, nasıl ilerleyeceğinizi belirlemelidir.
Mümkünse kullanıcının güncelleme yapmadan devam etmesine izin verin ve daha sonra tekrar hatırlatın. Uygulamanız güncelleme olmadan çalışamıyorsa güncelleme akışını yeniden başlatmadan veya kullanıcıdan uygulamayı kapatmasını istemeden önce bilgilendirici bir mesaj göstermeniz önerilir. Böylece kullanıcı, gerekli güncellemeyi yüklemeye hazır olduğunda uygulamanızı yeniden başlatabileceğini anlar.
Sonraki adımlar
Entegrasyonunuzun doğru şekilde çalıştığını doğrulamak için uygulamanızın uygulama içi güncellemelerini test edin.