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ığı ve Unity veya Unreal Engine kullandığı durumlar için ayrı kılavuzlar vardır.
Geliştirme ortamınızı kurma
Play uygulama içi güncelleme kitaplığı, Google Play Core Library'nin bir parçasıdır. Play uygulama içi güncelleme kitaplığını entegre etmek için aşağıdaki Gradle bağımlılığını ekleyin.
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") ... }
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
simgesini 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ılabilirliği durumunu içerir. Güncellemenin durumuna bağlı olarak örnekte aşağıdakiler de bulunur:
- Güncelleme varsa ve izin veriliyorsa örnek, güncellemeyi başlatma amaçlı bir niyet de içerir.
- Uygulama içi güncelleme zaten devam ediyorsa örnek, devam eden güncellemenin durumunu da bildirir.
Güncelliğini yitirmiş güncellemeleri kontrol etme
Güncelleme olup olmadığını kontrol etmenin yanı sıra, kullanıcının Play Store üzerinden en son güncelleme bildirimi almasından bu yana ne kadar zaman geçtiğini de kontrol etmek isteyebilirsiniz. Bu, esnek güncelleme mi yoksa anında güncelleme mi başlatmanız gerektiğine karar vermenize yardımcı olabilir. Örneğin, kullanıcıya esnek bir güncelleme bildirimi göndermeden önce birkaç gün, ardından da acil güncelleme yapmasını istemeden önce birkaç gün bekleyebilirsiniz.
Güncellemenin Play Store'da kullanıma sunulmasından bu yana geçen gün sayısını kontrol etmek için clientVersionStalenessDays()
simgesini 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, uygulamanızın kullanıcıya güncellemeyi ne kadar ısrarlı bir şekilde önereceğine karar vermesini sağlar. Örneğin, güncelleme önceliğini ayarlamak için aşağıdaki stratejiyi kullanabilirsiniz:
- Kullanıcı arayüzüyle ilgili küçük geliştirmeler: Düşük öncelikli güncelleme; esnek güncelleme veya anlık güncelleme isteğinde bulunulmaz. Yalnızca kullanıcı uygulamanızla etkileşimde bulunmadığında güncelleyin.
- Performans iyileştirmeleri: Orta öncelikli güncelleme; esnek bir güncelleme isteğinde bulunun.
- Kritik güvenlik güncellemesi: Yüksek öncelikli güncelleme; hemen güncelleme isteğinde bulunun.
Google Play, önceliği belirlemek için 0 ile 5 arasında bir tam sayı değeri kullanır. Varsayılan değer 0, en yüksek öncelik ise 5'tir. Bir güncellemenin önceliğini ayarlamak için Google Play Developer API'deki Edits.tracks.releases
altında 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.
Google Play Developer API'yi kullanarak önceliği Play Developer API dokümanlarında açıklandığı şekilde ayarlayın. Uygulama içi güncelleme ö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, yayın 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
dikkate alır. Örneğin, aşağıdaki senaryoyu inceleyin:
- 1. sürümü önceliği olmayan bir üretim kanalında yayınlarsınız.
- 2. sürümü 5 önceliğiyle dahili test kanalında yayınlarsınız.
- 3. sürümü önceliği olmayan bir üretim kanalında yayınlarsınız.
Üretim kullanıcıları sürüm 1'den sürüm 3'e güncelleme yaptığında, sürüm 2 farklı bir kanalda yayınlanmış olsa bile öncelik 5'i alır.
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üncellemeyi başlatma
Bir güncellemenin kullanıma sunulduğ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, güncelleme başlatmak için yalnızca bir kez kullanılabilir. Güncelleme başarısız olursa yeniden 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 arama alma bölümünü inceleyin.
Sonraki adımlar, esnek güncelleme veya anlık güncelleme isteğinde bulunup bulunmadığınıza bağlıdır.
AppUpdateOptions ile güncelleme yapılandırma
AppUpdateOptions
, cihaz depolama alanı sınırlı olduğunda güncellemenin öğe paketlerini temizlemesine izin verilip verilmediğini tanımlayan bir AllowAssetPackDeletion
alanı içerir. Bu alan varsayılan olarak false
olarak ayarlanır ancak setAllowAssetPackDeletion()
yöntemini kullanarak true
olarak 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 arama alma
Bir güncelleme başlatıldıktan sonra, kayıtlı etkinlik sonucu başlatıcı geri çağırması 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 etmiştir. Anında güncellemeler için, kontrol uygulamanıza geri verildiğinde güncelleme zaten tamamlanmış olacağından bu geri aramayı almayabilirsiniz.RESULT_CANCELED
: Kullanıcı, güncellemeyi reddetmiş veya iptal etmiştir.ActivityResult.RESULT_IN_APP_UPDATE_FAILED
: Başka bir hata, kullanıcının izin vermesini veya güncellemenin devam etmesini engelledi.
Esnek güncellemeyi işleme
Esnek bir güncellemeyi başlattığınızda kullanıcıya önce izin isteğinde bulunan bir iletişim kutusu gösterilir. Kullanıcı izin verirse indirme işlemi arka planda başlar ve kullanıcı uygulamanızla etkileşime devam edebilir. Bu bölümde, esnek uygulama içi güncellemenin nasıl izleneceği ve tamamlanacağı açıklanmaktadır.
Esnek güncelleme durumunu izleme
Esnek güncelleme indirilmeye başladıktan sonra uygulamanız, 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 izlemelidir.
Devam eden bir güncellemenin durumunu, yükleme durumu güncellemeleri için bir dinleyici kaydederek izleyebilirsiniz. Ayrıca, uygulamanın kullanıcı arayüzünde bir ilerleme çubuğu sağlayarak kullanıcıları indirme işleminin ilerlemesi hakkında bilgilendirebilirsiniz.
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 algıladığınızda güncellemeyi yüklemek için uygulamayı yeniden başlatmanız gerekir.
Anlık güncellemelerin aksine, Google Play esnek güncelleme için uygulama yeniden başlatmayı 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şime devam etmeyi beklemesidir.
Güncellemenin yüklenmeye hazır olduğunu bildirmek ve uygulamayı yeniden başlatmadan önce onay istemek için kullanıcıya bir bildirim (veya başka bir kullanıcı arayüzü göstergesi) sağlamanız önerilir.
Aşağıdaki örnekte, uygulamayı yeniden başlatmak için kullanıcıdan onay isteyen bir Material Design 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(); }
appUpdateManager.completeUpdate()
işlevini ön planda ç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 ana etkinliğinde yeniden başlatılır.
Bunun yerine uygulamanız arka plandayken completeUpdate()
numaralı telefonu ararsanız güncelleme, cihaz kullanıcı arayüzünü kapatmadan sessizce yüklenir.
Kullanıcı uygulamanızı ön plana getirdiğinde, uygulamanızda yüklenmeyi bekleyen bir güncelleme olup olmadığını kontrol edin. Uygulamanız DOWNLOADED
durumunda bir güncellemeye sahipse kullanıcıdan güncellemeyi yüklemesini isteyin. Aksi takdirde, güncelleme verileri kullanıcının cihaz depolama alanını işgal etmeye 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(); } }); }
Hemen güncelleme yapma
Anında güncelleme başlattığınızda ve kullanıcı güncellemenin başlatılmasına izin verdiğinde Google Play, güncelleme süresi boyunca uygulamanızın kullanıcı arayüzünün üzerinde güncelleme ilerleme durumunu gösterir. Kullanıcı, güncelleme sırasında uygulamanızı kapatırsa veya sonlandırırsa güncelleme, ek kullanıcı onayı olmadan arka planda indirilmeye ve yüklenmeye devam etmelidir.
Ancak uygulamanız ön plana döndüğünde güncellemenin UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS
durumunda takılmadığını onaylamanız gerekir. Güncelleme bu durumda takılıp 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 dokümanında açıklandığı gibi bir sonuç döndürür. Uygulamanız özellikle kullanıcının güncellemeyi reddettiği veya indirmeyi iptal ettiği durumları yönetebilmelidir. Kullanıcı bu işlemlerden birini gerçekleştirdiğinde Google Play kullanıcı arayüzü kapanır. Uygulamanız, devam etmenin en iyi yolunu belirlemelidir.
Mümkünse kullanıcının güncelleme yapmadan devam etmesine izin verin ve daha sonra tekrar güncelleme yapmasını isteyin. 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östermeyi düşünebilirsiniz. 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.