Uygulama içi güncellemeleri destekleme (Yerel)

Bu kılavuzda, yerel kod (C veya C++) kullanarak uygulamanızda uygulama içi güncellemelerin nasıl destekleneceği açıklanmaktadır. Uygulamanızda Kotlin programlama dilini veya Java programlama dilini kullandığı ve uygulamanızın Unity kullandığı durumlar için ayrı kılavuzlar bulunmaktadır.

Yerel SDK'ya genel bakış

Play Core Yerel SDK'sı, Play Core SDK'sı ailesinin bir parçasıdır. Yerel SDK, AppUpdateManager öğesini Java Play Uygulama İçi Güncelleme Kitaplığı'ndan saran bir C başlık dosyası (app_update.h) içerir. Bu başlık dosyası, uygulamanızın doğrudan yerel kodunuzdan uygulama içi güncellemeler için API'yi çağırmasına olanak tanır.

Geliştirme ortamınızı ayarlama

İndir Play Core Native SDK

İndirmeden önce aşağıdaki şartlar ve koşulları kabul etmeniz gerekir.

Hükümler ve Koşullar

Last modified: September 24, 2020
  1. 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.
  2. For purposes of these terms, "APIs" means Google's APIs, other developer services, and associated software, including any Redistributable Code.
  3. “Redistributable Code” means Google-provided object code or header files that call the APIs.
  4. 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.
  5. 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.
İndirin: Play Core Native SDK

play-core-native-sdk-1.14.0.zip

  1. Aşağıdakilerden birini yapın:

  2. SDK Yöneticisi'ni kullanarak en yeni CMake ve Android Yerel Geliştirme Kiti'ni (NDK) yükleyerek Android Studio'yu yerel geliştirme için hazırlayın. Yerel projeler oluşturma veya içe aktarma hakkında daha fazla bilgi için NDK'yı Kullanmaya Başlama bölümüne bakın.

  3. Zip dosyasını indirin ve projenizle birlikte çıkartın.

    İndirme Bağlantısı Boyut SHA-256 Sağlaması
    36 MiB 782a8522d937848c83a715c9a258b95a3ff2879a7cd71855d137b41c00786a5e
  4. Uygulamanızın build.gradle dosyasını aşağıda gösterildiği gibi güncelleyin:

    Modern

        // 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.0.0'
            implementation 'com.google.android.play:asset-delivery:2.0.0'
            implementation 'com.google.android.play:integrity:1.0.1'
            implementation 'com.google.android.play:review:2.0.0'
    
            // 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.0.0")
        implementation("com.google.android.play:asset-delivery:2.0.0")
        implementation("com.google.android.play:integrity:1.0.1")
        implementation("com.google.android.play:review:2.0.0")
    
        // Import these common dependencies.
        implementation("com.google.android.gms:play-services-tasks:18.0.2")
        implementation(files("$playcoreDir/playcore-native-metadata.jar"))
        ...
    }
    
  5. 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ştirmesini sağlamak için sürümle ilgili verileri toplayabilir. Bu veriler şunları içerir:

  • Uygulamanın paket adı
  • Uygulamanın paket sürümü
  • Play Core Yerel SDK'sı sürümü

Bu veriler, uygulama paketinizi Play Console'a yüklediğinizde toplanır. Bu veri toplama işlemini devre dışı bırakmak için build.gradle dosyasındaki $playcoreDir/playcore-native-metadata.jar içe aktarmayı kaldırın.

Play Core Yerel SDK'yı kullanımınız ve Google'ın toplanan verileri kullanımı ile ilgili bu veri toplama işleminin, uygulama paketinizi Play Console'a yüklediğinizde Google'ın Gradle'da beyan edilen kitaplık bağımlılıkları koleksiyonundan ayrı ve bağımsız olduğunu unutmayın.

Play Core Yerel SDK'sını projenize entegre ettikten sonra, API çağrıları içeren dosyalara aşağıdaki satırı ekleyin:

#include "play/app_update.h"

In-app Update API'yi başlatma

In-app Update API'yi her kullandığınızda önce android_native_app_glue.h ile oluşturulmuş aşağıdaki örnekte gösterildiği gibi, AppUpdateManager_init() işlevini çağırarak API'yi 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 bir güncelleme olup olmadığını kontrol edin. AppUpdateManager_requestInfo(), uygulama içi güncelleme akışını daha sonra başlatmak üzere gerekli bilgileri toplayan eşzamansız bir istek başlatır. İstek başarıyla başlatılırsa 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. Hata koduna ek olarak, bu işlev güncelleme isteği hakkında bilgi almak için kullanabileceğiniz bir AppUpdateInfo opak struct döndürür. Örneğin, info için null olmayan bir sonuç döndürene kadar her oyun döngüsünde bu işlevi ç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üncelleme eskiliğini kontrol et

Bir güncelleme olup olmadığını kontrol etmeye ek olarak, kullanıcıya Play Store'dan bir güncellemeyle ilgili son bildirim verilmesinden bu yana ne kadar süre geçtiğine de göz atabilirsiniz. Bu sayede esnek güncelleme mi yoksa anında güncelleme mi başlatmanız gerektiğine karar verebilirsiniz. Örneğin, kullanıcıyı esnek bir güncellemeyle bilgilendirmeden önce birkaç gün, bundan sonra da hemen güncelleme 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() aracını kullanın:

int32_t staleness_days = AppUpdateInfo_getClientVersionStalenessDays(info);

Güncelleme önceliğini kontrol etme

Google Play Geliştirici API'si her güncellemenin önceliğini ayarlamanızı sağlar. Bu sayede uygulamanız, kullanıcıya güncelleme önermesinin ne kadar güçlü olacağına karar verebilir. Örneğin, güncelleme önceliğini ayarlamak için aşağıdaki stratejiyi göz önünde bulundurun:

  • Kullanıcı arayüzünde küçük iyileştirmeler: Düşük öncelikli güncelleme; ne esnek güncelleme ne de anında güncelleme isteğinde bulunun. Yalnızca kullanıcı uygulamanızla etkileşimde olmadığında güncelleyin.
  • Performans iyileştirmeleri: Orta öncelikli güncelleme; esnek 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. 0 varsayılan, 5 ise en yüksek önceliklidir. 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ümdeki yeni eklenen tüm sürümlerin, sürümle aynı önceliğe sahip olduğu kabul edilir. Öncelik, yalnızca yeni bir sürüm kullanıma sunulurken ayarlanabilir ve daha sonra değiştirilemez.

Önceliği, Play Developer API dokümanlarında açıklandığı gibi Google Play Developer API'yi kullanarak ayarlayın. Edit.tracks: update yönteminde iletilen Edit.tracks kaynağında uygulama içi güncelleme önceliğini belirtin. Aşağıdaki örnekte, 88 ve inAppUpdatePriority 5 sürüm kodlarıyla 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 seviyesini kontrol edebilirsiniz:

int32_t priority = AppUpdateInfo_getPriority(info);

Güncelleme başlat

Bir güncellemenin olduğunu onayladıktan sonra AppUpdateManager_requestStartUpdate() adresini 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, uygulama içi güncelleme akışına ilişkin seçenekleri (güncellemenin esnek mi yoksa anında mı olacağı dahil) 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 örnek, anında güncelleme akışı için bir AppUpdateOptions nesnesi oluşturur:

// Creates an AppUpdateOptions configuring an immediate in-app update flow.
AppUpdateOptions* options;
AppUpdateErrorCode error_code = AppUpdateOptions_createOptions(APP_UPDATE_TYPE_IMMEDIATE, &options);

AppUpdateOptions nesnesi, güncellemenin cihaz depolama alanının sınırlı olması durumunda öğe paketlerini temizlemesine izin verilip verilmeyeceğini tanımlayan bir AllowAssetPackDeletion alanı da içerir. Bu alan varsayılan olarak false değerine ayarlıdır ancak bunun yerine true olarak ayarlamak için AppUpdateOptions_setAssetPackDeletionAllowed() yöntemini kullanabilirsiniz:

bool allow = true;
AppUpdateErrorCode error_code = AppUpdateOptions_setAssetPackDeletionAllowed(options, allow);

Güncel bir AppUpdateInfo nesneniz ve doğru şekilde yapılandırılmış bir AppUpdateOptions nesneniz olduğunda, AppUpdateManager_requestStartUpdate() yöntemini çağırarak eşzamansız olarak güncelleme akışı isteyin ve son parametre için bir Android Etkinliği jobject iletin.

AppUpdateErrorCode request_error_code =
AppUpdateManager_requestStartUpdate(info, options, app->activity->clazz);

Kaynaklarınızı boşaltmak için artık ihtiyacınız olmayan AppUpdateInfo ve AppUpdateOptions örneklerini sırasıyla AppUpdateInfo_destroy() ve AppUpdateOptions_destroy() çağrılarını yaparak serbest bırakın.

AppUpdateInfo_destroy(info);
AppUpdateOptions_destroy(options);

Anında güncelleme akışı için Google Play bir kullanıcı onay sayfası görüntüler. Kullanıcı isteği kabul ettiğinde Google Play, güncellemeyi otomatik olarak indirip ön planda yükler. Daha sonra yükleme başarılı olursa uygulamayı güncellenmiş sürümde yeniden başlatır.

Esnek güncelleme akışı için kullanıcı uygulamayla etkileşim kurmaya 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() yöntemini ç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ın API kullanımı tamamlandıktan sonra AppUpdateManager_destroy() işlevini çağırarak kaynakları boşaltabilirsiniz.

Hata işleme

Bu bölümde, belirli AppUpdateErrorCode değerleriyle belirtilen 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ı belirtir. API'yi başlatmak için AppUpdateManager_init() yöntemini çağırın.
  • -4, APP_UPDATE_INVALID_REQUEST hata kodu, güncelleme akışı isteğindeki bazı parametrelerin hatalı olduğunu belirtir. AppUpdateInfo ve AppUpdateOptions nesnelerinin boş değerli olmadığından ve doğru biçimlendirildiğinden emin olun.
  • -5, APP_UPDATE_UNAVAILABLE hata kodu geçerli bir güncelleme olmadığını belirtir. Hedef sürümün aynı paket adına, uygulama kimliğine ve imza anahtarına sahip olduğundan emin olun. Güncelleme varsa uygulamanın önbelleğini temizleyin ve AppUpdateInfo dosyasını yenilemek için AppUpdateManager_requestAppUpdateInfo() yöntemini tekrar çağırın.
  • -6, APP_UPDATE_NOT_ALLOWED hata kodu, AppUpdateOption nesnesiyle belirtilen güncelleme türüne izin verilmediğini belirtir. Güncelleme akışını başlatmadan önce AppUpdateInfo nesnesinin güncelleme türüne izin verildiğini gösterip göstermediğini kontrol edin.

Sonraki adımlar

Entegrasyonunuzun düzgün çalıştığını doğrulamak için uygulamanızın uygulama içi güncellemelerini test edin.