Bu kılavuzda, yerel kodu (C veya C++) kullanarak uygulamanızda uygulama içi güncellemeleri nasıl destekleyeceğiniz açıklanmaktadır. Uygulamanızın Kotlin veya Java programlama dilini kullandığı durumlar ve uygulamanızın Unity veya Unreal Engine kullandığı durumlar için ayrı kılavuzlar bulunmaktadır.
Native SDK'ya genel bakış
Play Core Yerel SDK'sı, Play Core SDK ailesinin bir parçasıdır. Yerel SDK, Java Play uygulama içi güncelleme kitaplığındaki AppUpdateManager
'yi sarmalayan bir C başlık dosyası (app_update.h
) içerir. Bu başlık dosyası, uygulamanızın uygulama içi güncellemeler için API'yi doğrudan yerel kodunuzdan çağırmasına olanak tanır.
Geliştirme ortamınızı kurma
İndir Play Core Native SDK
İndirmeden önce aşağıdaki hüküm ve koşulları kabul etmeniz gerekir.
Hükümler ve Koşullar
Last modified: September 24, 2020- By using the Play Core Software Development Kit, you agree to these terms in addition to the Google APIs Terms of Service ("API ToS"). If these terms are ever in conflict, these terms will take precedence over the API ToS. Please read these terms and the API ToS carefully.
- For purposes of these terms, "APIs" means Google's APIs, other developer services, and associated software, including any Redistributable Code.
- “Redistributable Code” means Google-provided object code or header files that call the APIs.
- Subject to these terms and the terms of the API ToS, you may copy and distribute Redistributable Code solely for inclusion as part of your API Client. Google and its licensors own all right, title and interest, including any and all intellectual property and other proprietary rights, in and to Redistributable Code. You will not modify, translate, or create derivative works of Redistributable Code.
- Google may make changes to these terms at any time with notice and the opportunity to decline further use of the Play Core Software Development Kit. Google will post notice of modifications to the terms at https://developer.android.com/guide/playcore/license. Changes will not be retroactive.
Aşağıdakilerden birini yapın:
- Android Studio 4.0 veya sonraki bir sürümünü yükleyin. Android SDK Platform 10.0 sürümünü (API düzeyi 29) yüklemek için SDK Yöneticisi kullanıcı arayüzünü kullanın.
- Android SDK komut satırı araçlarını yükleyin
ve
sdkmanager
komutunu kullanarak Android SDK Platform 10.0 sürümünü (API düzeyi 29) yükleyin.
En yeni CMake ve Android Native Development Kit'i (NDK) yüklemek için SDK Manager'ı kullanarak Android Studio'yu yerel geliştirmeye hazırlayın. Yerel projeler oluşturma veya içe aktarma hakkında daha fazla bilgi için NDK'yı kullanmaya başlama başlıklı makaleyi inceleyin.
ZIP dosyasını indirip projenizin yanına çıkarın.
İndirme Bağlantısı Boyut SHA-256 Sağlaması 37,8 MiB 9db60185185342f28d2c278b60222333608c67bc022e458a25224eaea8c4c4b7 Uygulamanızın
build.gradle
dosyasını aşağıda gösterildiği gibi güncelleyin:Groovy
// App build.gradle plugins { id 'com.android.application' } // Define a path to the extracted Play Core SDK files. // If using a relative path, wrap it with file() since CMake requires absolute paths. def playcoreDir = file('../path/to/playcore-native-sdk') android { defaultConfig { ... externalNativeBuild { cmake { // Define the PLAYCORE_LOCATION directive. arguments "-DANDROID_STL=c++_static", "-DPLAYCORE_LOCATION=$playcoreDir" } } ndk { // Skip deprecated ABIs. Only required when using NDK 16 or earlier. abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64' } } buildTypes { release { // Include Play Core Library proguard config files to strip unused code while retaining the Java symbols needed for JNI. proguardFile '$playcoreDir/proguard/common.pgcfg' proguardFile '$playcoreDir/proguard/gms_task.pgcfg' proguardFile '$playcoreDir/proguard/per-feature-proguard-files' ... } debug { ... } } externalNativeBuild { cmake { path 'src/main/CMakeLists.txt' } } } dependencies { // Import these feature-specific AARs for each Google Play Core library. implementation 'com.google.android.play:app-update:2.1.0' implementation 'com.google.android.play:asset-delivery:2.3.0' implementation 'com.google.android.play:integrity:1.4.0' implementation 'com.google.android.play:review:2.0.2' // Import these common dependencies. implementation 'com.google.android.gms:play-services-tasks:18.0.2' implementation files("$playcoreDir/playcore-native-metadata.jar") ... }
Kotlin
// App build.gradle plugins { id("com.android.application") } // Define a path to the extracted Play Core SDK files. // If using a relative path, wrap it with file() since CMake requires absolute paths. val playcoreDir = file("../path/to/playcore-native-sdk") android { defaultConfig { ... externalNativeBuild { cmake { // Define the PLAYCORE_LOCATION directive. arguments += listOf("-DANDROID_STL=c++_static", "-DPLAYCORE_LOCATION=$playcoreDir") } } ndk { // Skip deprecated ABIs. Only required when using NDK 16 or earlier. abiFilters.clear() abiFilters += listOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64") } } buildTypes { release { // Include Play Core Library proguard config files to strip unused code while retaining the Java symbols needed for JNI. proguardFile("$playcoreDir/proguard/common.pgcfg") proguardFile("$playcoreDir/proguard/gms_task.pgcfg") proguardFile("$playcoreDir/proguard/per-feature-proguard-files") ... } debug { ... } } externalNativeBuild { cmake { path = "src/main/CMakeLists.txt" } } } dependencies { // Import these feature-specific AARs for each Google Play Core library. implementation("com.google.android.play:app-update:2.1.0") implementation("com.google.android.play:asset-delivery:2.3.0") implementation("com.google.android.play:integrity:1.4.0") implementation("com.google.android.play:review:2.0.2") // Import these common dependencies. implementation("com.google.android.gms:play-services-tasks:18.0.2") implementation(files("$playcoreDir/playcore-native-metadata.jar")) ... }
Uygulamanızın
CMakeLists.txt
dosyalarını aşağıda gösterildiği gibi güncelleyin:cmake_minimum_required(VERSION 3.6) ... # Add a static library called “playcore” built with the c++_static STL. include(${PLAYCORE_LOCATION}/playcore.cmake) add_playcore_static_library() // In this example “main” is your native code library, i.e. libmain.so. add_library(main SHARED ...) target_include_directories(main PRIVATE ${PLAYCORE_LOCATION}/include ...) target_link_libraries(main android playcore ...)
Veri Toplama
Play Core Yerel SDK'sı, Google'ın ürünü iyileştirmesine olanak tanımak için sürümle ilgili veriler toplayabilir. Örneğin:
- Uygulamanın paket adı
- Uygulamanın paket sürümü
- Play Core Yerel SDK'sının sürümü
Bu veriler, Play Console'a uygulama paketinizi yüklediğinizde toplanır. Bu veri toplama sürecini devre dışı bırakmak için build.gradle dosyasındaki $playcoreDir/playcore-native-metadata.jar
içe aktarma işlemini kaldırın.
Play Core Native SDK kullanımınızla ilgili bu veri toplama işleminin ve Google'ın toplanan verileri kullanımının, uygulama paketinizi Play Console'a yüklediğinizde Gradle'da beyan edilen kitaplık bağımlılıklarının Google tarafından toplanmasından ayrı ve bağımsız olduğunu unutmayın.
Play Core Native SDK'yı projenize entegre ettikten sonra API çağrıları içeren dosyalara aşağıdaki satırı ekleyin:
#include "play/app_update.h"
Uygulama içi güncelleme API'sini başlatma
Uygulama içi güncelleme API'sini her kullandığınızda, android_native_app_glue.h
ile oluşturulan aşağıdaki örnekte gösterildiği gibi, AppUpdateManager_init()
işlevini çağırarak önce başlatın:
void android_main(android_app* app) {
app->onInputEvent = HandleInputEvent;
AppUpdateErrorCode error_code =
AppUpdateManager_init(app->activity->vm, app->activity->clazz);
if (error_code == APP_UPDATE_NO_ERROR) {
// You can use the API.
}
}
Güncelleme olup olmadığını kontrol etme
Güncelleme isteğinde bulunmadan önce uygulamanız için güncelleme olup olmadığını kontrol edin. AppUpdateManager_requestInfo()
, uygulama içi güncelleme akışını daha sonra başlatmak için gereken bilgileri toplayan eşzamansız bir istek başlatır. İstek başarıyla başlarsa işlev APP_UPDATE_NO_ERROR
değerini döndürür.
AppUpdateErrorCode error_code = AppUpdateManager_requestInfo()
if (error_code == APP_UPDATE_NO_ERROR) {
// The request has successfully started, check the result using
// AppUpdateManager_getInfo.
}
Devam eden süreci ve isteğin sonucunu AppUpdateManager_getInfo()
kullanarak takip edebilirsiniz. Bu işlev, hata koduna ek olarak güncelleme isteğiyle ilgili bilgileri almak için kullanabileceğiniz AppUpdateInfo
opak bir yapı döndürür. Örneğin, info
için null olmayan bir sonuç döndürene kadar bu işlevi her oyun döngüsünde çağırmak isteyebilirsiniz:
AppUpdateInfo* info;
GameUpdate() {
// Keep calling this in every game loop until info != nullptr
AppUpdateErrorCode error_code = AppUpdateManager_getInfo(&info);
if (error_code == APP_UPDATE_NO_ERROR && info != nullptr) {
// Successfully started, check the result in the following functions
}
...
}
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 AppUpdateInfo_getClientVersionStalenessDays()
işlevini kullanın:
int32_t staleness_days = AppUpdateInfo_getClientVersionStalenessDays(info);
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.
Play Developer API dokümanlarında açıklandığı şekilde Google Play Developer API'yi kullanarak önceliği ayarlayın. Edit.tracks: update
yönteminde iletilen Edit.tracks
kaynağında uygulama içi güncelleme önceliğini belirtin.
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, AppUpdateInfo_getPriority()
kullanarak belirli bir güncellemenin öncelik düzeyini kontrol edebilirsiniz:
int32_t priority = AppUpdateInfo_getPriority(info);
Güncellemeyi başlatma
Bir güncellemenin mevcut olduğunu onayladıktan sonra AppUpdateManager_requestStartUpdate()
kullanarak güncelleme isteğinde bulunabilirsiniz. Güncelleme isteğinde bulunmadan önce güncel bir AppUpdateInfo
nesnesi alın ve güncelleme akışını yapılandırmak için bir AppUpdateOptions
nesnesi oluşturun. AppUpdateOptions
nesnesi, güncellemenin esnek mi yoksa anlık mı olması gerektiği de dahil olmak üzere uygulama içi güncelleme akışıyla ilgili seçenekleri tanımlar.
Aşağıdaki örnek, esnek güncelleme akışı için bir AppUpdateOptions
nesnesi oluşturur:
// Creates an AppUpdateOptions configuring a flexible in-app update flow.
AppUpdateOptions* options;
AppUpdateErrorCode error_code = AppUpdateOptions_createOptions(APP_UPDATE_TYPE_FLEXIBLE, &options);
Aşağıdaki örnekte, anında güncelleme akışı için bir AppUpdateOptions
nesnesi oluşturulmaktadır:
// Creates an AppUpdateOptions configuring an immediate in-app update flow.
AppUpdateOptions* options;
AppUpdateErrorCode error_code = AppUpdateOptions_createOptions(APP_UPDATE_TYPE_IMMEDIATE, &options);
AppUpdateOptions
nesnesi, sınırlı cihaz depolama alanı olması durumunda güncellemenin öğe paketlerini temizlemesine izin verilip verilmeyeceğini tanımlayan bir AllowAssetPackDeletion
alanı da içerir. Bu alan varsayılan olarak false
olarak ayarlanır ancak AppUpdateOptions_setAssetPackDeletionAllowed()
yöntemini kullanarak bunun yerine true
olarak ayarlayabilirsiniz:
bool allow = true;
AppUpdateErrorCode error_code = AppUpdateOptions_setAssetPackDeletionAllowed(options, allow);
Güncel bir AppUpdateInfo
nesneniz ve düzgün şekilde yapılandırılmış bir AppUpdateOptions
nesneniz olduktan sonra, son parametre için bir Android Etkinliği jobject
ileterek bir güncelleme akışını eşzamansız olarak istemek üzere AppUpdateManager_requestStartUpdate()
işlevini çağırın.
AppUpdateErrorCode request_error_code =
AppUpdateManager_requestStartUpdate(info, options, app->activity->clazz);
Kaynakları serbest bırakmak için sırasıyla AppUpdateInfo_destroy()
ve AppUpdateOptions_destroy()
çağrılarını yaparak artık ihtiyacınız olmayan AppUpdateInfo
ve AppUpdateOptions
örneklerini serbest bırakın.
AppUpdateInfo_destroy(info);
AppUpdateOptions_destroy(options);
Google Play, anında güncelleme akışı için kullanıcı onayı sayfası gösterir. Kullanıcı isteği kabul ettiğinde Google Play, güncellemeyi otomatik olarak indirip ön planda yükler. Yükleme başarılı olursa uygulamayı güncellenmiş sürümde yeniden başlatır.
Esnek bir güncelleme akışı için, kullanıcı uygulamayla etkileşime devam ederken mevcut güncelleme durumunu takip etmek amacıyla güncel AppUpdateInfo
nesneleri istemeye devam edebilirsiniz. İndirme işlemi başarıyla tamamlandıktan sonra, aşağıdaki örnekte gösterildiği gibi AppUpdateManager_requestCompleteUpdate()
işlevini çağırarak güncellemenin tamamlanmasını tetiklemeniz gerekir:
AppUpdateStatus status = AppUpdateInfo_getStatus(info);
if (status == APP_UPDATE_DOWNLOADED) {
AppUpdateErrorCode error_code = AppUpdateManager_requestCompleteUpdate();
if (error_code != APP_UPDATE_NO_ERROR)
{
// There was an error while completing the update flow.
}
}
Uygulamanız API'yi kullanmayı bitirdikten sonra AppUpdateManager_destroy()
işlevini çağırarak kaynakları boşaltın.
Hata işleme
Bu bölümde, belirli AppUpdateErrorCode
değerleriyle gösterilen yaygın hataların çözümleri açıklanmaktadır:
-110, APP_UPDATE_INITIALIZATION_NEEDED
hata kodu, API'nin başarıyla başlatılmadığını gösterir. API'yi başlatmak içinAppUpdateManager_init()
işlevini çağırın.-4, APP_UPDATE_INVALID_REQUEST
hata kodu, güncelleme akışı isteğinin bazı parametrelerinin hatalı biçimlendirildiğini gösterir.AppUpdateInfo
veAppUpdateOptions
nesnelerinin boş olmadığından ve doğru biçimlendirildiğinden emin olun.-5, APP_UPDATE_UNAVAILABLE
hata kodu, geçerli bir güncelleme olmadığını gösterir. Hedef sürümün aynı paket adına, uygulama kimliğine ve imzalama anahtarına sahip olduğundan emin olun. Güncelleme varsa uygulamanın önbelleğini temizleyin veAppUpdateManager_requestAppUpdateInfo()
yenilemek için tekrar arayınAppUpdateInfo
.-6, APP_UPDATE_NOT_ALLOWED
hata kodu,AppUpdateOption
nesnesiyle belirtilen güncelleme türüne izin verilmediğini gösterir. Güncelleme akışını başlatmadan önceAppUpdateInfo
nesnesinin güncelleme türüne izin verildiğini gösterip göstermediğini kontrol edin.
Sonraki adımlar
Entegrasyonunuzun doğru şekilde çalıştığını doğrulamak için uygulamanızın uygulama içi güncellemelerini test edin.