Panduan ini menjelaskan cara mendukung update dalam aplikasi di aplikasi Anda menggunakan kode native (C atau C++). Ada panduan terpisah untuk kasus saat implementasi Anda menggunakan bahasa pemrograman Kotlin atau Java, dan saat implementasi Anda menggunakan Unity.
Ringkasan Native SDK
Play Core Native SDK adalah bagian dari kelompok Play Core
SDK. Native
SDK mencakup file header C, app_update.h
, yang menggabungkan
AppUpdateManager
dari Java Play In-App Update Library. File header ini memungkinkan aplikasi Anda memanggil API
untuk update dalam aplikasi langsung dari kode native.
Menyiapkan lingkungan pengembangan
Download Play Core Native SDK
Sebelum mendownload, Anda harus menyetujui ketentuan dan persyaratan berikut.
Persyaratan dan Ketentuan
Terakhir diubah: 24 September 2020- Dengan menggunakan Software Development Kit Play Core, Anda menyetujui persyaratan ini bersama dengan Persyaratan Layanan Google API ("ToS API"). Jika persyaratan ini bertentangan dengan ToS API, persyaratan ini akan lebih diutamakan. Baca persyaratan ini dan ToS API dengan saksama.
- Untuk tujuan persyaratan ini, "API" berarti API Google, layanan developer lainnya, dan software terkait, termasuk Kode yang Dapat Didistribusikan Ulang.
- “Kode yang Dapat Didistribusikan Ulang” berarti kode objek atau file header yang disediakan Google yang memanggil API.
- Tunduk pada persyaratan ini dan persyaratan ToS API, Anda dapat menyalin dan mendistribusikan Kode yang Dapat Didistribusikan Ulang hanya untuk disertakan sebagai bagian dari Klien API Anda. Google dan pemegang lisensinya memiliki semua hak, kepemilikan, dan kepentingan, termasuk setiap dan semua hak atas kekayaan intelektual dan hak milik eksklusif lainnya, atas dan untuk Kode yang Dapat Didistribusikan Ulang. Anda tidak akan memodifikasi, menerjemahkan, atau membuat karya turunan dari Kode yang Dapat Didistribusikan Ulang.
- Google dapat melakukan perubahan pada persyaratan ini kapan saja dengan pemberitahuan dan kesempatan untuk menolak penggunaan Software Development Kit Play Core lebih lanjut. Google akan memposting pemberitahuan terkait perubahan persyaratan ini di https://developer.android.com/guide/playcore/license. Perubahan tidak berlaku surut.
Lakukan salah satu hal berikut:
- Instal Android Studio versi 4.0 atau yang lebih tinggi. Gunakan UI SDK Manager untuk menginstal Android SDK Platform versi 10.0 (level API 29).
- Instal alat command line Android SDK
dan gunakan
sdkmanager
untuk menginstal Android SDK Platform versi 10.0 (level API 29).
Siapkan Android Studio untuk pengembangan native dengan menggunakan SDK Manager untuk menginstal CMake dan Android Native Development Kit (NDK) terbaru. Untuk informasi selengkapnya tentang membuat atau mengimpor project native, lihat Mulai Menggunakan NDK.
Download file zip dan ekstrak bersama project Anda.
Link Download Ukuran Checksum SHA-256 35,6 MiB 4eee8aafbe0309c0b4ba377c7c7bc1986c73ae70dd7ce3a04f792e1a67d79d51 Update file
build.gradle
aplikasi Anda seperti yang ditunjukkan di bawah ini: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.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")) ... }
Update file
CMakeLists.txt
aplikasi Anda seperti yang ditunjukkan di bawah ini: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 ...)
Pengumpulan Data
Play Core Native SDK dapat mengumpulkan data terkait versi untuk memungkinkan Google meningkatkan produk, termasuk:
- Nama paket aplikasi
- Versi paket aplikasi
- Versi Play Core Native SDK
Data ini akan dikumpulkan saat Anda mengupload paket aplikasi
ke Konsol Play. Untuk memilih tidak ikut dalam proses pengumpulan data ini, hapus
impor $playcoreDir/playcore-native-metadata.jar
di file build.gradle.
Perhatikan bahwa pengumpulan data ini yang terkait dengan penggunaan Play Core Native SDK oleh Anda dan penggunaan data yang dikumpulkan oleh Google terpisah dan tidak bergantung pada pengumpulan dependensi library Google yang dideklarasikan di Gradle saat Anda mengupload paket aplikasi ke Konsol Play.
Setelah Anda mengintegrasikan Play Core Native SDK ke dalam project, sertakan baris berikut di file yang berisi panggilan API:
#include "play/app_update.h"
Melakukan inisialisasi API update dalam aplikasi
Setiap Anda menggunakan API update dalam aplikasi, inisialisasi API tersebut terlebih dahulu dengan memanggil fungsi
AppUpdateManager_init()
,
seperti yang ditunjukkan dalam contoh berikut yang dibangun dengan
android_native_app_glue.h
:
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.
}
}
Memeriksa ketersediaan update
Sebelum Anda meminta update, periksa apakah ada update yang tersedia untuk aplikasi
Anda.
AppUpdateManager_requestInfo()
memulai konten asinkron yang mengumpulkan informasi yang diperlukan untuk meluncurkan
alur update dalam aplikasi nanti. Fungsi ini menampilkan APP_UPDATE_NO_ERROR
jika
permintaan berhasil dimulai.
AppUpdateErrorCode error_code = AppUpdateManager_requestInfo()
if (error_code == APP_UPDATE_NO_ERROR) {
// The request has successfully started, check the result using
// AppUpdateManager_getInfo.
}
Anda dapat melacak proses yang sedang berlangsung dan hasil permintaan menggunakan
AppUpdateManager_getInfo()
.
Selain kode error, fungsi ini menampilkan struktur buram
AppUpdateInfo
,
yang dapat Anda gunakan untuk mengambil informasi tentang permintaan
update. Misalnya, Anda mungkin ingin memanggil fungsi ini di setiap game loop
hingga menampilkan hasil non-null untuk info
:
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
}
...
}
Memeriksa penghentian update
Selain memeriksa apakah update tersedia, Anda juga perlu memeriksa jumlah waktu yang telah berlalu sejak pengguna terakhir kali diberi tahu tentang update melalui Play Store. Hal ini dapat membantu Anda menentukan apakah harus melakukan inisialisasi update fleksibel atau update langsung. Misalnya, Anda mungkin menunggu beberapa hari sebelum memberi tahu pengguna dengan update fleksibel, dan beberapa hari setelahnya sebelum meminta update langsung.
Gunakan
AppUpdateInfo_getClientVersionStalenessDays()
untuk memeriksa jumlah hari sejak update tersedia di Play
Store:
int32_t staleness_days = AppUpdateInfo_getClientVersionStalenessDays(info);
Memeriksa prioritas update
Dengan Google Play Developer API, Anda dapat menyetel prioritas setiap update. Hal ini memungkinkan aplikasi Anda menentukan seberapa kuat rekomendasi update kepada pengguna. Sebagai contoh, pertimbangkan strategi berikut untuk menyetel prioritas update:
- Peningkatan kecil pada UI: Update prioritas rendah; tidak meminta update fleksibel atau update langsung. Mengupdate hanya saat pengguna tidak berinteraksi dengan aplikasi Anda.
- Peningkatan performa: Update prioritas sedang; meminta update fleksibel.
- Update keamanan penting: Update prioritas tinggi; meminta update langsung.
Untuk menentukan prioritas, Google Play menggunakan nilai bilangan bulat antara 0 dan 5, dengan 0
adalah nilai default dan 5 adalah prioritas tertinggi. Guna menyetel prioritas untuk
update, gunakan kolom inAppUpdatePriority
di bawah Edits.tracks.releases
di
Google Play Developer API. Semua versi yang baru ditambahkan dalam rilis
dianggap sebagai prioritas yang sama dengan rilis tersebut. Prioritas hanya dapat disetel saat
meluncurkan rilis baru, dan tidak dapat diubah setelahnya.
Tetapkan prioritas menggunakan Google Play Developer API, seperti yang dijelaskan di dokumentasi
Play Developer
API.
Tentukan prioritas update dalam aplikasi di resource
Edit.tracks
yang diteruskan ke
metode
Edit.tracks: update
. Contoh berikut menunjukkan perilisan aplikasi dengan kode versi
88 dan inAppUpdatePriority
5:
{ "releases": [{ "versionCodes": ["88"], "inAppUpdatePriority": 5, "status": "completed" }] }
Dalam kode aplikasi, Anda dapat memeriksa tingkat prioritas untuk update tertentu menggunakan
AppUpdateInfo_getPriority()
:
int32_t priority = AppUpdateInfo_getPriority(info);
Memulai update
Setelah memastikan bahwa update tersedia, Anda dapat meminta update menggunakan
AppUpdateManager_requestStartUpdate()
.
Sebelum Anda meminta update, dapatkan objek AppUpdateInfo
terbaru dan
buat objek
AppUpdateOptions
untuk mengonfigurasi alur update. Objek AppUpdateOptions
menentukan
opsi untuk alur update dalam aplikasi, termasuk apakah update tersebut harus
fleksibel atau langsung.
Contoh berikut akan membuat objek AppUpdateOptions
untuk alur update
fleksibel:
// Creates an AppUpdateOptions configuring a flexible in-app update flow.
AppUpdateOptions* options;
AppUpdateErrorCode error_code = AppUpdateOptions_createOptions(APP_UPDATE_TYPE_FLEXIBLE, &options);
Contoh berikut membuat objek AppUpdateOptions
untuk alur
update langsung:
// Creates an AppUpdateOptions configuring an immediate in-app update flow.
AppUpdateOptions* options;
AppUpdateErrorCode error_code = AppUpdateOptions_createOptions(APP_UPDATE_TYPE_IMMEDIATE, &options);
Objek AppUpdateOptions
juga berisi kolom AllowAssetPackDeletion
yang menentukan apakah update diizinkan untuk menghapus paket
aset jika penyimpanan perangkat terbatas. Kolom
ini ditetapkan ke false
secara default, tetapi Anda dapat menggunakan metode
AppUpdateOptions_setAssetPackDeletionAllowed()
untuk menetapkannya ke true
:
bool allow = true;
AppUpdateErrorCode error_code = AppUpdateOptions_setAssetPackDeletionAllowed(options, allow);
Setelah Anda memiliki objek AppUpdateInfo
terbaru dan objek AppUpdateOptions
yang dikonfigurasi dengan benar, panggil AppUpdateManager_requestStartUpdate()
untuk
meminta alur update secara asinkron, yang meneruskan jobject
Aktivitas Android untuk parameter akhir.
AppUpdateErrorCode request_error_code =
AppUpdateManager_requestStartUpdate(info, options, app->activity->clazz);
Untuk mengosongkan resource, rilis instance AppUpdateInfo
dan
AppUpdateOptions
yang tidak lagi Anda perlukan dengan memanggil
masing-masing
AppUpdateInfo_destroy()
dan
AppUpdateOptions_destroy()
.
AppUpdateInfo_destroy(info);
AppUpdateOptions_destroy(options);
Untuk alur update langsung, Google Play menampilkan halaman konfirmasi pengguna. Saat pengguna menyetujui permintaan, Google Play otomatis mendownload dan menginstal update di latar depan, lalu memulai ulang aplikasi ke versi yang diupdate jika penginstalan berhasil.
Untuk alur update fleksibel, Anda dapat terus meminta objek AppUpdateInfo
terbaru untuk melacak status update saat ini saat pengguna terus
berinteraksi dengan aplikasi. Setelah berhasil didownload, Anda harus
memicu penyelesaian update dengan memanggil
AppUpdateManager_requestCompleteUpdate()
,
seperti yang ditampilkan di contoh berikut:
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.
}
}
Kosongkan resource dengan memanggil fungsi
AppUpdateManager_destroy()
setelah aplikasi Anda selesai menggunakan API.
Penanganan error
Bagian ini menjelaskan solusi untuk kesalahan umum yang ditunjukkan oleh nilai
AppUpdateErrorCode
tertentu:
- Kode error
-110, APP_UPDATE_INITIALIZATION_NEEDED
menunjukkan bahwa API belum berhasil diinisialisasi. PanggilAppUpdateManager_init()
untuk melakukan inisialisasi API. - Kode error
-4, APP_UPDATE_INVALID_REQUEST
menunjukkan bahwa format beberapa parameter permintaan alur update salah. Periksa untuk memastikan bahwa objekAppUpdateInfo
danAppUpdateOptions
bukan null serta telah diformat dengan benar. - Kode error
-5, APP_UPDATE_UNAVAILABLE
menunjukkan bahwa tidak ada update yang tersedia dan dapat diterapkan. Pastikan versi target memiliki nama paket, ID aplikasi, dan kunci penandatanganan yang sama. Jika ada update yang tersedia, hapus cache aplikasi dan panggilAppUpdateManager_requestAppUpdateInfo()
lagi untuk memuat ulangAppUpdateInfo
. - Kode error
-6, APP_UPDATE_NOT_ALLOWED
menunjukkan bahwa jenis update yang ditunjukkan oleh objekAppUpdateOption
tidak diizinkan. Periksa apakah objekAppUpdateInfo
menunjukkan bahwa jenis update diizinkan sebelum memulai alur update.
Langkah berikutnya
Uji update dalam aplikasi pada aplikasi Anda untuk memastikan bahwa integrasi berfungsi dengan benar.